openapi: 3.0.1
info:
  title: Sorcha Platform API
  version: 2.0.0-dev
  description: 'Sorcha is cryptographic proof infrastructure for multi-party workflows — every action is wallet-signed, every record is Merkle-chained on an immutable register, every disclosure is cryptographically bounded rather than policy-enforced. AI agents and integrators can use this aggregated OpenAPI surface to discover the full platform: tenant authentication, HD wallets and signing (BIP32/39/44, ML-DSA FIPS 204), distributed register read/write, blueprint-driven multi-party workflow orchestration, peer-to-peer replication, and HAIP 1.0 OpenID4VCI / OpenID4VP credential issuance and verification. See `docs/quickstart.md` for setup, `STANDARDS.md` for the full standards posture, and `/.well-known/mcp.json` for the MCP server manifest.'
  contact:
    name: Sorcha Contributors
    url: https://github.com/Sorcha-Platform/Sorcha
  license:
    name: MIT License
    url: https://opensource.org/licenses/MIT
  x-mcp-server: /.well-known/mcp.json
  x-standards:
  - BIP32
  - BIP39
  - BIP44
  - ML-DSA (NIST FIPS 204)
  - ML-KEM (NIST FIPS 203)
  - OpenID4VCI
  - OpenID4VP
  - HAIP 1.0
  - W3C Verifiable Credentials Data Model 2.0
  - IETF Token Status List 2024 (RFC 9972)
  - DID 1.0
  - OAuth 2.0
servers:
- url: http://localhost:8080
  description: API Gateway (Docker)
- url: /
  description: Relative URL
paths:
  /api/blueprint/api/blueprints/from-published:
    post:
      tags:
      - Blueprints
      summary: Amend — derive a new draft from a published version
      description: Fetches the specified published Blueprint version, clones it to a new draft, stamps lineage metadata (x-source-register / x-source-blueprint-id / x-source-version), and returns the new draft id. The amend draft opens with Go live re-locked pending a fresh rehearsal — its executable-definition hash has no recorded RehearsalPass. The caller MUST hold a publish-governance role on the source register; otherwise 403 is returned and no draft is written. Returns 404 when the (registerId, blueprintId, version) triple does not resolve to a published blueprint.
      operationId: CloneBlueprintFromPublished
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CloneFromPublishedRequestBody'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CloneFromPublishedResponseBody'
        400:
          description: Bad Request
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/blueprint/api/files/{wallet}/{register}/{tx}/{fileId}:
    get:
      tags:
      - Actions
      summary: Get file attachment
      description: Retrieve a file attachment from an action transaction
      operationId: GetFile
      parameters:
      - name: wallet
        in: path
        required: true
        schema:
          type: string
      - name: register
        in: path
        required: true
        schema:
          type: string
      - name: tx
        in: path
        required: true
        schema:
          type: string
      - name: fileId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/health:
    get:
      tags:
      - Health
      summary: Service health check with metrics
      operationId: HealthCheck
      responses:
        200:
          description: OK
  /api/blueprint/api/stats:
    get:
      tags:
      - Statistics
      summary: Get blueprint statistics (public)
      description: Returns aggregate counts of blueprints and instances. No authentication required.
      operationId: GetBlueprintStats
      responses:
        200:
          description: OK
  /api/blueprint/api/operations/{operationId}:
    get:
      tags:
      - Operations
      summary: Get encryption operation status
      description: Returns current status of an async encryption operation. Use for polling fallback when SignalR is unavailable.
      operationId: GetEncryptionOperation
      parameters:
      - name: operationId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/blueprint/api/operations:
    get:
      tags:
      - Operations
      summary: List active encryption operations for a wallet
      description: Returns active in-memory encryption operations for the specified wallet. For historical data, query Tenant Service /api/events.
      operationId: ListEncryptionOperations
      parameters:
      - name: wallet
        in: query
        required: true
        schema:
          type: string
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/blueprint/api/blueprints:
    get:
      tags:
      - Blueprints
      summary: Get all blueprints
      description: 'Retrieve a paginated list of blueprints with optional search and status filtering. Supports JSON-LD via Accept: application/ld+json header.'
      operationId: GetBlueprints
      parameters:
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      - name: search
        in: query
        schema:
          type: string
      - name: status
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
    post:
      tags:
      - Blueprints
      summary: Create new blueprint
      description: 'Create a new blueprint with the provided details. Supports JSON-LD via Accept: application/ld+json header.'
      operationId: CreateBlueprint
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Blueprint'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/blueprints/{id}:
    get:
      tags:
      - Blueprints
      summary: Get blueprint by ID
      description: 'Retrieve a specific blueprint by its unique identifier. Supports JSON-LD via Accept: application/ld+json header.'
      operationId: GetBlueprintById
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
    put:
      tags:
      - Blueprints
      summary: Update blueprint
      description: Update an existing blueprint with new details
      operationId: UpdateBlueprint
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Blueprint'
        required: true
      responses:
        200:
          description: OK
    delete:
      tags:
      - Blueprints
      summary: Delete blueprint
      description: Soft delete a blueprint (can be recovered)
      operationId: DeleteBlueprint
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/blueprints/{id}/validate:
    post:
      tags:
      - Blueprints
      summary: Validate blueprint
      description: Validate a blueprint without publishing. Returns validation errors and warnings.
      operationId: ValidateBlueprint
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/blueprints/{id}/publish:
    post:
      tags:
      - Blueprints
      summary: Publish blueprint (governance-hard + rehearsal-soft gated)
      description: "Validate and publish a blueprint to a register. Requires { registerId } in the body. Enforces register governance rights server-side (403 if the caller lacks Owner/Admin/Designer on the register). Then checks the rehearsal soft gate: the publishing version's executable-definition hash must match a recorded rehearsal pass, otherwise 409 REHEARSAL_REQUIRED unless { override: { confirm: true, reason? } } is sent, which publishes and records an audited override. The 200 response carries 'overridden'."
      operationId: PublishBlueprint
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/blueprints/{id}/versions:
    get:
      tags:
      - Blueprints
      summary: Get blueprint versions
      description: Retrieve all published versions of a blueprint
      operationId: GetBlueprintVersions
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/blueprints/{id}/versions/{version}:
    get:
      tags:
      - Blueprints
      summary: Get specific version
      description: Retrieve a specific published version of a blueprint (immutable)
      operationId: GetBlueprintVersion
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: version
        in: path
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      responses:
        200:
          description: OK
  /api/blueprint/api/blueprints/{id}/rehearsals:
    post:
      tags:
      - Rehearsals
      summary: Start a full rehearsal
      description: Lazily provisions (or reuses) the org's devMode sandbox register, mints ephemeral per-role sandbox wallets, publishes the current draft to the sandbox, creates a fresh instance, and returns the initial walk-through. Returns 409 when the blueprint has blocking validation errors. Dry-run mode is handled client-side and does NOT call this.
      operationId: StartRehearsal
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartFullRehearsalRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Rehearsal'
        403:
          description: Forbidden
        404:
          description: Not Found
        409:
          description: Conflict
  /api/blueprint/api/blueprints/{id}/rehearsals/{rehearsalId}:
    get:
      tags:
      - Rehearsals
      summary: Get rehearsal status and log
      description: 'Retrieves the current state of a rehearsal: outcome, acting role, walk-through steps, and activity log.'
      operationId: GetRehearsal
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: rehearsalId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Rehearsal'
        404:
          description: Not Found
    delete:
      tags:
      - Rehearsals
      summary: Reset/discard a rehearsal
      description: Clears the rehearsal instance and discards its ephemeral per-role sandbox wallets. The sandbox register itself persists (reused next time). Idempotent — returns 204 even if the rehearsal is already gone.
      operationId: ResetRehearsal
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: rehearsalId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
  /api/blueprint/api/blueprints/{id}/rehearsals/{rehearsalId}/role:
    post:
      tags:
      - Rehearsals
      summary: Switch the acting participant role
      description: Changes the participant role under which subsequent step submissions are made.
      operationId: SwitchRehearsalRole
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: rehearsalId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SwitchRehearsalRoleBody'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Rehearsal'
        404:
          description: Not Found
        422:
          description: Unprocessable Entity
  /api/blueprint/api/blueprints/{id}/rehearsals/{rehearsalId}/steps:
    post:
      tags:
      - Rehearsals
      summary: Submit the current action as the acting role
      description: Runs the real execution pipeline (sign as acting role server-side, validate, route, seal, disclose, issue credentials) against the sandbox register, advances the walk-through, and appends to the log. On reaching a successful terminal state, records a RehearsalPass for the current executable-definition hash and marks Go live unlockable. Returns 422 when the payload fails validation or the submitted action is not the current step.
      operationId: SubmitRehearsalStep
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: rehearsalId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubmitRehearsalStepBody'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Rehearsal'
        404:
          description: Not Found
        422:
          description: Unprocessable Entity
  /api/blueprint/api/v1/schemas/system:
    get:
      tags:
      - Schemas
      summary: Get all system schemas
      description: 'Retrieve the four core system schemas: Installation, Organisation, Participant, Register'
      operationId: GetSystemSchemas
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SchemaEntryDto'
        401:
          description: Unauthorized
  /api/blueprint/api/v1/schemas/{identifier}:
    get:
      tags:
      - Schemas
      summary: Get schema by identifier
      description: Retrieve a specific schema by its unique identifier. Returns 304 Not Modified if ETag matches.
      operationId: GetSchemaByIdentifier
      parameters:
      - name: identifier
        in: path
        required: true
        schema:
          type: string
      - name: If-None-Match
        in: header
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaContentDto'
        304:
          description: Not Modified
        401:
          description: Unauthorized
        404:
          description: Not Found
    put:
      tags:
      - Schemas
      summary: Update a custom schema
      description: Update an existing custom schema's content or metadata
      operationId: UpdateSchema
      parameters:
      - name: identifier
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateSchemaRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaContentDto'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
    delete:
      tags:
      - Schemas
      summary: Delete a custom schema
      description: Delete a custom schema from the organization's schema store
      operationId: DeleteSchema
      parameters:
      - name: identifier
        in: path
        required: true
        schema:
          type: string
      responses:
        204:
          description: No Content
        400:
          description: Bad Request
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/blueprint/api/v1/schemas:
    get:
      tags:
      - Schemas
      summary: List all accessible schemas
      description: Retrieve schemas filtered by category, status, and search term
      operationId: ListSchemas
      parameters:
      - name: category
        in: query
        schema:
          type: string
      - name: status
        in: query
        schema:
          type: string
      - name: search
        in: query
        schema:
          type: string
      - name: limit
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 50
      - name: cursor
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaListResponse'
        401:
          description: Unauthorized
    post:
      tags:
      - Schemas
      summary: Create a custom schema
      description: Create a new custom schema in the organization's schema store
      operationId: CreateSchema
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateSchemaRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaContentDto'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
        409:
          description: Conflict
  /api/blueprint/api/v1/schemas/external/search:
    get:
      tags:
      - Schemas
      summary: Search external schema sources
      description: Search for schemas from external sources like SchemaStore.org
      operationId: SearchExternalSchemas
      parameters:
      - name: query
        in: query
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalSchemaSearchResponse'
        400:
          description: Bad Request
        401:
          description: Unauthorized
        503:
          description: Service Unavailable
  /api/blueprint/api/v1/schemas/external/import:
    post:
      tags:
      - Schemas
      summary: Import external schema
      description: Import a schema from an external source into the local schema store
      operationId: ImportExternalSchema
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ImportExternalSchemaRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaContentDto'
        400:
          description: Bad Request
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
        409:
          description: Conflict
        503:
          description: Service Unavailable
  /api/blueprint/api/v1/schemas/{identifier}/deprecate:
    post:
      tags:
      - Schemas
      summary: Deprecate a schema
      description: Mark a schema as deprecated, signaling it should no longer be used
      operationId: DeprecateSchema
      parameters:
      - name: identifier
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaContentDto'
        400:
          description: Bad Request
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/blueprint/api/v1/schemas/{identifier}/activate:
    post:
      tags:
      - Schemas
      summary: Activate a schema
      description: Reactivate a deprecated schema, making it available for use again
      operationId: ActivateSchema
      parameters:
      - name: identifier
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaContentDto'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/blueprint/api/v1/schemas/{identifier}/publish:
    post:
      tags:
      - Schemas
      summary: Publish a schema globally
      description: Make a custom schema available to all organizations
      operationId: PublishSchema
      parameters:
      - name: identifier
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaContentDto'
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
        409:
          description: Conflict
  /api/blueprint/api/v1/schemas/index:
    get:
      tags:
      - Schema Index
      summary: Search the schema index
      description: Full-text search across all indexed schemas. Results are filtered by the requesting user's organisation sector preferences.
      operationId: SearchSchemaIndex
      parameters:
      - name: search
        in: query
        schema:
          type: string
      - name: sectors
        in: query
        schema:
          type: string
      - name: provider
        in: query
        schema:
          type: string
      - name: status
        in: query
        schema:
          type: string
      - name: limit
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 25
      - name: cursor
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SchemaIndexSearchResponse'
        401:
          description: Unauthorized
  /api/blueprint/api/v1/schemas/index/{shortCode}:
    get:
      tags:
      - Schema Index
      summary: Get a specific schema index entry with full content
      description: Returns full schema index entry metadata plus the JSON Schema content by short code.
      operationId: GetSchemaIndexEntry
      parameters:
      - name: shortCode
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/blueprint/api/v1/schemas/index/content/{shortCode}:
    get:
      tags:
      - Schema Index
      summary: Get the full JSON Schema content for an indexed schema
      description: Returns the normalised JSON Schema draft-2020-12 content for a schema by short code.
      operationId: GetSchemaContent
      parameters:
      - name: shortCode
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/blueprint/api/v1/schemas/sectors:
    get:
      tags:
      - Sectors
      summary: List all available schema sectors
      description: Returns the platform-curated list of schema sectors.
      operationId: ListSectors
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SchemaSectorDto'
        401:
          description: Unauthorized
  /api/blueprint/api/v1/schemas/sectors/preferences:
    get:
      tags:
      - Sectors
      summary: Get organisation's sector visibility preferences
      description: Returns which sectors are enabled for the requesting user's organisation.
      operationId: GetSectorPreferences
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganisationSectorPreferencesDto'
        401:
          description: Unauthorized
    put:
      tags:
      - Sectors
      summary: Update organisation's sector visibility preferences
      description: Sets which sectors are visible to designers. Requires Administrator role.
      operationId: UpdateSectorPreferences
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateSectorPreferencesRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganisationSectorPreferencesDto'
        400:
          description: Bad Request
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/blueprint/api/v1/schemas/providers:
    get:
      tags:
      - Provider Health
      summary: List all schema providers with health status
      description: Returns the status of all configured schema providers including health, last fetch time, schema count, and error details.
      operationId: ListSchemaProviders
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/SchemaProviderStatusDto'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/blueprint/api/v1/schemas/providers/{providerName}/refresh:
    post:
      tags:
      - Provider Health
      summary: Trigger manual refresh for a specific provider
      description: Triggers an immediate index refresh for the specified provider. Returns immediately — refresh runs in background.
      operationId: RefreshSchemaProvider
      parameters:
      - name: providerName
        in: path
        required: true
        schema:
          type: string
      responses:
        202:
          description: Accepted
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
        429:
          description: Too Many Requests
  /api/blueprint/api/v1/credentials/{credentialId}/revoke:
    post:
      tags:
      - Credentials
      summary: Revoke a previously issued credential
      description: Revokes a credential by updating its status to 'Revoked' in the wallet store. Only the original issuer or register governance roles can revoke a credential.
      operationId: RevokeCredential
      parameters:
      - name: credentialId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RevokeCredentialRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RevokeCredentialResponse'
        400:
          description: Bad Request
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/blueprint/api/v1/credentials/{credentialId}/suspend:
    post:
      tags:
      - Credentials
      summary: Temporarily suspend a credential
      description: Suspends an Active credential (reversible). Only the original issuer or governance roles can suspend.
      operationId: SuspendCredential
      parameters:
      - name: credentialId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LifecycleCredentialRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/blueprint/api/v1/credentials/{credentialId}/reinstate:
    post:
      tags:
      - Credentials
      summary: Reinstate a suspended credential
      description: Reinstates a Suspended credential to Active. Only the original issuer or governance roles can reinstate.
      operationId: ReinstateCredential
      parameters:
      - name: credentialId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LifecycleCredentialRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/blueprint/api/v1/credentials/{credentialId}/refresh:
    post:
      tags:
      - Credentials
      summary: Reissue an expired credential with a fresh expiry
      description: Consumes the expired credential and issues a new one with a fresh expiry period.
      operationId: RefreshCredential
      parameters:
      - name: credentialId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RefreshCredentialRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/blueprint/api/v1/credentials/status-lists/{listId}:
    get:
      tags:
      - StatusLists
      summary: Get a Bitstring Status List Credential (W3C format)
      description: Returns the status list as a W3C BitstringStatusListCredential. This endpoint is public and unauthenticated — verifiers use it to check credential revocation/suspension status.
      operationId: GetStatusList
      parameters:
      - name: listId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
  /api/blueprint/api/v1/credentials/ietf-status-lists/{listId}:
    get:
      tags:
      - StatusLists
      summary: Get a Token Status List (IETF format)
      description: Returns the status list as a signed JWT per the IETF Token Status List draft. HAIP-conformant verifiers use this endpoint. The underlying bitstring is shared with the W3C endpoint.
      operationId: GetIetfStatusList
      parameters:
      - name: listId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/statuslist+jwt:
              schema:
                type: string
        404:
          description: Not Found
  /api/blueprint/api/v1/credentials/status-lists/{listId}/allocate:
    post:
      tags:
      - StatusLists
      summary: Allocate next available index in a status list (internal)
      description: Allocates the next available index for a new credential. Service-to-service auth required.
      operationId: AllocateStatusListIndex
      parameters:
      - name: listId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AllocateIndexRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
        409:
          description: Conflict
  /api/blueprint/api/v1/credentials/status-lists/{listId}/bits/{index}:
    put:
      tags:
      - StatusLists
      summary: Set or clear a bit in a status list (internal)
      description: Sets or clears the bit at a given index. Used by lifecycle operations (revoke, suspend, reinstate).
      operationId: SetStatusListBit
      parameters:
      - name: listId
        in: path
        required: true
        schema:
          type: string
      - name: index
        in: path
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type: integer
          format: int32
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetBitRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/blueprint/api/actions/pending:
    get:
      tags:
      - Actions
      summary: Get pending actions for the authenticated user
      description: Returns all pending actions across blueprint instances for every wallet the user owns. Resolves the user's wallets from the `wallet_address` JWT claim when present (fast path), and falls back to a live Wallet Service lookup keyed by the user's `sub` claim when the claim is absent — this keeps the endpoint self-healing for users whose token was issued before their first wallet was created.
      operationId: GetPendingActions
      parameters:
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      responses:
        200:
          description: OK
  /api/blueprint/api/actions/pending/count:
    get:
      tags:
      - Actions
      summary: Get pending action count for badge display
      description: Returns the count of pending actions across every wallet the authenticated user owns. Uses the same wallet resolution path as GetPendingActions. urgentCount is currently always 0 — urgency-aware counting will be added in a future iteration.
      operationId: GetPendingActionCount
      responses:
        200:
          description: OK
  /api/blueprint/api/file-chunks:
    post:
      tags:
      - FileChunks
      summary: Submit an encrypted file chunk
      description: Accepts a single Base64-encoded file chunk, encrypts it server-side using an HKDF-derived XChaCha20-Poly1305 key, and stages it for inclusion in a blueprint action transaction. Chunks are submitted individually and assembled by the validator once all chunks for a file have been received. The caller must submit all chunks (0 to totalChunks-1) before the parent action can be finalised. Each chunk must not exceed 4 MB and the total chunk count must not exceed 10. On the first chunk (no uploadSessionId), the server creates an upload session, stores the master key server-side, and returns an opaque uploadSessionId plus the salt. Subsequent chunks must supply the uploadSessionId to reuse the same encryption session. The salt (not the master key) is returned so the client can build a FileReference.
      operationId: SubmitFileChunk
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FileChunkSubmissionRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FileChunkSubmissionResponse'
        400:
          description: Bad Request
        401:
          description: Unauthorized
        413:
          description: Payload Too Large
  /api/blueprint/api/file-chunks/{chunkId}:
    get:
      tags:
      - FileChunks
      summary: Retrieve a stored file chunk by ID
      description: Returns the encrypted content of a previously staged file chunk. Used by the Wallet Service during file download reassembly. The chunk content is returned as Base64-encoded bytes.
      operationId: GetFileChunk
      parameters:
      - name: chunkId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FileChunkResponse'
        404:
          description: Not Found
  /api/blueprint/api/presentations/{presentationRequestId}/status:
    get:
      tags:
      - Presentations
      summary: Get the current lifecycle state of a presentation attempt
      description: Returns only the lifecycle state (awaiting-presentation / success / decline / abandoned / abandoned-with-late-outcome / expired) and the attempt expiry. Wallet-facing and polled unauthenticated by the QR scanner; no instance, register, or consumer metadata is included. The register's transaction stream is the authoritative history.
      operationId: GetPresentationStatus
      parameters:
      - name: presentationRequestId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
  /api/blueprint/api/presentations/callbacks/{consumerName}/{presentationRequestId}:
    post:
      tags:
      - Presentations
      summary: Verifier callback for a presentation outcome
      description: Called by a registered IPresentationConsumer (e.g. HAIP Service) after verifying a presentation. Writes the PresentationOutcome transaction. Idempotent by presentationRequestId. (Action advancement on success is deferred to US3.)
      operationId: PresentationCallback
      parameters:
      - name: consumerName
        in: path
        required: true
        schema:
          type: string
      - name: presentationRequestId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JsonElement'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/presentations/{presentationRequestId}/disclosed-claims:
    get:
      tags:
      - Presentations
      summary: Fetch the disclosed claims from a successful presentation for council-page autofill
      description: Feature 127 supplement to F111's presentation lifecycle. The token returned by InitiateAsync authenticates the caller as the council page that originated the flow. Single-use; consumed on first fetch. Claims are returned in plaintext, filtered to the requiredClaims declared on the action's credentialRequirement. Returns 200 + status=pending while the wallet's outcome hasn't been written; returns 410 on decline / abandonment / claims-expired; returns 401 when the token is invalid or doesn't match the path's presentationRequestId.
      operationId: GetDisclosedClaims
      parameters:
      - name: presentationRequestId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: token
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/templates:
    get:
      tags:
      - Templates
      summary: Get all published templates
      description: Retrieve all published blueprint templates, optionally filtered by category
      operationId: GetTemplates
      parameters:
      - name: category
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
    post:
      tags:
      - Templates
      summary: Create or update template
      description: Create a new template or update an existing one
      operationId: SaveTemplate
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BlueprintTemplate'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/templates/{id}:
    get:
      tags:
      - Templates
      summary: Get template by ID
      description: Retrieve a specific blueprint template by its unique identifier
      operationId: GetTemplateById
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
    delete:
      tags:
      - Templates
      summary: Delete template
      description: Delete a blueprint template
      operationId: DeleteTemplate
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/templates/evaluate:
    post:
      tags:
      - Templates
      summary: Evaluate template
      description: Evaluate a blueprint template with specific parameters to generate a blueprint
      operationId: EvaluateTemplate
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TemplateEvaluationRequest'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/templates/{id}/validate:
    post:
      tags:
      - Templates
      summary: Validate parameters
      description: Validate parameters against a template's parameter schema
      operationId: ValidateTemplateParameters
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/templates/{id}/examples/{exampleName}:
    get:
      tags:
      - Templates
      summary: Evaluate template example
      description: Evaluate a predefined example from the template
      operationId: EvaluateTemplateExample
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      - name: exampleName
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/templates/{id}/increment-usage:
    post:
      tags:
      - Templates
      summary: Increment template usage count
      description: Increments the usage counter for a template after it has been used to create a blueprint
      operationId: IncrementTemplateUsage
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/actions/{wallet}/{register}/blueprints:
    get:
      tags:
      - Actions
      summary: Get available blueprints
      description: Retrieve blueprints and actions available to a specific wallet/register combination
      operationId: GetAvailableBlueprints
      parameters:
      - name: wallet
        in: path
        required: true
        schema:
          type: string
      - name: register
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/actions/{wallet}/{register}/blueprints/{blueprintId}:
    get:
      tags:
      - Actions
      summary: Get published blueprint detail
      description: Retrieve a single published blueprint including full action schemas. Sourced from the published blueprint store — works on any node, not just the authoring node.
      operationId: GetPublishedBlueprintDetail
      parameters:
      - name: wallet
        in: path
        required: true
        schema:
          type: string
      - name: register
        in: path
        required: true
        schema:
          type: string
      - name: blueprintId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/actions/{wallet}/{register}:
    get:
      tags:
      - Actions
      summary: Get actions for wallet/register
      description: Retrieve paginated list of actions for a specific wallet and register
      operationId: GetActions
      parameters:
      - name: wallet
        in: path
        required: true
        schema:
          type: string
      - name: register
        in: path
        required: true
        schema:
          type: string
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      responses:
        200:
          description: OK
  /api/blueprint/api/actions/{wallet}/{register}/{tx}:
    get:
      tags:
      - Actions
      summary: Get action details
      description: Retrieve detailed information about a specific action transaction
      operationId: GetActionDetails
      parameters:
      - name: wallet
        in: path
        required: true
        schema:
          type: string
      - name: register
        in: path
        required: true
        schema:
          type: string
      - name: tx
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/actions:
    post:
      tags:
      - Actions
      summary: Submit an action
      description: Submit a new action for execution in a blueprint workflow
      operationId: SubmitAction
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActionSubmissionRequest'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/actions/reject:
    post:
      tags:
      - Actions
      summary: Reject an action
      description: Reject a pending action with a reason
      operationId: RejectAction
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActionRejectionRequest'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/execution/validate:
    post:
      tags:
      - Execution
      summary: Validate action data
      description: Validate action data against the action's JSON Schema without executing the full workflow
      operationId: ValidateAction
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ValidateRequest'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/execution/calculate:
    post:
      tags:
      - Execution
      summary: Apply calculations
      description: Apply JSON Logic calculations to action data without executing the full workflow
      operationId: CalculateAction
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CalculateRequest'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/execution/route:
    post:
      tags:
      - Execution
      summary: Determine routing
      description: Determine the next action and participant based on routing conditions
      operationId: DetermineRouting
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RouteRequest'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/execution/disclose:
    post:
      tags:
      - Execution
      summary: Apply disclosure rules
      description: Apply selective disclosure rules to see what data each participant will receive
      operationId: ApplyDisclosure
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DiscloseRequest'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/notifications/transaction-confirmed:
    post:
      tags:
      - Notifications
      summary: Notify transaction confirmed
      description: Internal endpoint for Register Service to notify of transaction confirmations (requires service authentication)
      operationId: NotifyTransactionConfirmed
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransactionConfirmationNotification'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/instances:
    get:
      tags:
      - Instances
      summary: List workflow instances for the authenticated user
      description: Returns paginated workflow instances where the authenticated user's wallet is a participant. Supports optional status filtering (Active, Completed, Rejected, TimedOut, Cancelled).
      operationId: ListInstances
      parameters:
      - name: status
        in: query
        schema:
          $ref: '#/components/schemas/InstanceState'
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      responses:
        200:
          description: OK
    post:
      tags:
      - Instances
      summary: Create workflow instance
      description: Create a new workflow instance for a published blueprint
      operationId: CreateInstance
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateInstanceRequest'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/instances/{instanceId}:
    get:
      tags:
      - Instances
      summary: Get workflow instance
      description: Retrieve a workflow instance by its ID
      operationId: GetInstance
      parameters:
      - name: instanceId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/instances/{instanceId}/actions/{actionId}/execute:
    post:
      tags:
      - Instances
      summary: Execute action with orchestration
      description: 'Execute an action in a workflow instance with full orchestration: state reconstruction, validation, routing, transaction building, and notification. Requires X-Delegation-Token header.'
      operationId: ExecuteAction
      parameters:
      - name: instanceId
        in: path
        required: true
        schema:
          type: string
      - name: actionId
        in: path
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActionSubmissionRequest'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/instances/{instanceId}/actions/{actionId}/reject:
    post:
      tags:
      - Instances
      summary: Reject action in workflow
      description: Reject an action in a workflow instance, routing to the configured rejection target. Requires X-Delegation-Token header.
      operationId: RejectActionInInstance
      parameters:
      - name: instanceId
        in: path
        required: true
        schema:
          type: string
      - name: actionId
        in: path
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActionRejectionRequest'
        required: true
      responses:
        200:
          description: OK
  /api/blueprint/api/instances/{instanceId}/state:
    get:
      tags:
      - Instances
      summary: Get accumulated state
      description: Get the accumulated state from all prior actions in the workflow. Requires X-Delegation-Token header.
      operationId: GetInstanceState
      parameters:
      - name: instanceId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/instances/{instanceId}/next-actions:
    get:
      tags:
      - Instances
      summary: Get next available actions
      description: Get the next available actions that can be executed in the workflow instance
      operationId: GetNextActions
      parameters:
      - name: instanceId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/internal/instances/{registerId}/{instanceId}/parity:
    get:
      tags:
      - Instances
      summary: Check instance projection parity
      description: Rebuilds the instance from the register's sealed transactions and reports whether it matches the materialized view (Feature 145 US4 self-check).
      operationId: CheckInstanceParity
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: instanceId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/blueprint/api/internal/instances/{registerId}/{instanceId}/rebuild:
    post:
      tags:
      - Instances
      summary: Rebuild instance from the ledger
      description: "Operator repair: reconstructs the instance projection from the register's sealed transactions and overwrites the materialized view (Feature 145 US4)."
      operationId: RebuildInstance
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: instanceId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/tenant/api/users/{userId}/passkeys/recovery-key:
    get:
      tags:
      - Passkey
      summary: Get passkey public key for recovery key wrapping
      description: Returns the primary passkey's public key for the specified user. Used by Wallet Service for recovery key wrapping during wallet creation.
      operationId: GetPasskeyRecoveryKey
      parameters:
      - name: userId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasskeyRecoveryKeyResponse'
        404:
          description: Not Found
  /api/tenant/api/me/auth-methods:
    get:
      tags:
      - Auth Methods
      summary: List all sign-in methods attached to the signed-in user
      description: Returns email + verification status, password presence, every linked social provider, and every Active/Disabled passkey with per-row CanRemove flags. Powers the Accounts tab in Settings.
      operationId: GetMyAuthMethods
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthMethodsResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/tenant/orgs/{orgId}/did.json:
    get:
      tags:
      - OrgDidDocumentEndpoints
      summary: Resolve the published DID document for an organisation
      description: Returns the W3C DID Core document published for the organisation as application/did+json. The document declares the canonical did:sorcha:org:* identifier alongside the federated did:web:{platform}:orgs:{orgId} form via alsoKnownAs, and lists every Active issuance key under both versioned and RFC 7638 thumbprint kid styles. Anonymous, cacheable for 6h.
      operationId: ResolveOrgDidDocument
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
        404:
          description: Not Found
  /api/tenant/orgs/{orgId}/did-document/regenerate:
    post:
      tags:
      - OrgDidDocumentEndpoints
      summary: Regenerate the published DID document for an organisation
      description: Internal endpoint used by Wallet Service after a key event (issuance key derivation / rotation / revocation). Rebuilds the document from the supplied key snapshot, persists it, and returns the new version. Idempotent — returns the existing row unchanged if the recomputed key-version fingerprint matches.
      operationId: RegenerateOrgDidDocument
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrgDidRegenerateRequest'
        required: true
      responses:
        200:
          description: OK
  /api/tenant/api/organizations/{organizationId}/dashboard-summary:
    get:
      tags:
      - Dashboard
      summary: Get the org-scoped dashboard summary
      description: Returns active users, pending invitations, subscribed registers, and recent transactions across subscribed registers — the four cards rendered on Home.razor in org-scope view.
      operationId: GetOrgDashboardSummary
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrgSummaryResponse'
        401:
          description: Unauthorized
  /api/tenant/api/me/subscribed-registers:
    get:
      tags:
      - Register Subscriptions
      summary: List registers the current user's organization is subscribed to
      description: Resolves the organization from the authenticated user's org_id JWT claim and returns all active register subscriptions for that organization.
      operationId: GetMySubscribedRegisters
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RegisterSubscriptionResponse'
        401:
          description: Unauthorized
  /api/tenant/api/internal/inbox:
    post:
      tags:
      - Internal
      - Inbox
      summary: Write an inbox entry on behalf of a user. Idempotent on (PlatformUserId, SourceEventId).
      operationId: WriteInboxEntry
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InboxWriteRequestDto'
        required: true
      responses:
        200:
          description: OK
  /api/tenant/api/tenants/bootstrap:
    post:
      tags:
      - Bootstrap
      summary: Bootstrap fresh Sorcha installation
      description: >-
        Atomically creates initial organization, administrator user, and optional service principal.

        This endpoint is designed for first-time platform setup.


        **Security Notes:**

        - This endpoint should be protected in production (e.g., firewall rules, one-time tokens)

        - Consider disabling after initial setup via configuration

        - Password must meet complexity requirements


        **What gets created:**

        1. New organization with specified name and subdomain

        2. Administrator user with full permissions

        3. JWT access and refresh tokens for immediate use

        4. Optional service principal for automation


        **Response includes:**

        - Organization and user IDs

        - Admin JWT tokens (access + refresh)

        - Service principal credentials (if requested)
      operationId: BootstrapPlatform
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BootstrapRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BootstrapResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        409:
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        500:
          description: Internal Server Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
  /api/tenant/api/organizations:
    post:
      tags:
      - Organizations
      summary: Create a new organization
      description: Creates a new organization. The authenticated user becomes the organization administrator.
      operationId: CreateOrganization
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOrganizationRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationResponse'
        409:
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
    get:
      tags:
      - Organizations
      summary: List organizations
      description: Lists all organizations. Requires administrator role.
      operationId: ListOrganizations
      parameters:
      - name: includeInactive
        in: query
        schema:
          type: boolean
          default: false
      - name: pageNumber
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 50
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationListResponse'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{id}:
    get:
      tags:
      - Organizations
      summary: Get organization details
      description: Gets details of a specific organization.
      operationId: GetOrganization
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
    put:
      tags:
      - Organizations
      summary: Update an organization
      description: Updates an existing organization. Requires administrator role.
      operationId: UpdateOrganization
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOrganizationRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationResponse'
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
    delete:
      tags:
      - Organizations
      summary: Deactivate an organization
      description: Soft deletes an organization. Data retained for 30 days. Requires administrator role.
      operationId: DeactivateOrganization
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/by-subdomain/{subdomain}:
    get:
      tags:
      - Organizations
      summary: Get organization by subdomain
      description: Gets an organization by its subdomain.
      operationId: GetOrganizationBySubdomain
      parameters:
      - name: subdomain
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationResponse'
        404:
          description: Not Found
  /api/tenant/api/organizations/stats:
    get:
      tags:
      - Organizations
      summary: Get organization statistics
      description: Gets count of active organizations. Public endpoint for dashboard.
      operationId: GetOrganizationStats
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrganizationStatsResponse'
  /api/tenant/api/organizations/validate-subdomain/{subdomain}:
    get:
      tags:
      - Organizations
      summary: Validate subdomain availability
      description: Checks if a subdomain is valid and available.
      operationId: ValidateSubdomain
      parameters:
      - name: subdomain
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubdomainValidationResponse'
        400:
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubdomainValidationResponse'
  /api/tenant/api/organizations/{organizationId}/users:
    post:
      tags:
      - Organizations
      summary: Add user to organization
      description: Adds a user to the organization. Requires administrator role.
      operationId: AddUserToOrganization
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AddUserToOrganizationRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserResponse'
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
    get:
      tags:
      - Organizations
      summary: List organization users
      description: Lists all users in the organization.
      operationId: GetOrganizationUsers
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: includeInactive
        in: query
        schema:
          type: boolean
          default: false
      - name: emailVerified
        in: query
        schema:
          type: boolean
      - name: provisionedVia
        in: query
        schema:
          type: string
      - name: includePending
        in: query
        schema:
          type: boolean
          default: false
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserListResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/users/provision:
    post:
      tags:
      - Organizations
      summary: Provision an org-scoped password user
      description: Creates a NEW single-org password user (no public account, no invitation) in the organization. The emailVerified bypass is gated by Platform:AllowAdminVerifiedUserCreation. Requires administrator role.
      operationId: ProvisionOrgUser
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProvisionOrgUserRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserResponse'
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/users/{userId}:
    get:
      tags:
      - Organizations
      summary: Get organization user
      description: Gets details of a specific user in the organization.
      operationId: GetOrganizationUser
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: userId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
    put:
      tags:
      - Organizations
      summary: Update organization user
      description: Updates a user in the organization. Requires administrator role.
      operationId: UpdateOrganizationUser
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: userId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateUserRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserResponse'
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
    delete:
      tags:
      - Organizations
      summary: Remove user from organization
      description: Removes a user from the organization. Requires administrator role.
      operationId: RemoveUserFromOrganization
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: userId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/users/{userId}/unlock:
    post:
      tags:
      - Organizations
      summary: Unlock a locked user account
      description: Resets the failed login counter and removes lockout for a user account.
      operationId: UnlockUser
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: userId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/users/{userId}/suspend:
    post:
      tags:
      - Organizations
      summary: Suspend a user account
      description: Suspends a user account, preventing authentication. Active sessions are invalidated.
      operationId: SuspendUser
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: userId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/users/{userId}/reactivate:
    post:
      tags:
      - Organizations
      summary: Reactivate a suspended user account
      description: Reactivates a previously suspended user account.
      operationId: ReactivateUser
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: userId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
        400:
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/users/{userId}/verify-email:
    post:
      tags:
      - Organizations
      summary: Admin override to mark user email as verified
      description: Allows an organisation administrator to mark a user's email as verified without requiring the email verification loop. Sets EmailVerified=true, clears verification token, records audit event.
      operationId: AdminVerifyEmail
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: userId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        400:
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/users/{userId}/role:
    put:
      tags:
      - Organizations
      summary: Change a user's role
      description: Changes a user's role. Cannot target SystemAdmin users or assign SystemAdmin role.
      operationId: ChangeUserRole
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: userId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangeUserRoleRequest'
        required: true
      responses:
        200:
          description: OK
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{orgId}/recovery-config:
    post:
      tags:
      - Organizations
      summary: Configure organization recovery key pair
      description: Sets the organization's ED25519 recovery public key for wrapping wallet recovery keys. Requires Administrator role.
      operationId: CreateOrgRecoveryConfig
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrgRecoveryConfigRequest'
        required: true
      responses:
        201:
          description: Created
        409:
          description: Conflict
    get:
      tags:
      - Organizations
      summary: Get organization recovery configuration
      description: Returns the organization's recovery key configuration status. Requires org membership.
      operationId: GetOrgRecoveryConfig
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
        404:
          description: Not Found
  /api/tenant/api/organizations/{organizationId}/participants:
    post:
      tags:
      - Participants
      summary: Register a user as a participant
      description: Registers a user as a participant in the organization. Requires administrator role.
      operationId: CreateParticipant
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateParticipantRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantDetailResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        409:
          description: Conflict
        401:
          description: Unauthorized
        403:
          description: Forbidden
    get:
      tags:
      - Participants
      summary: List participants in organization
      description: Lists all participants in the organization with pagination.
      operationId: ListParticipants
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      - name: status
        in: query
        schema:
          $ref: '#/components/schemas/ParticipantIdentityStatus'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantListResponse'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/participants/{id}:
    get:
      tags:
      - Participants
      summary: Get participant details
      description: Gets details of a specific participant including linked wallets.
      operationId: GetParticipant
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantDetailResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
    put:
      tags:
      - Participants
      summary: Update participant
      description: Updates a participant's information. Requires administrator role.
      operationId: UpdateParticipant
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateParticipantRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantDetailResponse'
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
    delete:
      tags:
      - Participants
      summary: Deactivate participant
      description: Soft deletes a participant. Audit trail preserved. Requires administrator role.
      operationId: DeactivateParticipant
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/participants/{id}/suspend:
    post:
      tags:
      - Participants
      summary: Suspend participant
      description: Temporarily suspends a participant. Requires administrator role.
      operationId: SuspendParticipant
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/participants/{id}/reactivate:
    post:
      tags:
      - Participants
      summary: Reactivate participant
      description: Reactivates a suspended or inactive participant. Requires administrator role.
      operationId: ReactivateParticipant
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/participants/publish:
    post:
      tags:
      - Participants
      summary: Publish a participant record to a register
      description: Builds a Participant transaction, signs with the specified wallet, and submits via the validator pipeline.
      operationId: PublishParticipantRecord
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublishParticipantRequest'
        required: true
      responses:
        202:
          description: Accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantPublishResult'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        409:
          description: Conflict
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/participants/publish/{participantId}:
    put:
      tags:
      - Participants
      summary: Update a published participant record
      description: Publishes a new version of the participant record with updated fields. Version is auto-incremented.
      operationId: UpdateParticipantRecord
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: participantId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdatePublishedParticipantRequest'
        required: true
      responses:
        202:
          description: Accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantPublishResult'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
    delete:
      tags:
      - Participants
      summary: Revoke a published participant record
      description: Publishes a new version with status 'Revoked'. The participant is excluded from default queries.
      operationId: RevokeParticipantRecord
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: participantId
        in: path
        required: true
        schema:
          type: string
      - name: registerId
        in: query
        required: true
        schema:
          type: string
      - name: signerWalletAddress
        in: query
        required: true
        schema:
          type: string
      responses:
        202:
          description: Accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantPublishResult'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/participants/{id}/wallet-links:
    post:
      tags:
      - Participants
      summary: Initiate wallet link
      description: Initiates a wallet link challenge. Returns a message that must be signed.
      operationId: InitiateWalletLink
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InitiateWalletLinkRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletLinkChallengeResponse'
        404:
          description: Not Found
        409:
          description: Conflict
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
    get:
      tags:
      - Participants
      summary: List wallet links
      description: Lists all linked wallet addresses for a participant.
      operationId: ListWalletLinks
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: includeRevoked
        in: query
        schema:
          type: boolean
          default: false
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/LinkedWalletAddressResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/tenant/api/organizations/{organizationId}/participants/{id}/wallet-links/{challengeId}/verify:
    post:
      tags:
      - Participants
      summary: Verify wallet link
      description: Verifies a wallet link challenge with a signature.
      operationId: VerifyWalletLink
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: challengeId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyWalletLinkRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LinkedWalletAddressResponse'
        404:
          description: Not Found
        400:
          description: Bad Request
        409:
          description: Conflict
        401:
          description: Unauthorized
  /api/tenant/api/organizations/{organizationId}/participants/{id}/wallet-links/{linkId}:
    delete:
      tags:
      - Participants
      summary: Revoke wallet link
      description: Revokes a linked wallet address (soft delete). Requires administrator or self.
      operationId: RevokeWalletLink
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: linkId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/participants/search:
    post:
      tags:
      - Participants
      summary: Search participants
      description: Searches participants across accessible organizations.
      operationId: SearchParticipants
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ParticipantSearchRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantSearchResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/participants/by-wallet/{address}:
    get:
      tags:
      - Participants
      summary: Get participant by wallet address
      description: Finds a participant by their linked wallet address.
      operationId: GetParticipantByWallet
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/tenant/api/me/participant-profiles:
    get:
      tags:
      - User Profile
      summary: Get my participant profiles
      description: Gets all participant profiles for the current user across organizations.
      operationId: GetMyParticipantProfiles
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ParticipantDetailResponse'
        401:
          description: Unauthorized
  /api/tenant/api/me/organizations/{organizationId}/self-register:
    post:
      tags:
      - User Profile
      summary: Self-register as participant
      description: Registers the current user as a participant in the organization.
      operationId: SelfRegisterAsParticipant
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: displayName
        in: query
        schema:
          type: string
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantDetailResponse'
        400:
          description: Bad Request
        409:
          description: Conflict
        401:
          description: Unauthorized
  /api/tenant/api/organizations/{organizationId}/participants/by-user/{userId}:
    get:
      tags:
      - Participants (Service)
      summary: Get participant by user ID (service-to-service)
      description: Looks up a participant by user ID and organization. Used for wallet ownership validation.
      operationId: GetParticipantByUser
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: userId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ParticipantDetailResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/tenant/api/participants/{participantId}/wallet-links:
    get:
      tags:
      - Participants (Service)
      summary: Get wallet links by participant ID (service-to-service)
      description: Gets linked wallet addresses for a participant. Used for wallet ownership validation.
      operationId: GetParticipantWalletLinks
      parameters:
      - name: participantId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: includeRevoked
        in: query
        schema:
          type: boolean
          default: false
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/LinkedWalletAddressResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/tenant/api/internal/participants/auto-link:
    post:
      tags:
      - Participants (Internal)
      summary: Auto-register participant and link wallet (internal)
      description: Called by Wallet Service after wallet creation. Registers participant if needed and links wallet without challenge/verify flow. Ownership proven by mnemonic generation.
      operationId: AutoLinkWallet
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AutoLinkWalletRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AutoLinkResult'
        400:
          description: Bad Request
        401:
          description: Unauthorized
  /api/tenant/api/auth/login:
    post:
      tags:
      - Authentication
      summary: Login with email and password
      description: Authenticates a user with email and password. Returns access/refresh tokens on success, or a loginToken with requiresTwoFactor=true if the user has TOTP 2FA enabled.
      operationId: Login
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LoginRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TwoFactorLoginResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/auth/verify-2fa:
    post:
      tags:
      - Authentication
      summary: Verify TOTP 2FA code to complete login
      description: Accepts a loginToken (from login response) and a TOTP code or backup code. Returns access/refresh tokens on successful verification.
      operationId: Verify2Fa
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Verify2FaRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/auth/select-org:
    post:
      tags:
      - Authentication
      summary: Complete login by selecting an organisation
      description: After a login response with requires_org_selection=true, submit the platform login token and chosen organisation ID to receive access/refresh tokens.
      operationId: SelectOrg
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CompleteOrgSelectionRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TwoFactorLoginResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/auth/token/refresh:
    post:
      tags:
      - Authentication
      summary: Refresh access token
      description: Exchanges a valid refresh token for a new access token.
      operationId: RefreshToken
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TokenRefreshRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/auth/token/revoke:
    post:
      tags:
      - Authentication
      summary: Revoke a token
      description: Revokes an access or refresh token, preventing future use.
      operationId: RevokeToken
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TokenRevocationRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/auth/token/introspect:
    post:
      tags:
      - Authentication
      summary: Introspect a token
      description: Returns information about a token, including whether it is active. Service tokens only.
      operationId: IntrospectToken
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TokenIntrospectionRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenIntrospectionResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/auth/token/revoke-user:
    post:
      tags:
      - Authentication
      summary: Revoke all tokens for a user
      description: Revokes all access and refresh tokens for a specific user. Administrator only.
      operationId: RevokeUserTokens
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RevokeUserTokensRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/auth/token/revoke-organization:
    post:
      tags:
      - Authentication
      summary: Revoke all tokens for an organization
      description: Revokes all access and refresh tokens for all users in an organization. Administrator only.
      operationId: RevokeOrganizationTokens
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RevokeOrganizationTokensRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/auth/me:
    get:
      tags:
      - Authentication
      summary: Get current user information
      description: Returns information about the currently authenticated user from their token claims.
      operationId: GetCurrentUser
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CurrentUserResponse'
        401:
          description: Unauthorized
  /api/tenant/api/auth/register:
    post:
      tags:
      - Authentication
      summary: Self-register with email/password
      description: Creates a local account for public organizations with self-registration enabled. Validates password against NIST policy and HIBP breach list. Sends verification email.
      operationId: Register
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SelfRegistrationRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SelfRegistrationResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        403:
          description: Forbidden
  /api/tenant/api/auth/verify-passkey/options:
    post:
      tags:
      - Authentication
      summary: Get passkey assertion options for 2FA login
      description: Validates the login token and returns FIDO2 assertion options scoped to the user's registered passkeys. The returned options and transaction ID are used in the verify-passkey endpoint.
      operationId: VerifyPasskeyOptions
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasskeyAssertionOptionsRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasskeyAssertionOptionsResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/auth/verify-passkey:
    post:
      tags:
      - Authentication
      summary: Verify passkey assertion to complete 2FA login
      description: Verifies the passkey assertion response and issues access/refresh tokens on success. Requires a valid login token from the initial login response.
      operationId: VerifyPasskey
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasskeyVerifyRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/auth/logout:
    post:
      tags:
      - Authentication
      summary: Logout and revoke current token
      description: Logs out the current user by revoking their access token.
      operationId: Logout
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        401:
          description: Unauthorized
  /api/tenant/api/auth/me/organizations:
    get:
      tags:
      - Authentication
      summary: List organisations the current user belongs to
      description: Returns all org memberships for the authenticated PlatformUser. Used by the org switcher UI. Includes org name, subdomain, role, and isCurrent flag.
      operationId: GetMyOrganizations
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrgMembershipListResponse'
        401:
          description: Unauthorized
  /api/tenant/api/auth/switch-org:
    post:
      tags:
      - Authentication
      summary: Switch active organisation context
      description: Issues a new JWT scoped to the target org. Validates the user has a PlatformUserOrgMembership for the target org and an active UserIdentity.
      operationId: SwitchOrganization
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SwitchOrgRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/auth/create-org:
    post:
      tags:
      - Authentication
      summary: Create a new private organisation
      description: Self-service org creation for public org members. Validates eligibility (email verified, within org limit, subdomain available) and atomically provisions the org with the caller as admin.
      operationId: CreateOrganizationSelfService
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProvisionOrgRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrgProvisioningResult'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/passkey/register/options:
    post:
      tags:
      - Passkey
      summary: Generate passkey registration challenge
      description: Creates FIDO2 credential creation options for registering a new passkey. Returns a transaction ID and challenge options to pass to the browser WebAuthn API.
      operationId: PasskeyRegisterOptions
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasskeyRegisterOptionsRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasskeyRegistrationOptionsResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/passkey/register/verify:
    post:
      tags:
      - Passkey
      summary: Verify passkey registration attestation
      description: Verifies the attestation response from the authenticator and creates a new passkey credential. The transaction ID must match a pending registration challenge.
      operationId: PasskeyRegisterVerify
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasskeyRegisterVerifyRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasskeyCredentialResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/passkey/credentials:
    get:
      tags:
      - Passkey
      summary: List user's passkey credentials
      description: Returns all passkey credentials registered by the current user.
      operationId: PasskeyListCredentials
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasskeyCredentialListResponse'
        401:
          description: Unauthorized
  /api/tenant/api/passkey/credentials/{id}:
    put:
      tags:
      - Passkey
      summary: Rename a passkey credential
      description: Updates the user-visible display name of an Active passkey credential. Disabled or Revoked credentials cannot be renamed (returns 409). No re-authentication challenge is required for rename.
      operationId: PasskeyRenameCredential
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasskeyRenameRequest'
        required: true
      responses:
        204:
          description: No Content
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
        409:
          description: Conflict
    delete:
      tags:
      - Passkey
      summary: Soft-revoke a passkey credential
      description: Transitions an Active passkey to Revoked (preserving the audit row). Active passkeys require a fresh re-authentication challenge in the X-Auth-Challenge header. Disabled passkeys (already non-functional) bypass the challenge requirement. Removing a credential that would leave the user with zero sign-in methods is rejected with 409.
      operationId: PasskeyDeleteCredential
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
        409:
          description: Conflict
  /api/tenant/api/auth/challenge/initiate:
    post:
      tags:
      - Auth Challenge
      summary: Begin a re-authentication challenge
      description: Selects a proof method per the ladder (TOTP → Password → Passkey → re-OAuth) and prepares the appropriate dialog input. Returns 400 when the user has no enrolled method (only reachable in the bootstrap edge case).
      operationId: InitiateAuthChallenge
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChallengeInitiateRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChallengeInitiateResponse'
        400:
          description: Bad Request
        401:
          description: Unauthorized
  /api/tenant/api/auth/challenge/verify:
    post:
      tags:
      - Auth Challenge
      summary: Submit challenge proof and receive a one-shot token
      description: Verifies the user's proof for an in-flight challenge. On success, returns an opaque single-use token (5-minute lifetime) that the caller presents in the X-Auth-Challenge header on the subsequent mutation call.
      operationId: VerifyAuthChallenge
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChallengeVerifyRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChallengeVerifyResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/auth/password/set:
    post:
      tags:
      - Password
      summary: Set an initial password
      description: Sets a password on a user that does not currently have one. Requires a fresh X-Auth-Challenge token issued for SetPassword unless the user has zero other sign-in methods (bootstrap mode — bypasses the challenge). Returns 409 if the user already has a password.
      operationId: SetPassword
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasswordRequest'
        required: true
      responses:
        204:
          description: No Content
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        409:
          description: Conflict
  /api/tenant/api/auth/password/change:
    post:
      tags:
      - Password
      summary: Rotate the password
      description: Replaces the current password with a new one. Requires a fresh X-Auth-Challenge token issued for ChangePassword. Returns 409 if no password is currently set.
      operationId: ChangePassword
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PasswordRequest'
        required: true
      responses:
        204:
          description: No Content
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        409:
          description: Conflict
  /api/tenant/api/auth/password/remove:
    post:
      tags:
      - Password
      summary: Clear the password
      description: Removes the password from the user. Requires a fresh X-Auth-Challenge token issued for RemovePassword. Returns 409 if no password to remove or if removing it would leave the user with zero sign-in methods.
      operationId: RemovePassword
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
        409:
          description: Conflict
  /api/tenant/api/auth/public/passkey/register/options:
    post:
      tags:
      - Public Passkey Registration
      summary: Generate passkey registration options for new user signup
      description: Creates a new PlatformUser and generates FIDO2 credential creation options. The public organisation must be enabled. If an email is provided, it must be unique.
      operationId: PublicPasskeyRegisterOptions
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicPasskeyRegisterOptionsRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasskeyRegistrationOptionsResponse'
        400:
          description: Bad Request
        409:
          description: Conflict
  /api/tenant/api/auth/public/passkey/register/verify:
    post:
      tags:
      - Public Passkey Registration
      summary: Verify passkey registration and complete signup
      description: Verifies the attestation response from the authenticator, creates a UserIdentity in the public organisation, and issues a JWT access token.
      operationId: PublicPasskeyRegisterVerify
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicPasskeyRegisterVerifyRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicTokenResponse'
        400:
          description: Bad Request
  /api/tenant/api/auth/passkey/assertion/options:
    post:
      tags:
      - Public Passkey Authentication
      summary: Generate passkey assertion options for sign-in
      description: Creates FIDO2 assertion options for passwordless sign-in. Optionally accepts an email to narrow down allowed credentials.
      operationId: PublicPasskeyAssertionOptions
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicPasskeyAssertionOptionsRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PasskeyAssertionOptionsResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
  /api/tenant/api/auth/passkey/assertion/verify:
    post:
      tags:
      - Public Passkey Authentication
      summary: Verify passkey assertion and complete sign-in
      description: Verifies the assertion response from the authenticator, resolves the user, and issues a JWT access token.
      operationId: PublicPasskeyAssertionVerify
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublicPasskeyAssertionVerifyRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicTokenResponse'
        400:
          description: Bad Request
        401:
          description: Unauthorized
  /api/tenant/api/service-auth/token:
    post:
      tags:
      - Service Authentication
      summary: OAuth2 token endpoint
      description: 'OAuth2 compliant token endpoint. Supports grant types: password, client_credentials, refresh_token. Accepts both application/x-www-form-urlencoded and application/json content types.'
      operationId: GetOAuth2Token
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/service-auth/token/delegated:
    post:
      tags:
      - Service Authentication
      summary: Get delegated authority token
      description: Gets a service token that acts on behalf of a user.
      operationId: GetDelegatedToken
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DelegatedTokenRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/service-auth/rotate-secret:
    post:
      tags:
      - Service Authentication
      summary: Rotate service principal secret
      description: Rotates the client secret for a service principal. Requires current secret.
      operationId: RotateServiceSecret
      parameters:
      - name: clientId
        in: query
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RotateSecretRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RotateSecretResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/service-principals:
    post:
      tags:
      - Service Principals
      summary: Register a new service principal
      description: Registers a new service for service-to-service authentication. Returns credentials only once.
      operationId: RegisterServicePrincipal
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterServicePrincipalRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServicePrincipalRegistrationResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        409:
          description: Conflict
        401:
          description: Unauthorized
        403:
          description: Forbidden
    get:
      tags:
      - Service Principals
      summary: List all service principals
      description: Lists all registered service principals.
      operationId: ListServicePrincipals
      parameters:
      - name: includeInactive
        in: query
        schema:
          type: boolean
          default: false
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServicePrincipalListResponse'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/service-principals/{id}:
    get:
      tags:
      - Service Principals
      summary: Get service principal details
      description: Gets details of a specific service principal.
      operationId: GetServicePrincipal
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServicePrincipalResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
    delete:
      tags:
      - Service Principals
      summary: Revoke service principal
      description: Permanently revokes a service principal.
      operationId: RevokeServicePrincipal
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/service-principals/by-client/{clientId}:
    get:
      tags:
      - Service Principals
      summary: Get service principal by client ID
      description: Gets a service principal by its client ID.
      operationId: GetServicePrincipalByClientId
      parameters:
      - name: clientId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServicePrincipalResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/service-principals/{id}/scopes:
    put:
      tags:
      - Service Principals
      summary: Update service principal scopes
      description: Updates the allowed scopes for a service principal.
      operationId: UpdateServicePrincipalScopes
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                type: string
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServicePrincipalResponse'
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/service-principals/{id}/suspend:
    post:
      tags:
      - Service Principals
      summary: Suspend service principal
      description: Temporarily suspends a service principal.
      operationId: SuspendServicePrincipal
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/service-principals/{id}/reactivate:
    post:
      tags:
      - Service Principals
      summary: Reactivate service principal
      description: Reactivates a suspended service principal.
      operationId: ReactivateServicePrincipal
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SuccessResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/preferences:
    get:
      tags:
      - UserPreferences
      summary: Get user preferences
      description: Returns the authenticated user's preferences. If no preferences exist yet, creates a default set (Light theme, English, UTC, notifications enabled).
      operationId: GetUserPreferences
      responses:
        200:
          description: OK
    put:
      tags:
      - UserPreferences
      summary: Update user preferences
      description: 'Partially updates user preferences. Only non-null fields are applied. Valid themes: Light, Dark, System. Valid languages: en, fr, de, es. Valid time formats: UTC, Local.'
      operationId: UpdateUserPreferences
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdatePreferencesRequest'
        required: true
      responses:
        200:
          description: OK
  /api/tenant/api/preferences/default-wallet:
    get:
      tags:
      - UserPreferences
      summary: Get default wallet address
      description: Returns the user's default wallet address used for signing flows. Returns null if no default wallet is set.
      operationId: GetDefaultWallet
      responses:
        200:
          description: OK
    put:
      tags:
      - UserPreferences
      summary: Set default wallet address
      description: Sets the user's default wallet address for signing flows. Must be 200 characters or fewer.
      operationId: SetDefaultWallet
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetDefaultWalletRequest'
        required: true
      responses:
        200:
          description: OK
    delete:
      tags:
      - UserPreferences
      summary: Clear default wallet address
      description: Removes the user's default wallet address. Signing flows will require explicit wallet selection.
      operationId: ClearDefaultWallet
      responses:
        200:
          description: OK
  /api/tenant/api/v1/me/devices:
    get:
      tags:
      - Citizen Wallet Devices
      summary: List the authenticated citizen's enrolled wallet devices
      description: Mirror of GET /api/v1/wallet/devices reachable through the main Sorcha web UI for recovery flows. Returns active and revoked devices ordered by enrolment date descending.
      operationId: ListMyPlatformUserDevices
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceListResponse'
        401:
          description: Unauthorized
  /api/tenant/api/v1/me/devices/{deviceId}:
    delete:
      tags:
      - Citizen Wallet Devices
      summary: Revoke a citizen wallet device
      description: Marks the device as revoked on the Tenant Service. The Wallet Service status-list bit is flipped via the existing service-to-service channel (PR2). Returns 204 on success or first revocation, and 404 when the device does not exist or is not owned by the caller (the two cases are intentionally indistinguishable to avoid leaking device existence).
      operationId: RevokeMyPlatformUserDevice
      parameters:
      - name: deviceId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/tenant/api/v1/me/devices/has-any:
    get:
      tags:
      - Citizen Wallet Devices
      summary: Has the authenticated citizen paired at least one active device?
      description: Aggregate read used by F128 cold-start surfaces — the wallet PWA pairing takeover (FR-010) and the Sorcha Web nag banner (FR-024). Returns hasAnyDevice + the latest active-device enrolment timestamp; does not leak the per-device list.
      operationId: CheckMyPlatformUserHasAnyDevice
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HasAnyDeviceResponse'
        401:
          description: Unauthorized
  /api/tenant/api/me/persona:
    get:
      tags:
      - Persona
      summary: Get the signed-in user's persona for a context
      description: Returns the decrypted persona in PersonaReadModelV1 form for the requested organisational context (Feature 125). Omit the 'context' query parameter for the Personal context. Scalar attributes are wrapped in PersonaAttribute<T> carrying provenance (always SelfAsserted in v1). An empty persona (new user or no row) returns 200 with all fields null / empty lists — never 404. The optional 'actingAs' query parameter is reserved for future delegation; only the literal value 'self' is accepted in v1. 403 when the caller's JWT lacks an OrgMembership for the requested context.
      operationId: GetMyPersona
      parameters:
      - name: context
        in: query
        schema:
          type: string
          format: uuid
      - name: actingAs
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonaReadModelV1'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        401:
          description: Unauthorized
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        403:
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
    put:
      tags:
      - Persona
      summary: Replace the signed-in user's persona for a context (full replace)
      description: Validates the supplied PersonaAttributesV1 against the invariants in data-model.md §2 (list cap of 5, exactly one default per multi-value list, RFC 5322 email, E.164 phone, ISO 3166-1 alpha-2 country). Encrypts via the Wallet Service under the sorcha:persona-vault purpose and upserts the row keyed by (PlatformUserId, ContextOrgId). Omit the 'context' query parameter for the Personal context (Feature 125). Returns the canonical read model. 403 when the caller's JWT lacks an OrgMembership for the requested context.
      operationId: ReplaceMyPersona
      parameters:
      - name: context
        in: query
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PersonaAttributesV1'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonaReadModelV1'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        403:
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        409:
          description: Conflict
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
    delete:
      tags:
      - Persona
      summary: Wipe the signed-in user's persona for a context
      description: Hard-deletes the persona row for the requested context. Idempotent — returns 204 whether or not a row existed. Omit the 'context' query parameter for the Personal context (Feature 125). 403 when the caller's JWT lacks an OrgMembership for the requested context.
      operationId: DeleteMyPersona
      parameters:
      - name: context
        in: query
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        403:
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
  /api/tenant/api/address-lookup/postcode:
    post:
      tags:
      - AddressLookup
      summary: Look up a postcode and return validation metadata or full-address candidates
      description: Resolves the supplied postcode against the most capable available provider for the target country. Returns either a ValidateOnly result (postcode metadata + town/region) or a FullAddress result (list of address candidates). On provider unavailability or unknown postcode, returns 200 with IsValid=false and Provider='none' so the form renderer can fall back gracefully to plain text entry.
      operationId: LookupPostcode
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostcodeLookupRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AddressLookupResult'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
  /api/tenant/api/address-lookup/providers:
    get:
      tags:
      - AddressLookup
      summary: List configured address lookup providers and their capabilities
      description: Returns the set of providers currently registered in this deployment along with their capability (ValidateOnly | FullAddress), supported country codes, and current availability. Used by the form renderer to decide which UI to show for fields that declare x-address-lookup.
      operationId: ListAddressLookupProviders
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AddressLookupProviderInfo'
        401:
          description: Unauthorized
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
  /api/tenant/api/totp/setup:
    post:
      tags:
      - TOTP Two-Factor Authentication
      summary: Initiate TOTP 2FA setup
      description: Generates a new TOTP secret, QR code URI, and backup codes. Call verify endpoint with a code from your authenticator app to complete setup.
      operationId: TotpSetup
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TotpSetupResponse'
        401:
          description: Unauthorized
  /api/tenant/api/totp/verify:
    post:
      tags:
      - TOTP Two-Factor Authentication
      summary: Verify and enable TOTP 2FA
      description: Verifies the initial TOTP code from the authenticator app to complete enrollment. After this, the user will need to provide a TOTP code on every login.
      operationId: TotpVerify
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TotpCodeRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TotpVerifyResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/totp/validate:
    post:
      tags:
      - TOTP Two-Factor Authentication
      summary: Validate TOTP code during login
      description: Validates a TOTP code during the two-factor authentication login step. Requires the loginToken issued after successful password verification.
      operationId: TotpValidate
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TotpValidateRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TotpValidateResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/totp/backup-validate:
    post:
      tags:
      - TOTP Two-Factor Authentication
      summary: Validate backup code during login
      description: Validates and consumes a one-time backup code during the two-factor authentication login step. Each backup code can only be used once.
      operationId: TotpBackupValidate
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TotpBackupValidateRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TotpValidateResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/totp:
    delete:
      tags:
      - TOTP Two-Factor Authentication
      summary: Disable TOTP 2FA
      description: Removes TOTP two-factor authentication for the current user. Requires a fresh X-Auth-Challenge token issued for Disable2Fa — the user must prove possession of another sign-in method before the second factor can be cleared.
      operationId: TotpDisable
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TotpStatusResponse'
        401:
          description: Unauthorized
  /api/tenant/api/totp/status:
    get:
      tags:
      - TOTP Two-Factor Authentication
      summary: Get TOTP 2FA status
      description: Returns whether TOTP two-factor authentication is enabled for the current user.
      operationId: TotpStatus
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TotpStatusResponse'
        401:
          description: Unauthorized
  /api/tenant/api/organizations/{orgId}/idp:
    get:
      tags:
      - Identity Provider Configuration
      summary: Get IDP configuration
      description: Returns the identity provider configuration for an organization, including discovered endpoints and enabled status.
      operationId: GetIdpConfiguration
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdpConfigurationResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
    put:
      tags:
      - Identity Provider Configuration
      summary: Create or update IDP configuration
      description: 'Creates a new IDP configuration or updates an existing one. Automatically triggers OIDC discovery to populate endpoints. Supports provider presets: MicrosoftEntra, Google, Okta, Apple, AmazonCognito, GenericOidc.'
      operationId: CreateOrUpdateIdpConfiguration
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IdpConfigurationRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdpConfigurationResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
    delete:
      tags:
      - Identity Provider Configuration
      summary: Delete IDP configuration
      description: Removes the identity provider configuration for an organization. Users will no longer be able to sign in via SSO.
      operationId: DeleteIdpConfiguration
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{orgId}/idp/discover:
    post:
      tags:
      - Identity Provider Configuration
      summary: Discover IDP endpoints
      description: Fetches the OIDC discovery document (.well-known/openid-configuration) from the specified issuer URL and returns the discovered endpoints.
      operationId: DiscoverIdpEndpoints
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DiscoverIdpRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DiscoveryResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{orgId}/idp/test:
    post:
      tags:
      - Identity Provider Configuration
      summary: Test IDP connection
      description: Tests the IDP connection by attempting a client_credentials grant against the configured token endpoint. Verifies that the client ID and secret are valid.
      operationId: TestIdpConnection
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestConnectionResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{orgId}/idp/toggle:
    post:
      tags:
      - Identity Provider Configuration
      summary: Enable or disable IDP
      description: Enables or disables the identity provider for an organization. When disabled, users cannot sign in via SSO but the configuration is preserved.
      operationId: ToggleIdp
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ToggleIdpRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IdpConfigurationResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/auth/oidc/initiate:
    post:
      tags:
      - OIDC Authentication
      summary: Initiate OIDC login flow
      description: Generates an authorization URL for the organization's configured IDP. The client should redirect the user to this URL to begin the OIDC login flow.
      operationId: OidcInitiate
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OidcInitiateRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OidcInitiateResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        404:
          description: Not Found
  /api/tenant/api/auth/callback/{orgSubdomain}:
    get:
      tags:
      - OIDC Authentication
      summary: OIDC callback — exchange authorization code for Sorcha JWT
      description: Receives the authorization code from the external IDP, exchanges it for tokens, provisions or matches the user, and returns a Sorcha JWT.
      operationId: OidcCallback
      parameters:
      - name: orgSubdomain
        in: path
        required: true
        schema:
          type: string
      - name: code
        in: query
        schema:
          type: string
      - name: state
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OidcCallbackResult'
        400:
          description: Bad Request
        403:
          description: Forbidden
  /api/tenant/api/auth/oidc/complete-profile:
    post:
      tags:
      - OIDC Authentication
      summary: Complete user profile after OIDC login
      description: Updates missing profile fields (display name, email) for a user provisioned via OIDC whose IDP did not return all required claims.
      operationId: OidcCompleteProfile
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OidcCompleteProfileRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OidcCallbackResult'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/auth/verify-email:
    post:
      tags:
      - OIDC Authentication
      summary: Verify email address with token
      description: Validates an email verification token and marks the user's email as verified.
      operationId: VerifyEmail
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyEmailRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmailVerificationResponse'
        400:
          description: Bad Request
  /api/tenant/api/auth/resend-verification:
    post:
      tags:
      - OIDC Authentication
      summary: Resend email verification
      description: Resends an email verification token. Rate limited to 3 per hour per user.
      operationId: ResendVerification
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ResendVerificationRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmailVerificationResponse'
        401:
          description: Unauthorized
        429:
          description: Too Many Requests
  /api/tenant/api/auth/social/providers:
    get:
      tags:
      - Social Login
      summary: List configured social providers
      description: Returns the social providers that have working credentials on this host. Anonymous — drives the conditional 'Continue with…' buttons on the wallet sign-in screen.
      operationId: ListSocialProviders
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SocialProvidersResponse'
  /api/tenant/api/auth/social/initiate:
    post:
      tags:
      - Social Login
      summary: Start social login or link flow
      description: Generates an OAuth authorization URL for the specified provider. Pass intent=login (default) for the anonymous signup/login flow, or intent=link from a signed-in session to add the provider to the caller's existing PlatformUser. Feature 116 / Q6.
      operationId: InitiateSocialLogin
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SocialLoginInitiateRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SocialLoginInitiateResponse'
        400:
          description: Bad Request
        401:
          description: Unauthorized
  /api/tenant/api/auth/social/callback:
    post:
      tags:
      - Social Login
      summary: Complete social login or link with authorization code
      description: Exchanges the authorization code for user claims and dispatches on the intent recovered from the cached state token. login → resolve/create PlatformUser + JWT; link → verify caller matches captured PlatformUser + ISocialLinkService.LinkAsync.
      operationId: CompleteSocialLogin
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SocialLoginCallbackRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenResponse'
        204:
          description: No Content
        400:
          description: Bad Request
        401:
          description: Unauthorized
        409:
          description: Conflict
  /api/tenant/api/auth/social/{linkId}:
    delete:
      tags:
      - Social Login
      summary: Unlink a social provider from the signed-in user
      description: Hard-deletes the PlatformSocialLogin row. Requires a valid X-Auth-Challenge header scoped to RemoveAuthMethod. Returns 409 if removing would leave the user with zero sign-in methods. Feature 116 US1.
      operationId: UnlinkSocialProvider
      parameters:
      - name: linkId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
        404:
          description: Not Found
        409:
          description: Conflict
  /api/tenant/api/platform/settings:
    get:
      tags:
      - Platform Settings
      summary: Get platform settings
      description: Returns platform configuration including public org status and max orgs per user. Requires SystemAdmin role in the system admin organisation.
      operationId: GetPlatformSettings
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformSettingsResponse'
        403:
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
  /api/tenant/api/platform/settings/public-org:
    put:
      tags:
      - Platform Settings
      summary: Enable or disable the public organisation
      description: Atomically toggles the public org status and self-registration setting. When enabled, sets Organization.Status = Active and SelfRegistrationEnabled = true. When disabled, sets Organization.Status = Suspended and SelfRegistrationEnabled = false.
      operationId: UpdatePublicOrgSettings
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdatePublicOrgRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformSettingsResponse'
        403:
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
  /api/tenant/api/platform/settings/max-orgs:
    put:
      tags:
      - Platform Settings
      summary: Update maximum orgs per user setting
      description: Updates the maximum number of private organisations a single user can create. Value must be between 1 and 100.
      operationId: UpdateMaxOrgsPerUser
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateMaxOrgsRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PlatformSettingsResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        403:
          description: Forbidden
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
  /api/tenant/api/platform/organizations:
    post:
      tags:
      - Platform Organisations
      summary: Admin-initiated organisation creation with invite
      description: Creates a private org and invites the specified admin by email. If the admin email matches an existing PlatformUser, they are added directly. Otherwise, a pending invitation is created. Requires SystemAdmin role.
      operationId: AdminCreateOrganization
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdminCreateOrganizationRequest'
        required: true
      responses:
        200:
          description: OK
    get:
      tags:
      - Platform Organisations
      summary: List all organisations
      description: Returns paginated list of all orgs with metadata. System admin only.
      operationId: ListPlatformOrganizations
      parameters:
      - name: status
        in: query
        schema:
          type: string
      - name: page
        in: query
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: pageSize
        in: query
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      responses:
        200:
          description: OK
  /api/tenant/api/platform/organizations/{orgId}/status:
    put:
      tags:
      - Platform Organisations
      summary: Update organisation status
      description: Changes org status (Active/Suspended). Platform orgs cannot be suspended.
      operationId: UpdateOrganizationStatus
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOrgStatusRequest'
        required: true
      responses:
        200:
          description: OK
  /api/tenant/api/platform/organizations/{orgId}/users:
    get:
      tags:
      - Platform Organisations
      summary: View organisation user list
      description: Returns paginated user list for an org. Read-only audit view.
      operationId: GetOrganizationUsersPlatform
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: page
        in: query
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: pageSize
        in: query
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      responses:
        200:
          description: OK
  /api/tenant/api/platform/users:
    post:
      tags:
      - Platform User Management
      summary: Provision a platform user into an organisation
      description: Creates PlatformUser + UserIdentity + PlatformUserOrgMembership atomically. If a PlatformUser with the same email already exists, it is reused and linked to the target organisation. Supports optional password, role selection, and email verification skip. Requires SystemAdmin role.
      operationId: AdminProvisionUser
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdminProvisionUserRequest'
        required: true
      responses:
        200:
          description: OK
  /api/tenant/api/platform/users/{id}/password:
    put:
      tags:
      - Platform User Management
      summary: Reset a platform user's password
      description: Updates the password hash for a platform user. New password must comply with NIST password policy (min 12 characters, breach list check). Requires SystemAdmin role.
      operationId: AdminResetPassword
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdminResetPasswordRequest'
        required: true
      responses:
        200:
          description: OK
  /api/tenant/api/organizations/{orgId}/settings:
    get:
      tags:
      - Organization Settings
      summary: Get organization settings
      description: Returns org type, self-registration status, allowed email domains, and audit retention.
      operationId: GetOrgSettings
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrgSettingsResponse'
    put:
      tags:
      - Organization Settings
      summary: Update organization settings
      description: Updates self-registration status and audit retention period (1-120 months).
      operationId: UpdateOrgSettings
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OrgSettingsRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrgSettingsResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
  /api/tenant/api/organizations/{organizationId}/domain-restrictions:
    get:
      tags:
      - Domain Restrictions
      summary: Get domain restrictions
      description: Returns the allowed email domains for auto-provisioning and whether restrictions are active.
      operationId: GetDomainRestrictions
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DomainRestrictionsResponse'
        404:
          description: Not Found
    put:
      tags:
      - Domain Restrictions
      summary: Update domain restrictions
      description: Sets the allowed email domains for auto-provisioning. An empty array disables restrictions (all domains allowed). Invited users always bypass domain restrictions.
      operationId: UpdateDomainRestrictions
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateDomainRestrictionsRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DomainRestrictionsResponse'
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
  /api/tenant/api/organizations/{organizationId}/audit:
    get:
      tags:
      - Audit Log
      summary: Query audit log events
      description: Returns paginated audit events with optional filtering by date range, event type, and user. Max page size is 200.
      operationId: GetAuditEvents
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: startDate
        in: query
        schema:
          type: string
          format: date-time
      - name: endDate
        in: query
        schema:
          type: string
          format: date-time
      - name: eventType
        in: query
        schema:
          type: string
      - name: userId
        in: query
        schema:
          type: string
          format: uuid
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 50
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditLogResponse'
        404:
          description: Not Found
  /api/tenant/api/organizations/{organizationId}/audit/retention:
    get:
      tags:
      - Audit Log
      summary: Get audit retention configuration
      description: Returns the current audit log retention period in months for this organization.
      operationId: GetAuditRetention
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditRetentionResponse'
        404:
          description: Not Found
    put:
      tags:
      - Audit Log
      summary: Update audit retention period
      description: Sets the audit log retention period (1-120 months). Events older than this period are automatically purged daily.
      operationId: UpdateAuditRetention
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateAuditRetentionRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuditRetentionResponse'
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
  /api/tenant/api/organizations/{organizationId}/invitations:
    post:
      tags:
      - Invitations
      summary: Send an organization invitation
      description: Creates and sends an invitation email to join the organization with a specified role. Generates a 32-byte cryptographic token with configurable expiry (1-30 days, default 7).
      operationId: CreateInvitation
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateInvitationRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvitationResponse'
        409:
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
    get:
      tags:
      - Invitations
      summary: List organization invitations
      description: Lists all invitations for the organization, optionally filtered by status (Pending, Accepted, Expired, Revoked).
      operationId: ListInvitations
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: status
        in: query
        schema:
          $ref: '#/components/schemas/InvitationStatus'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/InvitationResponse'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/invitations/{invitationId}/revoke:
    post:
      tags:
      - Invitations
      summary: Revoke an invitation
      description: Revokes a pending invitation. Only Pending invitations can be revoked.
      operationId: RevokeInvitation
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: invitationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
        400:
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/dashboard:
    get:
      tags:
      - Dashboard
      summary: Get admin dashboard statistics
      description: Returns aggregated statistics including active/suspended user counts, role distribution, recent logins, pending invitations, and IDP configuration status.
      operationId: GetDashboard
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DashboardResponse'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{organizationId}/custom-domain:
    get:
      tags:
      - Custom Domain
      summary: Get custom domain configuration
      description: Returns the custom domain setup and verification status for the organization.
      operationId: GetCustomDomain
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomDomainResponse'
        401:
          description: Unauthorized
        403:
          description: Forbidden
    put:
      tags:
      - Custom Domain
      summary: Configure custom domain
      description: Sets or updates the custom domain. Returns CNAME instructions for DNS configuration.
      operationId: ConfigureCustomDomain
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ConfigureCustomDomainRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CnameInstructionsResponse'
        409:
          description: Conflict
        400:
          description: Bad Request
    delete:
      tags:
      - Custom Domain
      summary: Remove custom domain
      description: Removes the custom domain configuration for the organization.
      operationId: RemoveCustomDomain
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
  /api/tenant/api/organizations/{organizationId}/custom-domain/verify:
    post:
      tags:
      - Custom Domain
      summary: Verify custom domain CNAME
      description: Checks DNS resolution for the configured custom domain and updates verification status.
      operationId: VerifyCustomDomain
      parameters:
      - name: organizationId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DomainVerificationResponse'
        400:
          description: Bad Request
  /api/tenant/api/push-subscriptions:
    post:
      tags:
      - PushSubscriptions
      summary: Register a push notification subscription
      description: Registers or updates a Web Push API subscription for the authenticated user. Requires the push endpoint URL and VAPID keys (p256dh and auth).
      operationId: SubscribePush
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PushSubscriptionRequest'
        required: true
      responses:
        200:
          description: OK
    delete:
      tags:
      - PushSubscriptions
      summary: Remove a push notification subscription
      description: Removes an existing push notification subscription by endpoint URL. The user will no longer receive push notifications on that browser/device.
      operationId: UnsubscribePush
      parameters:
      - name: endpoint
        in: query
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/tenant/api/push-subscriptions/status:
    get:
      tags:
      - PushSubscriptions
      summary: Check if user has an active push subscription
      description: Returns whether the authenticated user has at least one active push notification subscription.
      operationId: GetPushStatus
      responses:
        200:
          description: OK
  /api/tenant/api/events:
    get:
      tags:
      - Events
      summary: Get activity events for the authenticated user
      description: Returns paginated activity events for the authenticated user. Supports filtering by severity (Info, Warning, Error, Critical), unread-only flag, and events since a specific timestamp. Default page size is 50.
      operationId: GetEvents
      parameters:
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 50
      - name: unreadOnly
        in: query
        schema:
          type: boolean
          default: false
      - name: severity
        in: query
        schema:
          type: string
      - name: since
        in: query
        schema:
          type: string
          format: date-time
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
    post:
      tags:
      - Events
      summary: Create an activity event (service-to-service)
      description: Creates a new activity event targeted at a specific user. Intended for service-to-service calls to notify users of system events. Requires service token authentication.
      operationId: CreateEvent
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateEventRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/tenant/api/events/unread-count:
    get:
      tags:
      - Events
      summary: Get unread event count
      description: Returns the count of unread activity events for the authenticated user. Useful for notification badge indicators in the UI.
      operationId: GetUnreadCount
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/tenant/api/events/mark-read:
    post:
      tags:
      - Events
      summary: Mark events as read
      description: Marks activity events as read. If EventIds array is provided, marks only those events. If EventIds is null or empty, marks all events as read for the authenticated user.
      operationId: MarkEventsRead
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/MarkReadRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/tenant/api/events/admin:
    get:
      tags:
      - Events
      summary: Get events for all users in organisation (admin only)
      description: Returns paginated activity events for all users in the authenticated admin's organisation. Supports filtering by user ID, severity, and timestamp. Requires Administrator or SystemAdmin role.
      operationId: GetAdminEvents
      parameters:
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 50
      - name: userId
        in: query
        schema:
          type: string
          format: uuid
      - name: severity
        in: query
        schema:
          type: string
      - name: since
        in: query
        schema:
          type: string
          format: date-time
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/events/{id}:
    delete:
      tags:
      - Events
      summary: Delete a specific event
      description: Deletes an activity event by ID. Only the event owner can delete their own events. Returns 404 if the event does not exist or belongs to another user.
      operationId: DeleteEvent
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/tenant/api/organizations/{orgId}/register-subscriptions:
    get:
      tags:
      - Register Subscriptions
      summary: List register subscriptions for an organization
      description: 'Returns a paginated list of register subscriptions for the specified organization. Supports page and pageSize query parameters (defaults: page=1, pageSize=25).'
      operationId: ListRegisterSubscriptions
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 25
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterSubscriptionListResponse'
        401:
          description: Unauthorized
        403:
          description: Forbidden
    post:
      tags:
      - Register Subscriptions
      summary: Subscribe organization to a register
      description: Creates a new subscription for the organization to a public register. Requires a valid 32-character hex register ID. Returns 409 if already subscribed.
      operationId: SubscribeToRegister
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubscribeRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterSubscriptionResponse'
        409:
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{orgId}/register-subscriptions/{registerId}:
    get:
      tags:
      - Register Subscriptions
      summary: Get a specific register subscription
      description: Returns the subscription details for a specific register within the organization. Returns 404 if the organization does not have a subscription to the specified register.
      operationId: GetRegisterSubscription
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterSubscriptionResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
    delete:
      tags:
      - Register Subscriptions
      summary: Unsubscribe organization from a register
      description: Revokes the organization's subscription to a register. Owner subscriptions cannot be revoked (returns 400). Returns 204 on success.
      operationId: UnsubscribeFromRegister
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        204:
          description: No Content
        400:
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
        404:
          description: Not Found
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/tenant/api/organizations/{orgId}/register-invitations:
    post:
      tags:
      - Register Invitations
      summary: Create a private register invitation
      description: Creates a signed and encrypted invitation token for a target organization to join a private register owned by this organization. The token is returned for out-of-band delivery (email, messaging, etc.).
      operationId: CreateRegisterInvitation
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateRegisterInvitationRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvitationCreatedResponse'
        400:
          description: Bad Request
        403:
          description: Forbidden
        429:
          description: Too Many Requests
    get:
      tags:
      - Register Invitations
      summary: List register invitations
      description: Lists invitations for this organization, optionally filtered by direction (sent, received, or all).
      operationId: ListRegisterInvitations
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: direction
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvitationListResponse'
  /api/tenant/api/organizations/{orgId}/register-invitations/accept:
    post:
      tags:
      - Register Invitations
      summary: Accept a register invitation
      description: 'Accepts an invitation token: decrypts, verifies the source signature, checks nonce replay protection, validates expiry and target organization, then creates an Invited subscription to the register.'
      operationId: AcceptRegisterInvitation
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AcceptInvitationRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvitationAcceptedResponse'
        400:
          description: Bad Request
        409:
          description: Conflict
  /api/tenant/api/organizations/{orgId}/register-invitations/{invitationId}:
    delete:
      tags:
      - Register Invitations
      summary: Revoke a pending invitation
      description: Revokes a pending invitation created by this organization. Already-accepted invitations cannot be revoked.
      operationId: RevokeRegisterInvitation
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: invitationId
        in: path
        required: true
        schema:
          type: string
      responses:
        204:
          description: No Content
        404:
          description: Not Found
  /api/tenant/api/v1/trust/tenants/{tenantId}/provision:
    post:
      tags:
      - Trust
      summary: Provision a self-signed root CA for a tenant
      description: Creates a self-signed X.509 root CA certificate for the tenant. Idempotent — returns the existing root if already provisioned.
      operationId: ProvisionTrustAnchor
      parameters:
      - name: tenantId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrustAnchorResponse'
  /api/tenant/api/v1/trust/tenants/{tenantId}/trust-anchor:
    get:
      tags:
      - Trust
      summary: Get the tenant's trust anchor certificate (DER)
      description: Returns the DER-encoded self-signed root CA certificate. Public endpoint — verifiers use it to validate organisation certificate chains.
      operationId: GetTrustAnchor
      parameters:
      - name: tenantId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
        404:
          description: Not Found
  /api/tenant/api/v1/trust/tenants/{tenantId}/orgs/{orgWalletAddress}/enrol:
    post:
      tags:
      - Trust
      summary: Issue an organisation certificate signed by the tenant root CA
      description: Issues an X.509 certificate for the organisation's HAIP classical co-key, signed by the tenant's root CA. Binds the org's DID to the certificate via SAN URI.
      operationId: EnrolOrgCert
      parameters:
      - name: tenantId
        in: path
        required: true
        schema:
          type: string
      - name: orgWalletAddress
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EnrolOrgCertRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrgCertEnrolmentResponse'
        400:
          description: Bad Request
  /api/tenant/api/v1/trust/tenants/{tenantId}/orgs/{orgWalletAddress}/cert-chain:
    get:
      tags:
      - Trust
      summary: Get the organisation's certificate chain (leaf + root)
      description: Returns the organisation certificate and the tenant root CA as base64-encoded DER. Used by the Wallet Service to populate the x5c JWS header on HAIP-path credentials.
      operationId: GetOrgCertChain
      parameters:
      - name: tenantId
        in: path
        required: true
        schema:
          type: string
      - name: orgWalletAddress
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CertChainResponse'
        404:
          description: Not Found
  /api/tenant/api/v1/trust/tenants/{tenantId}/orgs/{orgWalletAddress}/revoke:
    post:
      tags:
      - Trust
      summary: Revoke an organisation certificate
      description: Marks the organisation certificate as revoked and regenerates the tenant CRL. Subsequent CRL fetches will include the revoked serial. Idempotent.
      operationId: RevokeOrgCert
      parameters:
      - name: tenantId
        in: path
        required: true
        schema:
          type: string
      - name: orgWalletAddress
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
              - type: null
              - $ref: '#/components/schemas/RevokeOrgCertRequest'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrgCertEnrolmentResponse'
        400:
          description: Bad Request
        404:
          description: Not Found
  /api/tenant/api/v1/trust/tenants/{tenantId}/crl:
    get:
      tags:
      - Trust
      summary: Get the tenant's Certificate Revocation List (DER)
      description: Returns the DER-encoded signed CRL for the tenant root CA. Served as application/pkix-crl with a Cache-Control max-age aligned to the CRL's nextUpdate. Public endpoint — strict X.509 validators embed the CDP URL in org certs and fetch this endpoint during chain validation.
      operationId: GetTenantCrl
      parameters:
      - name: tenantId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
        404:
          description: Not Found
  /api/tenant/api/v1/trust/trustlists/{trustListId}:
    put:
      tags:
      - Trust
      summary: Upload or replace a trust-list snapshot
      description: Stores an operator-curated set of trusted X.509 root certificates (base64 DER) under the given id. Referenced by a credential requirement's trust policy `trustlist` source; the snapshot id + freshness are copied into the trust evidence on every decision that used the list. A live LOTL feed is a future provider behind the same seam.
      operationId: PutTrustListSnapshot
      parameters:
      - name: trustListId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UploadTrustListRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrustListSummaryResponse'
        400:
          description: Bad Request
    get:
      tags:
      - Trust
      summary: Get trust-list snapshot metadata
      description: Returns the snapshot id, root count, source, and freshness so operators can audit what is loaded. Not used per-verification (the trust source caches the roots).
      operationId: GetTrustListSnapshot
      parameters:
      - name: trustListId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TrustListSummaryResponse'
        404:
          description: Not Found
  /api/tenant/api/v1/trust/trustlists:
    get:
      tags:
      - Trust
      summary: List available trust-list snapshots
      description: Returns the id + freshness of every loaded trust-list snapshot.
      operationId: ListTrustListSnapshots
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TrustListSummaryResponse'
  /api/tenant/api/auth/enrol-session:
    post:
      tags:
      - EnrolSession
      summary: Mint a one-time enrolment session token for the signed-in caller.
      description: "Returns a JWT scoped to 'enrol', a QR URL embedding the token, the absolute expiry timestamp, and the mode discriminator. The caller must be authenticated. Request body is optional — omit (or send `mode: gated`) for F126 council-page callers; send `mode: standalone` for F128 cold-start callers."
      operationId: MintEnrolSession
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
              - type: null
              - $ref: '#/components/schemas/MintEnrolSessionRequest'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MintEnrolSessionResponse'
        401:
          description: Unauthorized
  /api/tenant/api/auth/enrol-session/redeem:
    post:
      tags:
      - EnrolSession
      summary: Redeem a one-time enrolment session token.
      description: "Anonymous (the token is the credential). Single-use: subsequent attempts to redeem the same token return 409. Returns the bound user's display name and email so the wallet PWA can surface a confirmation dialog before any device-pairing happens."
      operationId: RedeemEnrolSession
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RedeemEnrolSessionRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RedeemEnrolSessionResponse'
        400:
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RedeemEnrolSessionErrorBody'
        409:
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RedeemEnrolSessionErrorBody'
        410:
          description: Gone
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RedeemEnrolSessionErrorBody'
  /api/tenant/api/auth/enrol-session/short-code:
    post:
      tags:
      - PairingShortCode
      summary: Mint a 6-digit pairing short code for the signed-in caller.
      description: Returns a 6-digit numeric code with a 5-minute TTL. The code wraps a fresh standalone enrol-session token; redeem via POST /api/auth/enrol-session/redeem-short-code. Used by the F128 pairing takeover sub-affordance and the mobile-web install fallback path.
      operationId: MintPairingShortCode
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
              - type: null
              - $ref: '#/components/schemas/MintPairingShortCodeRequest'
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MintPairingShortCodeResponse'
        401:
          description: Unauthorized
  /api/tenant/api/auth/enrol-session/redeem-short-code:
    post:
      tags:
      - PairingShortCode
      summary: Redeem a 6-digit pairing short code.
      description: Anonymous — the code is the credential for this single call. Single-use, 5-attempts-per-code rate-limited. Returns the underlying enrol-session redeem result (the same access token shape as POST /api/auth/enrol-session/redeem).
      operationId: RedeemPairingShortCode
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RedeemPairingShortCodeRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RedeemEnrolSessionResponse'
        400:
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RedeemPairingShortCodeErrorBody'
        409:
          description: Conflict
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RedeemPairingShortCodeErrorBody'
        410:
          description: Gone
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RedeemPairingShortCodeErrorBody'
        429:
          description: Too Many Requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RedeemPairingShortCodeErrorBody'
  /api/tenant/api/auth/pairing-resumption-email:
    post:
      tags:
      - PairingResumption
      summary: Email the signed-in caller a magic-link to reopen /setup/add-device.
      description: Feature 128 US2 — the 'Email me a link' affordance on the desktop handoff page. Body is empty; the citizen's email is read from the auth principal (never trusting a request-body email). Rate-limited.
      operationId: SendPairingResumptionEmail
      responses:
        202:
          description: Accepted
        401:
          description: Unauthorized
  /api/tenant/api/auth/pairing-resumption/redeem:
    get:
      tags:
      - PairingResumption
      summary: Redeem an emailed pairing-resumption link.
      description: Anonymous. Validates the token, looks up the bound platform user, issues a fresh access+refresh token, and 302s to /app/#token=...&returnUrl=/setup/add-device. Single-use.
      operationId: RedeemPairingResumptionEmail
      parameters:
      - name: token
        in: query
        required: true
        schema:
          type: string
      responses:
        302:
          description: Found
  /api/tenant/api/me/inbox:
    get:
      tags:
      - Inbox
      summary: List the authenticated user's inbox entries.
      description: Paginated, sorted newest first. Excludes dismissed entries unless includeDismissed=true.
      operationId: ListMyInbox
      parameters:
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      - name: category
        in: query
        schema:
          $ref: '#/components/schemas/InboxCategory'
      - name: unreadOnly
        in: query
        schema:
          type: boolean
          default: false
      - name: includeDismissed
        in: query
        schema:
          type: boolean
          default: false
      responses:
        200:
          description: OK
  /api/tenant/api/me/inbox/unread-count:
    get:
      tags:
      - Inbox
      summary: Return the user's unread inbox count.
      description: Authoritative server-side count. Realtime updates are pushed via TenantHub InboxUnreadCountUpdated.
      operationId: GetMyInboxUnreadCount
      responses:
        200:
          description: OK
  /api/tenant/api/me/inbox/{id}:
    get:
      tags:
      - Inbox
      summary: Fetch a single inbox entry by id.
      description: Returns 404 indistinguishably if the entry does not exist or is not owned by the caller.
      operationId: GetMyInboxEntry
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
  /api/tenant/api/me/inbox/{id}/read:
    post:
      tags:
      - Inbox
      summary: Mark an entry as read. Idempotent.
      operationId: MarkMyInboxEntryRead
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
  /api/tenant/api/me/inbox/{id}/dismiss:
    post:
      tags:
      - Inbox
      summary: Dismiss an entry. Idempotent.
      operationId: DismissMyInboxEntry
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
  /api/tenant/api/me/inbox/mark-all-read:
    post:
      tags:
      - Inbox
      summary: Mark every unread entry for the authenticated user read.
      operationId: MarkAllMyInboxEntriesRead
      responses:
        200:
          description: OK
  /api/wallet/api/v1/wallets/{address}/did-document:
    get:
      tags:
      - IssuanceKeyEndpoints
      summary: Public DID document resolution by wallet address (Feature 120 verifier path)
      description: "Returns the W3C DID document for did:sorcha:org:{address} including the wallet's public key under the standard #key-1 verification method id and, if an Active issuance key exists for the controlling org, an alias #vc-issuance-{n} verification method pointing at the same key bytes."
      operationId: ResolveWalletDidDocument
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
        404:
          description: Not Found
  /api/wallet/api/stats:
    get:
      tags:
      - Statistics
      summary: Get wallet statistics (public)
      description: Returns aggregate wallet count. No authentication required.
      operationId: GetWalletStats
      responses:
        200:
          description: OK
  /api/wallet/api/v1/wallets/system:
    post:
      tags:
      - Wallets
      summary: Create or retrieve system wallet
      description: Creates or retrieves a system wallet for a validator. Used by Validator Service for signing operations.
      operationId: CreateOrRetrieveSystemWallet
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SystemWalletRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SystemWalletResponse'
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SystemWalletResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
  /api/wallet/api/v1/wallets/system/recover:
    post:
      tags:
      - Wallets
      summary: Recover a system wallet from a mnemonic
      description: Recovers (or imports) a system wallet for a validator from a provided BIP39 mnemonic. Used by 'sorcha system-register import-validator-key' to seat the genesis-ceremony validator wallet so the Validator Service can sign system register dockets. Idempotent only when the existing wallet's seed already matches the supplied mnemonic — otherwise returns 409 Conflict.
      operationId: RecoverSystemWallet
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecoverSystemWalletRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SystemWalletResponse'
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SystemWalletResponse'
        409:
          description: Conflict
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
  /api/wallet/api/v1/wallets:
    post:
      tags:
      - Wallets
      summary: Create a new wallet
      description: Creates a new HD wallet with the specified algorithm and returns the mnemonic phrase for backup. Optionally accepts a 'signingMode' parameter ('Local' or 'KmsResident') to override the server-side signing mode policy. When signingMode is 'KmsResident', the private key is created and held within cloud KMS and never extracted. The response includes 'signingMode' and 'kmsKeyId' fields indicating the wallet's key management configuration.
      operationId: CreateWallet
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateWalletRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateWalletResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
    get:
      tags:
      - Wallets
      summary: List wallets for current user
      description: Retrieve all wallets owned by the current user in the current tenant
      operationId: ListWallets
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WalletDto'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallets/recover:
    post:
      tags:
      - Wallets
      summary: Recover a wallet from mnemonic phrase
      description: Recovers an existing wallet from a BIP39 mnemonic phrase
      operationId: RecoverWallet
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecoverWalletRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletDto'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        409:
          description: Conflict
  /api/wallet/api/v1/wallets/recover/passkey:
    post:
      tags:
      - Wallets
      summary: Recover wallets using passkey authentication
      description: Recovers all wallets for the authenticated user using their FIDO2 passkey. Revokes all delegations by default; returns pending review items for selective preservation.
      operationId: RecoverWalletViaPasskey
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecoverPasskeyRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecoveryResult'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/recover/org:
    post:
      tags:
      - Wallets
      summary: Recover wallets via organization admin
      description: Org admin recovers all wallets for a member. Requires Administrator role. Delegation revocation can be skipped by the admin.
      operationId: RecoverWalletViaOrg
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecoverOrgRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecoveryResult'
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/recover/delegations/preserve:
    post:
      tags:
      - Wallets
      summary: Selectively preserve delegations after recovery
      description: After recovery, re-grants specific delegations that were revoked. Must be called by the recovered user.
      operationId: PreserveDelegations
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PreserveDelegationsRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PreserveDelegationsResult'
        400:
          description: Bad Request
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/recovery-status:
    get:
      tags:
      - Wallets
      summary: Check recovery capabilities for current user
      description: Returns which recovery paths are available for the authenticated user, and counts of wallets with/without recovery enabled.
      operationId: GetRecoveryStatus
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RecoveryStatusResponse'
  /api/wallet/api/v1/wallets/by-owner/{ownerId}:
    get:
      tags:
      - Wallets
      summary: List wallets owned by a specific user (service only)
      description: Returns all active wallets owned by the specified user id (the NameIdentifier / sub claim used as Owner on wallet creation). Intended for service-to-service lookups such as the Blueprint Service's pending-actions query, which must resolve a user's wallets without relying on the `wallet_address` JWT claim (that claim is populated at login/refresh time and can be stale or absent for users whose wallets were created after the current token was issued).
      operationId: ListWalletsByOwner
      parameters:
      - name: ownerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WalletDto'
        401:
          description: Unauthorized
        403:
          description: Forbidden
  /api/wallet/api/v1/wallets/{address}:
    get:
      tags:
      - Wallets
      summary: Get wallet by address
      description: Retrieve detailed information about a specific wallet
      operationId: GetWallet
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletDto'
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
    patch:
      tags:
      - Wallets
      summary: Update wallet metadata
      description: Update wallet name and tags
      operationId: UpdateWallet
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateWalletRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletDto'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
    delete:
      tags:
      - Wallets
      summary: Delete wallet
      description: Soft delete a wallet (can be recovered by support)
      operationId: DeleteWallet
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/sign:
    post:
      tags:
      - Wallets
      summary: Sign a transaction
      description: Sign transaction data with the wallet's private key. Returns a base64 signature plus the algorithm identifier so a verifier can pick the correct verify path.
      operationId: SignTransaction
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignTransactionRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignTransactionResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/decrypt:
    post:
      tags:
      - Wallets
      summary: Decrypt a payload
      description: Decrypt an encrypted payload using the wallet's private key
      operationId: DecryptPayload
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DecryptPayloadRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DecryptPayloadResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/encrypt:
    post:
      tags:
      - Wallets
      summary: Encrypt a payload
      description: Encrypt a payload for a recipient wallet using their public key
      operationId: EncryptPayload
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EncryptPayloadRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EncryptPayloadResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/addresses:
    post:
      tags:
      - Wallets
      summary: Register a client-derived HD address
      description: Register an HD wallet address that was derived client-side. The client must derive the address using their mnemonic and provide the public key and derivation path. This maintains security by never storing the mnemonic on the server.
      operationId: RegisterDerivedAddress
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterDerivedAddressRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
        409:
          description: Conflict
    get:
      tags:
      - Wallets
      summary: List wallet addresses
      description: List all derived addresses for a wallet with optional filtering by type (receive/change), used status, account, and labels
      operationId: ListAddresses
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      - name: type
        in: query
        schema:
          type: string
      - name: used
        in: query
        schema:
          type: boolean
      - name: account
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: uint32
      - name: label
        in: query
        schema:
          type: string
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 50
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AddressListResponse'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/addresses/{id}:
    get:
      tags:
      - Wallets
      summary: Get address by ID
      description: Retrieve detailed information about a specific derived address
      operationId: GetAddress
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
    patch:
      tags:
      - Wallets
      summary: Update address metadata
      description: Update address label, notes, tags, and metadata
      operationId: UpdateAddress
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateAddressRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/addresses/{id}/mark-used:
    post:
      tags:
      - Wallets
      summary: Mark address as used
      description: Mark an address as used (received a transaction). Updates gap limit calculations.
      operationId: MarkAddressAsUsed
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/accounts:
    get:
      tags:
      - Wallets
      summary: List BIP44 accounts
      description: List all BIP44 accounts for this wallet with address counts and gap status
      operationId: ListAccounts
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/gap-status:
    get:
      tags:
      - Wallets
      summary: Get gap limit status
      description: Check BIP44 gap limit compliance for all accounts. Shows unused address counts and warnings.
      operationId: GetGapStatus
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GapStatusResponse'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/encapsulate:
    post:
      tags:
      - Wallets
      summary: Encapsulate a shared secret using PQC key
      description: Performs ML-KEM-768 key encapsulation with the recipient's PQC public key, returning ciphertext and the encrypted payload.
      operationId: EncapsulateKey
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/EncapsulateRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallets/{address}/decapsulate:
    post:
      tags:
      - Wallets
      summary: Decapsulate a shared secret using PQC private key
      description: Performs ML-KEM-768 key decapsulation to recover the shared secret and decrypt the payload.
      operationId: DecapsulateKey
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DecapsulateRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/verify:
    post:
      tags:
      - Wallets
      summary: Verify a cryptographic signature
      description: Verify a signature against data using the provided public key and algorithm. Used by services for wallet link verification.
      operationId: VerifySignature
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifySignatureRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallets/{walletAddress}/access:
    post:
      tags:
      - Delegation
      summary: Grant access to a wallet
      description: Grant read or write access to a wallet for a specific subject (user or service)
      operationId: GrantAccess
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GrantAccessRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletAccessDto'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
        409:
          description: Conflict
    get:
      tags:
      - Delegation
      summary: List active access grants
      description: Retrieve all active access grants for a specific wallet
      operationId: GetAccess
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/WalletAccessDto'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallets/{walletAddress}/access/{subject}:
    delete:
      tags:
      - Delegation
      summary: Revoke access to a wallet
      description: Revoke a subject's access to a wallet
      operationId: RevokeAccess
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      - name: subject
        in: path
        required: true
        schema:
          type: string
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{walletAddress}/access/{subject}/check:
    get:
      tags:
      - Delegation
      summary: Check if subject has access
      description: Verify whether a subject has the required access level to a wallet
      operationId: CheckAccess
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      - name: subject
        in: path
        required: true
        schema:
          type: string
      - name: requiredRight
        in: query
        schema:
          type: string
          default: ReadOnly
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccessCheckResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallets/{walletAddress}/credentials:
    get:
      tags:
      - Credentials
      summary: List all credentials for a wallet
      description: Returns all active verifiable credentials stored in the specified wallet.
      operationId: ListCredentials
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      - name: status
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
        401:
          description: Unauthorized
    post:
      tags:
      - Credentials
      summary: Store a credential in a wallet
      description: Stores a pre-issued verifiable credential in the specified wallet.
      operationId: StoreCredential
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StoreCredentialRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallets/{walletAddress}/credentials/{credentialId}:
    get:
      tags:
      - Credentials
      summary: Get a credential by ID
      description: Returns a specific credential by its DID URI identifier.
      operationId: GetCredential
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      - name: credentialId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CredentialEntity'
        401:
          description: Unauthorized
        404:
          description: Not Found
    delete:
      tags:
      - Credentials
      summary: Delete a credential from wallet
      description: Permanently removes a credential from the wallet store.
      operationId: DeleteCredential
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      - name: credentialId
        in: path
        required: true
        schema:
          type: string
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
        404:
          description: Not Found
    patch:
      tags:
      - Credentials
      summary: Holder accept or decline a pending credential (Feature 106)
      description: "Transitions a credential's status under the Feature 106 state machine. Valid transitions: PendingAcceptance → Active (accept), PendingAcceptance → Declined (decline). Returns 409 Conflict on disallowed transitions."
      operationId: PatchCredentialStatus
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      - name: credentialId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateStatusRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CredentialEntity'
        401:
          description: Unauthorized
        404:
          description: Not Found
        409:
          description: Conflict
  /api/wallet/api/v1/wallets/{walletAddress}/credentials/match:
    post:
      tags:
      - Credentials
      summary: Match credentials against requirements
      description: Finds stored credentials that satisfy the given credential requirements.
      operationId: MatchCredentials
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/CredentialRequirement'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallets/{walletAddress}/credentials/{credentialId}/export:
    get:
      tags:
      - Credentials
      summary: Export a credential as SD-JWT VC
      description: Returns the raw SD-JWT VC token for use in presentations.
      operationId: ExportCredential
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      - name: credentialId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{walletAddress}/credentials/{credentialId}/status:
    patch:
      tags:
      - Credentials
      summary: Update a credential's status
      description: Updates the status of a credential (e.g., Active → Revoked).
      operationId: UpdateCredentialStatus
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      - name: credentialId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateStatusRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{walletAddress}/credentials/issue:
    post:
      tags:
      - Credentials
      summary: Issue a new credential using the wallet's signing key
      description: Creates and signs a new SD-JWT VC credential using the wallet's private key, stores it, and returns the issued credential.
      operationId: IssueCredential
      parameters:
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IssueCredentialRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IssuedCredentialResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/presentations/request:
    post:
      tags:
      - Presentations
      summary: Create a new presentation request
      description: A verifier creates a request for credential presentation. Returns request ID, nonce, and OID4VP URL.
      operationId: CreatePresentationRequest
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreatePresentationRequestBody'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/wallet/api/v1/presentations/{requestId}:
    get:
      tags:
      - Presentations
      summary: Get presentation request details
      description: Returns request details with matching credentials for the holder's wallet.
      operationId: GetPresentationRequest
      parameters:
      - name: requestId
        in: path
        required: true
        schema:
          type: string
      - name: walletAddress
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/presentations/{requestId}/submit:
    post:
      tags:
      - Presentations
      summary: Submit a credential presentation
      description: Holder submits a VP token with disclosed claims for verification.
      operationId: SubmitPresentation
      parameters:
      - name: requestId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubmitPresentationBody'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/presentations/{requestId}/deny:
    post:
      tags:
      - Presentations
      summary: Deny a presentation request
      description: Holder declines to present the requested credential.
      operationId: DenyPresentationRequest
      parameters:
      - name: requestId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/presentations/{requestId}/result:
    get:
      tags:
      - Presentations
      summary: Poll for verification result
      description: Verifier polls for the outcome of a presentation request.
      operationId: GetPresentationResult
      parameters:
      - name: requestId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/wallets/org/{orgId}/master-key:
    post:
      tags:
      - Org Key Management
      summary: Provision organisation master key
      description: Generates a new BIP39 mnemonic and provisions an HD master key for the organisation. The mnemonic is returned once and must be securely backed up by the administrator. Returns 409 Conflict if the organisation already has a master key.
      operationId: ProvisionOrgMasterKey
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OrgMasterKeyProvisionResult'
        409:
          description: Conflict
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
  /api/wallet/api/wallets/org/{orgId}/derive-key:
    post:
      tags:
      - Org Key Management
      summary: Derive a user key from the organisation master key
      description: 'Derives a child key for a specific user, department, and usage purpose using BIP32 hierarchical deterministic derivation. Idempotent: returns existing key if the same derivation path has already been derived.'
      operationId: DeriveOrgUserKey
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeriveKeyRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DerivedKeyResult'
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DerivedKeyResult'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
  /api/wallet/api/wallets/org/{orgId}/keys/{derivedKeyId}/rotate:
    post:
      tags:
      - Org Key Management
      summary: Rotate a derived organisation key
      description: Derives a new key at the next index in the hierarchy and marks the existing key as Rotated. The rotated key can still be used for decryption but not for signing.
      operationId: RotateOrgKey
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
      - name: derivedKeyId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DerivedKeyResult'
        400:
          description: Bad Request
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/wallet/api/wallets/org/{orgId}/keys/{derivedKeyId}:
    delete:
      tags:
      - Org Key Management
      summary: Revoke a derived organisation key
      description: Permanently revokes a derived key and locks the associated wallet. If the key was used for Identity purposes, a DID revocation event is triggered.
      operationId: RevokeOrgKey
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
      - name: derivedKeyId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
        400:
          description: Bad Request
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/wallet/api/v1/orgs/{orgId}/issuance-key/ensure:
    post:
      tags:
      - IssuanceKey
      summary: Lazily derive (idempotent) the org's VC issuance key
      description: Returns 200 with the active key's metadata after deriving it on first call or returning the existing Active row on retry. Triggers DID document regeneration on the Tenant side as a side effect. Designed for callers that mint credentials outside the direct /credentials/issue path (notably Sorcha.Haip.Service's pre-authorized_code flow).
      operationId: EnsureOrgIssuanceKey
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnsureIssuanceKeyResponse'
        500:
          description: Internal Server Error
  /api/wallet/api/v1/orgs/{orgId}/issuance-key/sign:
    post:
      tags:
      - IssuanceKey
      summary: Sign-on-behalf — produce a signature using the org's Active issuance key
      description: Signs the supplied bytes with the org's Active issuance private key and returns the signature plus the kid / issuer DID / algorithm to embed in the JWS header. Used by Sorcha.Haip.Service to delegate credential signing to wallet without transmitting private key material across services. Returns 404 when no Active issuance key exists.
      operationId: SignWithOrgIssuanceKey
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SignWithIssuanceKeyRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SignWithIssuanceKeyResponse'
        404:
          description: Not Found
        500:
          description: Internal Server Error
  /api/wallet/api/v1/orgs/{orgId}/issuance-key/rotate:
    post:
      tags:
      - IssuanceKey
      summary: Rotate the org's Active issuance key (Feature 120 US6)
      description: Marks the existing Active key as Rotated and derives a new key at the next rotation index. Triggers DID document regeneration. Body carries the governance-op id that authorised the rotation (auditing).
      operationId: RotateOrgIssuanceKey
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RotateIssuanceKeyRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EnsureIssuanceKeyResponse'
        404:
          description: Not Found
  /api/wallet/api/v1/orgs/{orgId}/issuance-key/revoke:
    post:
      tags:
      - IssuanceKey
      summary: Revoke a specific issuance key by rotation index (Feature 120 US6)
      description: Marks the named rotation as Revoked, records the reason and authorising governance op, and triggers DID document regeneration. The published DID document drops the revoked key from assertionMethod so verifiers reject credentials signed by it. Idempotent on already-revoked keys.
      operationId: RevokeOrgIssuanceKey
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RevokeIssuanceKeyRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RevokeIssuanceKeyResponse'
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/files/download:
    get:
      tags:
      - FileDownload
      summary: Download and decrypt a file attachment from a register transaction
      description: Fetches the encrypted chunks of a file attachment from the Register Service, unwraps the master file key using the wallet's private key, derives per-chunk XChaCha20-Poly1305 keys via HKDF-SHA256, decrypts every chunk, reassembles the file, and streams the result. The SHA-256 hash of the reassembled plaintext is verified before the response is committed. The requesting JWT subject must own the wallet specified in {address}.
      operationId: DownloadFile
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      - name: registerId
        in: query
        schema:
          type: string
      - name: txId
        in: query
        schema:
          type: string
      - name: fieldName
        in: query
        schema:
          type: string
      - name: fileIndex
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      responses:
        200:
          description: OK
        400:
          description: Bad Request
        403:
          description: Forbidden
        404:
          description: Not Found
        422:
          description: Unprocessable Entity
  /api/wallet/api/v1/wallets/{address}/persona/encrypt:
    post:
      tags:
      - Persona Crypto (Internal)
      summary: Encrypt a persona plaintext blob (internal, S2S only)
      description: Derives the sorcha:persona-vault key for the wallet owner, encrypts the supplied plaintext with XChaCha20-Poly1305, and returns the ciphertext, nonce, and an opaque wrappedKeyRef for the Tenant Service to store alongside the ciphertext. Requires a service-to-service JWT with the persona:crypto scope.
      operationId: EncryptPersona
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PersonaEncryptRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonaEncryptResponse'
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
  /api/wallet/api/v1/wallets/{address}/persona/decrypt:
    post:
      tags:
      - Persona Crypto (Internal)
      summary: Decrypt a stored persona blob (internal, S2S only)
      description: Derives the sorcha:persona-vault key for the wallet owner and decrypts the supplied ciphertext. Returns the plaintext bytes for the Tenant Service to wrap in its read DTO. Requires a service-to-service JWT with the persona:crypto scope.
      operationId: DecryptPersona
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PersonaDecryptRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonaDecryptResponse'
        401:
          description: Unauthorized
        403:
          description: Forbidden
        404:
          description: Not Found
        500:
          description: Internal Server Error
  /api/wallet/api/v1/wallet/status/{orgId}/citizen-devices/{listId}.statuslist+jwt:
    get:
      tags:
      - Citizen Wallet — Status Lists
      summary: Fetch a signed citizen-device status list (public)
      description: Returns the IETF Token Status List 2024 JWT for the given org + list. Public — no auth — so external verifiers can refresh their cached revocation status without Sorcha credentials. Cache-Control reflects the list's exp, so well-behaved clients honour the 24h freshness window.
      operationId: GetCitizenDeviceStatusList
      parameters:
      - name: orgId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: listId
        in: path
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type: integer
          format: int32
      responses:
        200:
          description: OK
        404:
          description: Not Found
  /api/wallet/api/v1/wallet/devices/enrol:
    post:
      tags:
      - Citizen Wallet
      summary: Enrol a citizen wallet device (PWA)
      description: Generates (if absent) the citizen's holder key under sorcha:citizen-holder, issues a device delegation credential signed by the holder key, allocates a status-list slot, persists the device on the Tenant Service, and returns everything the wallet needs to operate offline. Rate-limited (Strict).
      operationId: EnrolCitizenDevice
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeviceEnrolmentRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceEnrolmentResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        409:
          description: Conflict
  /api/wallet/api/v1/wallet/credentials:
    get:
      tags:
      - Citizen Wallet
      summary: Full credential snapshot for the authenticated citizen
      description: Returns every credential currently issued to the citizen. Used by a freshly-enrolled wallet to seed its cache; subsequent updates flow through GET /api/v1/wallet/sync.
      operationId: ListCitizenCredentials
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CredentialListResponse'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallet/holder-keys:
    get:
      tags:
      - Citizen Wallet
      summary: Get the citizen's holder + encryption public keys
      description: Feature 137 (cross-node submission). Resolves the caller's slot-108 holder public JWK (for the SD-JWT cnf binding) and wallet encryption public key (for the on-register AEAD envelope) from the citizen JWT. Used by the HolderKeyRenderer to auto-fill the cross-node submission key field. Public material only — never a private key. 404 when no wallet resolves for the caller (indistinguishable from non-existence).
      operationId: GetCitizenHolderKeys
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HolderKeysResponse'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallet/exists:
    get:
      tags:
      - Citizen Wallet
      summary: Does the signed-in citizen have a wallet?
      description: Feature 149. Reports whether a wallet resolves for the caller so the Citizen Wallet PWA's pairing takeover can route a walletless citizen to web wallet creation instead of dead-ending at the device-enrol 404. ALWAYS returns 200 with an explicit boolean for an authenticated consumer (no 401/404 ambiguity); an unauthenticated or non-consumer caller is rejected at the audience gate. Carries a boolean only — never a wallet address or other PII.
      operationId: CitizenWalletExists
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletExistsResponse'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallet/devices/renew-delegation:
    post:
      tags:
      - Citizen Wallet
      summary: Renew the device delegation credential
      description: Idempotent re-issuance of the holder→device delegation, signed by the citizen's holder key. Wallets call this when their current delegation is approaching expiry (within 30 days). Returns 404 if the device is unknown or not owned by the caller.
      operationId: RenewCitizenDeviceDelegation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DelegationRenewalRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DelegationRenewalResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallet/sync:
    get:
      tags:
      - Citizen Wallet
      summary: Pull credential and delegation deltas since the last sync
      description: Returns adds/revokes/replacements since the supplied opaque cursor. Omit the cursor on first sync. Cursors older than 30 days return 410 — the wallet should fall back to GET /credentials.
      operationId: SyncCitizenWallet
      parameters:
      - name: since
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SyncResponse'
        401:
          description: Unauthorized
        410:
          description: Gone
  /api/wallet/api/v1/wallet/devices/{deviceId}:
    delete:
      tags:
      - Citizen Wallet
      summary: Revoke a citizen wallet device (PWA-initiated)
      description: Looks up the device on the Tenant Service, flips the citizen-devices status-list bit, broadcasts the SignalR DeviceRevoked event to the user's group, and marks the Tenant row revoked via the existing service-to-service channel. Returns 404 when the device does not exist or is not owned by the caller (intentionally indistinguishable to avoid leaking device existence).
      operationId: RevokeCitizenDevice
      parameters:
      - name: deviceId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallet/devices:
    get:
      tags:
      - Citizen Wallet
      summary: List the authenticated citizen's enrolled wallet devices
      description: Mirror of GET /api/v1/me/devices for the wallet PWA. Proxies through to the Tenant Service via service-to-service auth so the PWA only ever talks to the Wallet Service for citizen-wallet operations.
      operationId: ListCitizenDevices
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeviceListResponse'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallet/devices/{deviceId}/label:
    put:
      tags:
      - Citizen Wallet
      summary: Rename a citizen wallet device
      description: Updates the citizen-visible device label (1..120 chars). 404 when the device does not exist or is not owned by the caller.
      operationId: UpdateCitizenDeviceLabel
      parameters:
      - name: deviceId
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeviceLabelUpdateRequest'
        required: true
      responses:
        204:
          description: No Content
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/wallet/api/v1/wallet/presentations/log:
    post:
      tags:
      - Citizen Wallet
      summary: Report presentations the wallet has made (US5)
      description: Accepts a batch of presentation-log entries the wallet recorded locally and reports them to the platform so the citizen's cross-device history is filled. Returns 202 Accepted immediately; dedupe (per entry id, 24h) and forwarding happen off the request path. Wallets may re-report the same entry safely — duplicates are absorbed by the entry-id dedupe.
      operationId: ReportCitizenPresentationLog
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PresentationLogReportRequest'
        required: true
      responses:
        202:
          description: Accepted
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallet/presentations:
    get:
      tags:
      - Citizen Wallet
      summary: List the citizen's presentation history (US5)
      description: Returns every presentation the authenticated citizen has reported, from any of their devices, newest-first. Backs the PWA Activity page's cross-device history. Returns an empty list (never 404) when there is no history. Carries disclosed claim names only — never values.
      operationId: ListCitizenPresentations
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PresentationHistoryResponse'
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallet/presentations/{id}:
    delete:
      tags:
      - Citizen Wallet
      summary: Delete a presentation from the citizen's history (US5)
      description: "Server-authoritative delete: removes the entry from the citizen's history across all their devices. Idempotent. A delete targeting another citizen's entry, or a non-existent entry, returns 204 — indistinguishable from success, to avoid leaking existence. Does not affect the verifier's own records (there is no register/ledger record for these presentations)."
      operationId: DeleteCitizenPresentation
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
  /api/wallet/api/v1/wallet/pending-applications:
    get:
      tags:
      - Citizen Wallet
      summary: Read the citizen's current pending-application notice
      description: Returns the active notice or null. The wallet calls this on every Home render to decide whether to show the waiting state. Notice is scoped to the calling PlatformUser via JWT.
      operationId: GetPendingApplication
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PendingApplicationEnvelope'
        401:
          description: Unauthorized
    put:
      tags:
      - Citizen Wallet
      summary: Set or replace the citizen's pending-application notice
      description: Idempotent. If a prior notice exists, the new label replaces it and the TTL resets. Notice expires after 24 hours unless explicitly cleared first.
      operationId: SetPendingApplication
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SetPendingApplicationRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PendingApplicationEnvelope'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
    delete:
      tags:
      - Citizen Wallet
      summary: Clear the citizen's pending-application notice
      description: Idempotent. Returns 204 whether or not a notice was present. The wallet's waiting state clears within one second on next Home render.
      operationId: ClearPendingApplication
      responses:
        204:
          description: No Content
        401:
          description: Unauthorized
  /api/register/health/sync:
    get:
      tags:
      - Health
      summary: Get recovery sync status for all registers
      description: Returns the current recovery/sync status for all local registers. Status is 'synced' when up-to-date, 'recovering' when catching up, or 'stalled' when recovery has stopped due to errors. Includes progress percentage, docket counts, and staleness detection (<10s threshold).
      operationId: GetRecoverySyncStatus
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
  /api/register/api/registers/{registerId}/local-relationship:
    get:
      tags:
      - Registers — Feature 108
      summary: Get this node's derived role set for a register (Feature 108)
      description: Returns the local-installation's role set on the register, derived from the latest control record and local identity. Cached; recomputed on control-transaction seal.
      operationId: GetRegisterLocalRelationship
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterLocalRelationship'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/register/api/registers/{registerId}/sync-state:
    get:
      tags:
      - Registers — Feature 108
      summary: Get typed sync state for a register with the inputs that derived it (Feature 108)
      description: 'Returns the resolved sync state for a register (synced, recovering, stalled) along with the inputs the resolver used: local docket height, recent peer-height observations within the staleness window, the latest validator sealing observation, and the persisted state. AI agents call this to decide whether a register is current enough to read from before consuming transactions or generating verification bundles.'
      operationId: GetRegisterSyncState
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterSyncStateView'
        401:
          description: Unauthorized
        404:
          description: Not Found
  /api/register/api/registers/{registerId}/transactions/{txId}/inclusion-proof:
    get:
      tags:
      - Verification
      summary: Generate Merkle inclusion proof for a transaction
      description: Generates a compact Merkle inclusion proof that a transaction is a leaf in its docket's Merkle tree. Returns the sibling hashes from leaf to root (log2(n) steps) for offline verification.
      operationId: GetMerkleInclusionProof
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: txId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MerkleInclusionProof'
        404:
          description: Not Found
        409:
          description: Conflict
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/inclusion-proofs/verify:
    post:
      tags:
      - Verification
      summary: Verify a Merkle inclusion proof (public)
      description: Verifies a standalone Merkle inclusion proof by recomputing the root from the proof path. No authentication required — suitable for offline verification workflows.
      operationId: VerifyMerkleInclusionProof
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyMerkleInclusionProofRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
  /api/register/api/registers/{registerId}/transactions/revoke:
    post:
      tags:
      - Revocation
      summary: Submit a transaction revocation
      description: Creates a revocation transaction that marks an existing transaction as revoked or superseded. The revocation is stored as a new transaction with TransactionType.Revocation and a RevocationPayload.
      operationId: RevokeTransaction
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RevokeTransactionRequest'
        required: true
      responses:
        202:
          description: Accepted
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
        404:
          description: Not Found
        409:
          description: Conflict
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/transactions/{txId}/status:
    get:
      tags:
      - Revocation
      summary: Get transaction lifecycle status
      description: Returns the lifecycle status of a transaction (active, revoked, or superseded) by checking for revocation transactions that reference it.
      operationId: GetTransactionStatus
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: txId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionStatusResponse'
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/transactions/{txId}/verification-bundle:
    get:
      tags:
      - Verification
      summary: Export an offline verification bundle for a transaction
      description: Assembles a portable verification bundle containing the transaction payload, sealed receipt with inclusion proof, and point-in-time revocation status. Returns 404 if the transaction does not exist, or 409 if not yet sealed (no receipt).
      operationId: GetVerificationBundle
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: txId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VerificationBundle'
        404:
          description: Not Found
        409:
          description: Conflict
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/verification-bundles/verify:
    post:
      tags:
      - Verification
      summary: Verify an offline verification bundle (public)
      description: 'Verifies all four components of a verification bundle: credential validity, Merkle inclusion proof, receipt signature, and revocation status. No authentication required — suitable for offline verification workflows.'
      operationId: VerifyVerificationBundle
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerificationBundle'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
  /api/register/api/registers/{registerId}/blueprints/publish:
    post:
      tags:
      - Blueprints
      summary: Publish a blueprint to a register
      description: Publishes a blueprint to a specific register after verifying governance rights.
      operationId: PublishBlueprintToRegister
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublishBlueprintToRegisterRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        403:
          description: Forbidden
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/blueprints/published:
    get:
      tags:
      - Sorcha.Register.Service
      summary: Get published blueprints for a register
      description: Returns all blueprint-publish control transactions for a register. Used by Blueprint Service during startup recovery to rebuild the published blueprint index.
      operationId: GetPublishedBlueprints
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
  /api/register/api/registers/{registerId}/devmode:
    put:
      tags:
      - Registers
      summary: Toggle DevMode on a register
      description: Enables or disables DevMode. When enabled, payloads are stored as plaintext with disclosure filtering at read time. When disabled, new payloads use envelope encryption.
      operationId: ToggleDevMode
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DevModeToggleRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/stats:
    get:
      tags:
      - Statistics
      summary: Get register statistics (public)
      description: Returns aggregate counts of registers and transactions. Optional ?registerIds=a,b,c (comma-separated, max 50) filters the counts to the listed registers. No authentication required.
      operationId: GetRegisterStats
      parameters:
      - name: registerIds
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/register/api/system-register:
    get:
      tags:
      - System Register
      summary: Get system register status and summary
      description: Returns the current status of the system register including its deterministic ID, display name, initialization status, blueprint count, and creation timestamp.
      operationId: GetSystemRegisterInfo
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/system-register/initialize:
    post:
      tags:
      - System Register
      summary: Initialize the system register
      description: Seeds the system register with default blueprints. This operation is idempotent — calling it on an already-initialized register is safe.
      operationId: InitializeSystemRegister
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
        500:
          description: Internal Server Error
  /api/register/api/system-register/publish:
    post:
      tags:
      - System Register
      summary: Publish a blueprint to the system register
      description: Publishes a new blueprint to the system register as a signed control-chain transaction. The blueprint JSON is stored on the ledger with a deterministic transaction ID, signed by the system wallet. Returns the transaction ID and blueprint metadata on success.
      operationId: PublishBlueprint
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PublishBlueprintRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublishBlueprintResponse'
        400:
          description: Bad Request
        401:
          description: Unauthorized
        500:
          description: Internal Server Error
  /api/register/api/system-register/blueprints:
    get:
      tags:
      - System Register
      summary: List system register blueprints with pagination
      description: 'Returns a paginated list of blueprints published to the system register. Results are ordered by version descending (newest first). Supports page and pageSize query parameters (default: page=1, pageSize=20, max=100).'
      operationId: GetSystemRegisterBlueprints
      parameters:
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/system-register/blueprints/{blueprintId}:
    get:
      tags:
      - System Register
      summary: Get a specific blueprint from the system register
      description: Retrieves a specific blueprint by its unique identifier from the system register. Returns 404 if the blueprint does not exist.
      operationId: GetSystemRegisterBlueprint
      parameters:
      - name: blueprintId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/system-register/blueprints/{blueprintId}/versions/{version}:
    get:
      tags:
      - System Register
      summary: Get a specific version of a blueprint from the system register
      description: Retrieves a specific version of a blueprint by its ID and version number. Returns 404 if the blueprint or version does not exist.
      operationId: GetSystemRegisterBlueprintVersion
      parameters:
      - name: blueprintId
        in: path
        required: true
        schema:
          type: string
      - name: version
        in: path
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type: integer
          format: int64
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/system-register/blueprints/{blueprintId}/versions:
    get:
      tags:
      - System Register
      summary: Query version history for a published blueprint
      description: Returns the complete version history for a blueprint including change type (structural vs documentation), structural hash, signer identity, and timestamps.
      operationId: GetBlueprintVersions
      parameters:
      - name: blueprintId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/system-register/blueprints/{blueprintId}/classify-change:
    post:
      tags:
      - System Register
      summary: Classify a proposed blueprint change as structural or documentation
      description: Compares a new blueprint against the latest published version to determine whether the change is structural (major bump) or documentation-only (minor bump). Returns the proposed next version number.
      operationId: ClassifyBlueprintChange
      parameters:
      - name: blueprintId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClassifyChangeRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/policy:
    get:
      tags:
      - Register Policy
      summary: Get the current operational policy for a register
      description: Returns the active RegisterPolicy for a register. For registers without an explicit policy (pre-feature), returns default values with isDefault=true.
      operationId: GetRegisterPolicy
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RegisterPolicyResponse'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/policy/history:
    get:
      tags:
      - Register Policy
      summary: Get the policy version history for a register
      description: Returns a paginated list of policy snapshots from the control transaction chain, ordered chronologically.
      operationId: GetRegisterPolicyHistory
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyHistoryResponse'
        400:
          description: Bad Request
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/policy/update:
    post:
      tags:
      - Register Policy
      summary: Validate and propose a register policy update
      description: Validates the proposed policy update against the current policy and returns acceptance status. The actual update must be submitted as a control.policy.update transaction through the governance process.
      operationId: ProposeRegisterPolicyUpdate
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PolicyUpdateRequest'
        required: true
      responses:
        202:
          description: Accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyUpdateResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        409:
          description: Conflict
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/validators/approved:
    get:
      tags:
      - Validator Queries
      summary: Get the approved validator list from register policy
      description: Returns the on-chain approved validator list from the register's policy. In Public registration mode the list may be empty (all validators are accepted). In Consent mode only listed validators may participate.
      operationId: GetApprovedValidators
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApprovedValidatorsResponse'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/validators/operational:
    get:
      tags:
      - Validator Queries
      summary: Get validators currently online for a register
      description: 'Returns validators currently reporting operational heartbeats via the ValidatorRegistry. NOTE: This endpoint is a placeholder — operational state is managed by the Validator Service and requires cross-service integration to resolve.'
      operationId: GetOperationalValidators
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationalValidatorsResponse'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/disable-dev-mode:
    post:
      tags:
      - Registers
      summary: Disable dev mode (one-way)
      description: Irreversibly disables dev mode via a replicated crypto-policy update, enabling mandatory field-level encryption for new transactions. Cannot be undone (validators reject re-enabling DevMode).
      operationId: DisableDevMode
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/register/api/registers:
    get:
      tags:
      - Registers
      summary: Get accessible registers
      description: Returns registers the caller's organisation is subscribed to, plus all system registers.
      operationId: GetAllRegisters
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/registers/{id}:
    get:
      tags:
      - Registers
      summary: Get register by ID
      description: Retrieves a specific register by its unique identifier. Surfaces 'advertise' (visibility) and a computed 'sandbox' flag (Feature 142) so callers can show visibility on the Go-live detail card and exclude sandbox registers from Go-live target pickers.
      operationId: GetRegister
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
    put:
      tags:
      - Registers
      summary: Update register
      description: Updates register metadata and settings.
      operationId: UpdateRegister
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateRegisterRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
    delete:
      tags:
      - Registers
      summary: Delete register
      description: Deletes a register. Authorization is based on control record attestations. System registers cannot be deleted.
      operationId: DeleteRegister
      parameters:
      - name: id
        in: path
        required: true
        schema:
          type: string
      responses:
        204:
          description: No Content
        403:
          description: Forbidden
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/stats/count:
    get:
      tags:
      - Registers
      summary: Get register count
      description: Returns the total number of registers.
      operationId: GetRegisterCount
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/registers/initiate:
    post:
      tags:
      - Register Creation
      summary: Initiate register creation (Phase 1)
      description: >2

        **Phase 1: Generate Unsigned Control Record**


        Initiates the two-phase register creation workflow by generating a unique register ID

        and unsigned control record template. The client must sign the returned `dataToSign` hash

        with each admin's wallet before calling the finalize endpoint.


        **Workflow:**

        1. Server generates unique register ID and control record template

        2. Server computes SHA-256 hash of control record for signing

        3. Client signs the hash with each admin's wallet (offline/client-side)

        4. Client calls /finalize with signed control record


        **Control Record:**

        The control record establishes administrative control with cryptographic attestations.

        At least one 'owner' attestation is required.


        **Expiration:**

        The pending registration expires after 5 minutes. The client must finalize within this timeframe.


        **Returns:**

        - `registerId`: Generated unique ID

        - `controlRecord`: Template with placeholder signatures

        - `dataToSign`: SHA-256 hash to sign with wallets

        - `expiresAt`: Expiration timestamp

        - `nonce`: Replay protection nonce
      operationId: InitiateRegisterCreation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InitiateRegisterCreationRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
  /api/register/api/registers/finalize:
    post:
      tags:
      - Register Creation
      summary: Finalize register creation (Phase 2)
      description: >2

        **Phase 2: Verify Signatures and Create Register**


        Completes the register creation workflow by verifying all attestation signatures,

        creating the register in the database, and generating the genesis transaction.


        **Workflow:**

        1. Server retrieves pending registration by ID and nonce

        2. Server validates control record against JSON Schema

        3. Server verifies each attestation signature using public keys

        4. Server creates register in database

        5. Server creates genesis transaction with control record payload

        6. Server submits genesis transaction to Validator Service

        7. Validator creates genesis docket (height 0)


        **Signature Verification:**

        - Each attestation signature is verified using the subject's public key

        - Supported algorithms: ED25519, NISTP256, RSA4096

        - Signature must match the SHA-256 hash from initiation phase


        **Genesis Transaction:**

        The genesis transaction contains the signed control record and establishes

        an immutable audit trail of register creation and ownership.


        **Returns:**

        - `registerId`: Created register ID

        - `status`: 'created'

        - `genesisTransactionId`: Genesis transaction ID

        - `genesisDocketId`: '0' (genesis docket)

        - `createdAt`: Creation timestamp


        **Errors:**

        - 400 Bad Request: Invalid control record or validation errors

        - 401 Unauthorized: Signature verification failed

        - 408 Request Timeout: Pending registration expired

        - 500 Internal Server Error: Database or service error
      operationId: FinalizeRegisterCreation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/FinalizeRegisterCreationRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/transactions:
    post:
      tags:
      - Transactions
      summary: Submit a transaction (internal/diagnostic only)
      description: Stores a transaction directly in the register. Action transactions should be submitted via the Validator Service pipeline.
      operationId: SubmitTransaction
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransactionModel'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionModel'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
    get:
      tags:
      - Transactions
      summary: Get all transactions
      description: Retrieves all transactions for a register with OData pagination ($skip, $top, $count).
      operationId: GetTransactions
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: $skip
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: $top
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: $count
        in: query
        schema:
          type: boolean
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/transactions/{txId}:
    get:
      tags:
      - Transactions
      summary: Get transaction by ID
      description: Retrieves a specific transaction by its ID.
      operationId: GetTransaction
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: txId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionModel'
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/transactions/graph:
    get:
      tags:
      - Query
      summary: Get lightweight transaction graph for DAG visualization
      description: Returns transaction IDs and PrevTxId links without payload data. Used by the Register Map UI for building the transaction lineage DAG.
      operationId: GetTransactionGraph
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: limit
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: before
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionGraphResponse'
        400:
          description: Bad Request
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/query/wallets/{address}/transactions:
    get:
      tags:
      - Query
      summary: Query transactions by wallet
      description: Retrieves all transactions for a specific wallet address.
      operationId: GetTransactionsByWallet
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      - name: registerId
        in: query
        schema:
          type: string
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
        401:
          description: Unauthorized
  /api/register/api/query/senders/{address}/transactions:
    get:
      tags:
      - Query
      summary: Query transactions by sender
      description: Retrieves all transactions sent by a specific address.
      operationId: GetTransactionsBySender
      parameters:
      - name: address
        in: path
        required: true
        schema:
          type: string
      - name: registerId
        in: query
        required: true
        schema:
          type: string
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/query/blueprints/{blueprintId}/transactions:
    get:
      tags:
      - Query
      summary: Query transactions by blueprint
      description: Retrieves all transactions for a specific blueprint.
      operationId: GetTransactionsByBlueprint
      parameters:
      - name: blueprintId
        in: path
        required: true
        schema:
          type: string
      - name: registerId
        in: query
        required: true
        schema:
          type: string
      - name: instanceId
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/query/stats:
    get:
      tags:
      - Query
      summary: Get transaction statistics
      description: Retrieves comprehensive statistics for a register.
      operationId: GetTransactionStatistics
      parameters:
      - name: registerId
        in: query
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/query/previous/{prevTxId}/transactions:
    get:
      tags:
      - Query
      summary: Query transactions by previous transaction ID
      description: Retrieves all transactions that reference a given previous transaction ID. Used for fork detection and chain integrity auditing.
      operationId: GetTransactionsByPrevTxId
      parameters:
      - name: prevTxId
        in: path
        required: true
        schema:
          type: string
      - name: registerId
        in: query
        schema:
          type: string
      - name: $skip
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: $top
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: $count
        in: query
        schema:
          type: boolean
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
        401:
          description: Unauthorized
  /api/register/api/query/instance/{instanceId}/transactions/{registerId}:
    get:
      tags:
      - Query
      summary: Query transactions by workflow instance ID
      description: Returns all transactions for a workflow instance on the given register, ordered by timestamp. Powers the Validator's chain-derived participant binding.
      operationId: GetTransactionsByInstanceId
      parameters:
      - name: instanceId
        in: path
        required: true
        schema:
          type: string
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TransactionModel'
        400:
          description: Bad Request
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/dockets:
    get:
      tags:
      - Dockets
      summary: Get all dockets
      description: Retrieves all dockets for a register.
      operationId: GetDockets
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
    post:
      tags:
      - Dockets
      summary: Write a confirmed docket
      description: Writes a consensus-confirmed docket to the register. Used by Validator Service.
      operationId: WriteDocket
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WriteDocketRequest'
        required: true
      responses:
        409:
          description: Conflict
        201:
          description: Created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Docket'
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/dockets/{docketId}:
    get:
      tags:
      - Dockets
      summary: Get docket by ID
      description: Retrieves a specific docket by its ID (docket height).
      operationId: GetDocket
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: docketId
        in: path
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: uint64
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Docket'
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/dockets/{docketId}/transactions:
    get:
      tags:
      - Dockets
      summary: Get docket transactions
      description: Retrieves all transactions sealed in a specific docket.
      operationId: GetDocketTransactions
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: docketId
        in: path
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: uint64
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/dockets/latest:
    get:
      tags:
      - Dockets
      summary: Get latest docket
      description: Retrieves the most recent docket (block) for a register.
      operationId: GetLatestDocket
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Docket'
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/governance/roster:
    get:
      tags:
      - Governance
      summary: Get current admin roster
      description: Reconstructs the current admin roster by replaying all Control transactions for the register.
      operationId: GetGovernanceRoster
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/governance/history:
    get:
      tags:
      - Governance
      summary: Get governance history
      description: Retrieves paginated Control transactions that make up the governance history for a register.
      operationId: GetGovernanceHistory
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/governance/propose:
    post:
      tags:
      - Governance
      summary: Submit a governance proposal
      description: Submits a governance operation (Add, Remove, Transfer) as a Control transaction. Owner can Add/Remove without quorum. Transfer requires quorum.
      operationId: ProposeGovernanceOperation
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GovernanceProposalRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/governance/proposals:
    get:
      tags:
      - Governance
      summary: List governance proposals
      description: Returns paginated governance operations from Control transaction history.
      operationId: GetGovernanceProposals
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 1
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/governance/crypto-policy:
    post:
      tags:
      - Governance
      summary: Update register crypto policy
      description: Submits a crypto policy update as a control transaction. The new policy takes effect immediately for subsequent transactions.
      operationId: UpdateCryptoPolicy
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CryptoPolicy'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/crypto-policy:
    get:
      tags:
      - CryptoPolicy
      summary: Get active crypto policy
      description: Returns the active cryptographic policy for this register. If no explicit policy has been set, returns the default permissive policy accepting all algorithms.
      operationId: GetActiveCryptoPolicy
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/crypto-policy/history:
    get:
      tags:
      - CryptoPolicy
      summary: Get crypto policy version history
      description: Returns all crypto policy versions for this register, ordered by version number. Includes the genesis policy and all subsequent updates.
      operationId: GetCryptoPolicyHistory
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/participants:
    get:
      tags:
      - Participants
      summary: List published participants
      description: Returns a paginated list of published participant records on this register. Defaults to active participants only. Use status=all to include deprecated/revoked.
      operationId: ListParticipants
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: skip
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 0
      - name: top
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
          default: 20
      - name: status
        in: query
        schema:
          type: string
          default: active
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/participants/by-address/{walletAddress}:
    get:
      tags:
      - Participants
      summary: Look up participant by wallet address
      description: Returns the published participant record that owns the specified wallet address on this register.
      operationId: GetParticipantByAddress
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/participants/{participantId}:
    get:
      tags:
      - Participants
      summary: Get participant by ID
      description: Returns the latest published version of a participant record by participant ID.
      operationId: GetParticipantById
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: participantId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/participants/resolve:
    get:
      tags:
      - Participants
      summary: Resolve participant by role ID and organisation
      description: Resolves a participant by their blueprint role ID and optional organisation name. Returns the published participant record with wallet addresses.
      operationId: ResolveParticipant
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: participantId
        in: query
        required: true
        schema:
          type: string
      - name: orgName
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        410:
          description: Gone
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/participants/by-address/{walletAddress}/public-key:
    get:
      tags:
      - Participants
      summary: Resolve public key by wallet address
      description: Returns the public key for field-level encryption. Returns 410 Gone if participant is revoked.
      operationId: ResolvePublicKey
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: walletAddress
        in: path
        required: true
        schema:
          type: string
      - name: algorithm
        in: query
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicKeyResolution'
        404:
          description: Not Found
        410:
          description: Gone
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/participants/resolve-public-keys:
    post:
      tags:
      - Participants
      summary: Batch resolve public keys
      description: Resolves public keys for multiple wallet addresses. Returns resolved, not-found, and revoked addresses separately. Max 200 addresses per request.
      operationId: ResolvePublicKeysBatch
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchPublicKeyRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BatchPublicKeyResponse'
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/proofs/inclusion:
    post:
      tags:
      - ZK Proofs
      summary: Generate ZK inclusion proof
      description: Generates a zero-knowledge proof that a transaction is included in a docket's Merkle tree without revealing the transaction content.
      operationId: GenerateInclusionProof
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/InclusionProofRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/proofs/verify-inclusion:
    post:
      tags:
      - ZK Proofs
      summary: Verify ZK inclusion proof
      description: Verifies a zero-knowledge proof of transaction inclusion without access to the original transaction data.
      operationId: VerifyInclusionProof
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyInclusionProofRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/receipts/batch:
    post:
      tags:
      - Receipts
      summary: Store batch of transaction receipts (internal)
      description: Stores a batch of transaction receipts generated by the Validator Service after docket sealing. Internal endpoint for service-to-service communication.
      operationId: StoreBatchReceipts
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BatchReceiptRequest'
        required: true
      responses:
        201:
          description: Created
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/HttpValidationProblemDetails'
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/transactions/{txId}/receipt:
    get:
      tags:
      - Receipts
      summary: Get transaction receipt
      description: Retrieves the cryptographic receipt for a specific transaction, including the Merkle inclusion proof and validator signatures.
      operationId: GetTransactionReceipt
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: txId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionReceipt'
        404:
          description: Not Found
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/dockets/{docketNumber}/receipts:
    get:
      tags:
      - Receipts
      summary: Get docket receipts
      description: Retrieves paginated transaction receipts for a specific docket number.
      operationId: GetDocketReceipts
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: docketNumber
        in: path
        required: true
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type: integer
          format: int64
      - name: page
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      - name: pageSize
        in: query
        schema:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/register/api/registers/{registerId}/receipts/verify:
    post:
      tags:
      - Receipts
      summary: Verify a transaction receipt (public)
      description: Verifies a transaction receipt's validator signature, Merkle inclusion proof, and root consistency. No authentication required.
      operationId: VerifyReceipt
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VerifyReceiptRequest'
        required: true
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        400:
          description: Bad Request
  /api/register/api/admin/registers/{registerId}/orphan-transactions:
    get:
      tags:
      - Admin
      summary: Detect orphan transactions
      description: Finds transactions not referenced by any sealed docket. These are remnants of legacy direct-write paths.
      operationId: DetectOrphanTransactions
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        401:
          description: Unauthorized
    delete:
      tags:
      - Admin
      summary: Delete orphan transactions
      description: Removes transactions not referenced by any sealed docket. Refuses if docketed transactions chain from orphans.
      operationId: DeleteOrphanTransactions
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        404:
          description: Not Found
        409:
          description: Conflict
        401:
          description: Unauthorized
  /api/register/api/admin/registers/{registerId}/rebuild-index:
    post:
      tags:
      - Admin
      summary: Rebuild bloom filter address index
      description: Triggers a full rebuild of the bloom filter for a register. Fetches all wallet addresses from Wallet Service and rebuilds the Redis-backed probabilistic index. Returns address count and rebuild duration.
      operationId: RebuildAddressIndex
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema: {}
        401:
          description: Unauthorized
  /api/peer/:
    get:
      tags:
      - Info
      summary: Get service information
      description: Returns basic information about the Peer Service and its available ports
      operationId: GetServiceInfo
      responses:
        200:
          description: OK
          content:
            text/plain:
              schema:
                type: string
  /api/peer/api/peers:
    get:
      tags:
      - Peers
      summary: List all known peers in the network
      description: Returns a comprehensive list of all peer nodes currently known to this node, including connection metadata, latency metrics, quality scores, ban status, and advertised registers.
      operationId: GetAllPeers
      responses:
        200:
          description: OK
  /api/peer/api/peers/quality:
    get:
      tags:
      - Monitoring
      summary: Get connection quality metrics for all tracked peers
      description: Returns quality scores, latency breakdown, and success rates for all peers with tracked connection metrics.
      operationId: GetPeerQuality
      responses:
        200:
          description: OK
  /api/peer/api/peers/{peerId}:
    get:
      tags:
      - Peers
      summary: Get detailed information about a specific peer
      description: Retrieves comprehensive details for a single peer node including connection history, latency statistics, quality metrics, ban status, and advertised registers.
      operationId: GetPeerById
      parameters:
      - name: peerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/peer/api/peers/stats:
    get:
      tags:
      - Monitoring
      summary: Get aggregated peer network statistics
      description: Returns comprehensive statistics about the peer-to-peer network including total peer count, connection quality metrics, throughput statistics, and network health indicators. Useful for monitoring and diagnostics.
      operationId: GetPeerStatistics
      responses:
        200:
          description: OK
  /api/peer/api/peers/health:
    get:
      tags:
      - Monitoring
      summary: Get peer network health status
      description: Returns health status analysis of all peer nodes in the network, categorizing peers as healthy or unhealthy based on connectivity and responsiveness metrics. Includes overall health percentage and detailed metrics for healthy peers.
      operationId: GetPeerHealth
      responses:
        200:
          description: OK
  /api/peer/api/peers/connected:
    get:
      tags:
      - Peers
      summary: Get count of connected peers
      description: Returns the count of currently connected (healthy) peers. Anonymous users receive only the count, while authenticated users also receive the full list of connected peers with their details.
      operationId: GetConnectedPeers
      responses:
        200:
          description: OK
  /api/peer/api/registers/subscriptions:
    get:
      tags:
      - Registers
      summary: List all register subscriptions
      description: Returns all per-register replication subscriptions with their sync state and progress.
      operationId: GetRegisterSubscriptions
      responses:
        200:
          description: OK
  /api/peer/api/registers/cache:
    get:
      tags:
      - Registers
      summary: Get register cache statistics
      description: Returns cache statistics for all locally cached registers.
      operationId: GetRegisterCacheStats
      responses:
        200:
          description: OK
  /api/peer/api/registers/available:
    get:
      tags:
      - Registers
      summary: List registers advertised across the peer network
      description: Returns aggregated register information from all known peer advertisements. Only public registers are included.
      operationId: GetAvailableRegisters
      responses:
        200:
          description: OK
  /api/peer/api/registers/bulk-advertise:
    post:
      tags:
      - Registers
      summary: Bulk advertise or sync register advertisements
      description: Called by Register Service on startup and during periodic resync. When FullSync is true, removes any local advertisements not included in the request.
      operationId: BulkAdvertiseRegisters
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BulkAdvertiseRequest'
        required: true
      responses:
        200:
          description: OK
  /api/peer/api/registers/{registerId}/advertise:
    post:
      tags:
      - Registers
      summary: Advertise or remove advertisement for a register
      description: Called by Register Service when a register's advertise flag changes. Sets or removes the register's public advertisement in the peer network.
      operationId: AdvertiseRegister
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AdvertiseRegisterRequest'
        required: true
      responses:
        200:
          description: OK
  /api/peer/api/registers/{registerId}/subscribe:
    post:
      tags:
      - Registers
      summary: Subscribe to a register for replication
      description: Creates a new subscription to replicate a register. Mode can be 'forward-only' (new transactions only) or 'full-replica' (complete docket chain pull).
      operationId: SubscribeToRegister
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubscribeRequest'
        required: true
      responses:
        200:
          description: OK
    delete:
      tags:
      - Registers
      summary: Unsubscribe from a register
      description: Stops replication for a register. Cached data is retained unless ?purge=true is specified.
      operationId: UnsubscribeFromRegister
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      - name: purge
        in: query
        schema:
          type: boolean
      responses:
        200:
          description: OK
  /api/peer/api/registers/{registerId}/cache:
    delete:
      tags:
      - Registers
      summary: Purge cached data for a register
      description: Deletes all locally cached transactions and dockets for a register.
      operationId: PurgeRegisterCache
      parameters:
      - name: registerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/peer/api/peers/{peerId}/ban:
    post:
      tags:
      - Management
      summary: Ban a peer from communication
      description: Bans a peer, preventing all gossip, sync, and heartbeat communication. Ban persists across restarts.
      operationId: BanPeer
      parameters:
      - name: peerId
        in: path
        required: true
        schema:
          type: string
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
              - type: null
              - $ref: '#/components/schemas/BanRequest'
      responses:
        200:
          description: OK
    delete:
      tags:
      - Management
      summary: Unban a peer, restoring communication
      description: Removes the ban on a peer. The peer's failure count is preserved (not reset).
      operationId: UnbanPeer
      parameters:
      - name: peerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/peer/api/peers/{peerId}/reset:
    post:
      tags:
      - Management
      summary: Reset a peer's failure count
      description: Resets the consecutive failure count for a peer to zero, making it eligible for normal communication.
      operationId: ResetPeerFailures
      parameters:
      - name: peerId
        in: path
        required: true
        schema:
          type: string
      responses:
        200:
          description: OK
  /api/peer/api/health:
    get:
      tags:
      - Health
      summary: Service health check with metrics
      operationId: HealthCheck
      responses:
        200:
          description: OK
components:
  schemas:
    BlueprintAPI_Action:
      required:
      - id
      - title
      type: object
      properties:
        '@type':
          type:
          - null
          - string
        id:
          maximum: 2147483647
          minimum: 0
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        previousTxId:
          maxLength: 256
          type: string
        blueprint:
          maxLength: 64
          type: string
        title:
          maxLength: 100
          minLength: 1
          type: string
        description:
          maxLength: 2048
          type: string
        sender:
          maxLength: 100
          type: string
        target:
          type:
          - null
          - string
        participants:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/Condition'
        requiredActionData:
          type: array
          items:
            type: string
        additionalRecipients:
          minItems: 0
          type: array
          items:
            type: string
        disclosures:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/Disclosure'
        previousData:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonDocument'
        dataSchemas:
          minItems: 0
          type:
          - null
          - array
        condition:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonNode'
        calculations:
          type:
          - null
          - object
        published:
          type:
          - null
          - string
          format: date-time
        additionalProperties:
          type:
          - null
          - object
        form:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/Control'
        instructions:
          maxLength: 5000
          type:
          - null
          - string
        rejectionConfig:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/RejectionConfig'
        requiredPriorActions:
          type:
          - null
          - array
          items:
            pattern: ^-?(?:0|[1-9]\d*)$
            type:
            - integer
            - string
            format: int32
        isStartingAction:
          type: boolean
        routes:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/Route'
        credentialRequirements:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/CredentialRequirement'
        credentialIssuanceConfig:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/CredentialIssuanceConfig'
        notification:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/NotificationConfig'
    BlueprintAPI_ActionRejectionRequest:
      required:
      - reason
      type: object
      properties:
        reason:
          maxLength: 1000
          type: string
        transactionHash:
          type:
          - null
          - string
        senderWallet:
          type:
          - null
          - string
        registerAddress:
          type:
          - null
          - string
        fieldErrors:
          type:
          - null
          - object
          additionalProperties:
            type: string
        branchId:
          type:
          - null
          - string
        metadata:
          type:
          - null
          - object
    BlueprintAPI_ActionSubmissionRequest:
      required:
      - blueprintId
      - actionId
      - senderWallet
      - registerAddress
      - payloadData
      type: object
      properties:
        blueprintId:
          type: string
        actionId:
          type: string
        instanceId:
          type:
          - null
          - string
        previousTransactionHash:
          type:
          - null
          - string
        senderWallet:
          type: string
        registerAddress:
          type: string
        payloadData:
          type: object
        credentialPresentations:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/CredentialPresentation'
        externalRecipientKeys:
          type:
          - null
          - object
          additionalProperties:
            $ref: '#/components/schemas/ExternalKeyInfo'
        files:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/FileAttachment'
    BlueprintAPI_AllocateIndexRequest:
      required:
      - credentialId
      type: object
      properties:
        credentialId:
          type: string
    BlueprintAPI_AssuranceLevel:
      enum:
      - low
      - substantial
      - high
      - 
    BlueprintAPI_Blueprint:
      required:
      - id
      - title
      - description
      - version
      - participants
      - actions
      type: object
      properties:
        '@context':
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonNode'
        '@type':
          type:
          - null
          - string
        id:
          maxLength: 64
          type: string
        title:
          maxLength: 200
          minLength: 3
          type: string
        description:
          maxLength: 2000
          minLength: 5
          type: string
        version:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        dataSchemas:
          type:
          - null
          - array
        participants:
          minItems: 2
          type: array
          items:
            $ref: '#/components/schemas/Participant'
        actions:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/Action'
        organizationId:
          type:
          - null
          - string
        presentationConfig:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/BlueprintPresentationConfig'
        versionMajor:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        versionMinor:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        instructions:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/BlueprintInstructions'
        instanceReference:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/InstanceReferenceTemplate'
        metadata:
          type:
          - null
          - object
          additionalProperties:
            type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    BlueprintAPI_BlueprintInstructions:
      type: object
      properties:
        overview:
          maxLength: 5000
          type:
          - null
          - string
        locale:
          maxLength: 10
          type:
          - null
          - string
        actionInstructions:
          type:
          - null
          - object
          additionalProperties:
            type: string
        participantInstructions:
          type:
          - null
          - object
          additionalProperties:
            type: string
        instructionSets:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/InstructionSet'
        governanceRoles:
          type:
          - null
          - object
          additionalProperties:
            type: string
    BlueprintAPI_BlueprintPresentationConfig:
      type: object
      properties:
        recordAbandonment:
          type: boolean
          default: false
        outcomeDetailLevel:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/OutcomeDetailLevel'
        presentationValidityWindowSeconds:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
    BlueprintAPI_BlueprintTemplate:
      required:
      - id
      - title
      - description
      - version
      - template
      type: object
      properties:
        id:
          maxLength: 64
          type: string
        title:
          maxLength: 200
          minLength: 3
          type: string
        description:
          maxLength: 2000
          minLength: 5
          type: string
        version:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        category:
          type:
          - null
          - string
        tags:
          type:
          - null
          - array
          items:
            type: string
        template:
          $ref: '#/components/schemas/JsonNode'
        parameterSchema:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonDocument'
        defaultParameters:
          type:
          - null
          - object
        examples:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/TemplateExample'
        author:
          type:
          - null
          - string
        metadata:
          type:
          - null
          - object
          additionalProperties:
            type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        published:
          type: boolean
    BlueprintAPI_CalculateRequest:
      required:
      - blueprintId
      - actionId
      - data
      type: object
      properties:
        blueprintId:
          type: string
        actionId:
          type: string
        data:
          type: object
    BlueprintAPI_ClaimConstraint:
      required:
      - claimName
      type: object
      properties:
        claimName:
          maxLength: 200
          minLength: 1
          type: string
        expectedValue: {}
    BlueprintAPI_ClaimMapping:
      required:
      - claimName
      - sourceField
      type: object
      properties:
        claimName:
          maxLength: 200
          minLength: 1
          type: string
        sourceField:
          maxLength: 500
          minLength: 1
          type: string
    BlueprintAPI_CloneFromPublishedRequestBody:
      required:
      - registerId
      - blueprintId
      type: object
      properties:
        registerId:
          type: string
        blueprintId:
          type: string
        version:
          maximum: 2147483647
          minimum: 1
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    BlueprintAPI_CloneFromPublishedResponseBody:
      required:
      - draftBlueprintId
      - sourceVersion
      - registerId
      type: object
      properties:
        draftBlueprintId:
          type: string
        sourceVersion:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        registerId:
          type: string
    BlueprintAPI_Condition:
      required:
      - criteria
      type: object
      properties:
        principal:
          maxLength: 2048
          type: string
        criteria:
          minItems: 1
          type: array
          items:
            type: string
    BlueprintAPI_Control:
      required:
      - type
      type: object
      properties:
        type:
          $ref: '#/components/schemas/ControlTypes'
        title:
          maxLength: 100
          type: string
        scope:
          maxLength: 250
          type: string
        layout:
          $ref: '#/components/schemas/LayoutTypes'
        properties:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonDocument'
        schema:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonNode'
        instructions:
          maxLength: 500
          type:
          - null
          - string
        elements:
          type: array
          items:
            $ref: '#/components/schemas/Control'
        conditions:
          type: array
        rule:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/FormRule'
        options:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonDocument'
    BlueprintAPI_ControlTypes:
      enum:
      - Layout
      - Label
      - TextLine
      - TextArea
      - Numeric
      - DateTime
      - File
      - Choice
      - Checkbox
      - Selection
      - PostcodeLookup
      - HolderKey
    BlueprintAPI_CreateInstanceRequest:
      required:
      - blueprintId
      - registerId
      type: object
      properties:
        blueprintId:
          type: string
        registerId:
          type: string
        tenantId:
          type:
          - null
          - string
        metadata:
          type:
          - null
          - object
    BlueprintAPI_CreateSchemaRequest:
      required:
      - identifier
      - title
      - description
      - version
      - content
      type: object
      properties:
        identifier:
          type: string
        title:
          type: string
        description:
          type:
          - null
          - string
        version:
          type: string
        content:
          $ref: '#/components/schemas/JsonElement'
    BlueprintAPI_CredentialDisplayConfig:
      type: object
      properties:
        backgroundColor:
          type: string
        textColor:
          type: string
        icon:
          type: string
        cardLayout:
          type: string
        highlightClaims:
          type:
          - null
          - object
          additionalProperties:
            type: string
    BlueprintAPI_CredentialFormat:
      enum:
      - sd-jwt-vc
      - mso_mdoc
    BlueprintAPI_CredentialIssuanceConfig:
      required:
      - credentialType
      - claimMappings
      - recipientParticipantId
      type: object
      properties:
        credentialType:
          maxLength: 200
          minLength: 1
          type: string
        claimMappings:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/ClaimMapping'
        recipientParticipantId:
          maxLength: 100
          minLength: 1
          type: string
        expiryDuration:
          type:
          - null
          - string
        registerId:
          maxLength: 100
          type:
          - null
          - string
        disclosable:
          type:
          - null
          - array
          items:
            type: string
        usagePolicy:
          $ref: '#/components/schemas/UsagePolicy'
        maxPresentations:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        displayConfig:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/CredentialDisplayConfig'
        targetAudience:
          $ref: '#/components/schemas/TargetAudience'
        format:
          $ref: '#/components/schemas/CredentialFormat'
        trustAnchor:
          $ref: '#/components/schemas/TrustAnchor'
        holderKeySourceField:
          type:
          - null
          - string
    BlueprintAPI_CredentialPresentation:
      required:
      - credentialId
      - disclosedClaims
      - rawPresentation
      type: object
      properties:
        credentialId:
          maxLength: 500
          minLength: 1
          type: string
        disclosedClaims:
          type: object
        rawPresentation:
          minLength: 1
          type: string
        keyBindingProof:
          type:
          - null
          - string
    BlueprintAPI_CredentialRequirement:
      required:
      - type
      type: object
      properties:
        type:
          maxLength: 200
          minLength: 1
          type: string
        format:
          $ref: '#/components/schemas/CredentialFormat'
        trustPolicy:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/TrustPolicy'
        requiredClaims:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/ClaimConstraint'
        revocationCheckPolicy:
          $ref: '#/components/schemas/RevocationCheckPolicy'
        description:
          maxLength: 500
          type:
          - null
          - string
        presentationSource:
          $ref: '#/components/schemas/PresentationSource'
    BlueprintAPI_DiscloseRequest:
      required:
      - blueprintId
      - actionId
      - data
      type: object
      properties:
        blueprintId:
          type: string
        actionId:
          type: string
        data:
          type: object
    BlueprintAPI_Disclosure:
      required:
      - participantAddress
      - dataPointers
      type: object
      properties:
        participantAddress:
          maxLength: 100
          type: string
        dataPointers:
          minItems: 1
          type: array
          items:
            type: string
    BlueprintAPI_ExternalKeyInfo:
      required:
      - publicKey
      - algorithm
      type: object
      properties:
        publicKey:
          type: string
          description: Base64-encoded public key.
        algorithm:
          type: string
          description: 'Algorithm identifier: ED25519, NISTP256, RSA4096, ML_KEM_768.'
      description: >-
        Externally-provided public key for recipients not on the register.

        Used in action submission to bypass register lookup (FR-010).
    BlueprintAPI_ExternalSchemaResult:
      required:
      - name
      - description
      - url
      - provider
      type: object
      properties:
        name:
          type: string
        description:
          type: string
        url:
          type: string
        provider:
          type: string
        fileMatch:
          type:
          - null
          - array
          items:
            type: string
        versions:
          type:
          - null
          - array
          items:
            type: string
        content: {}
        sectorTags:
          type:
          - null
          - array
          items:
            type: string
    BlueprintAPI_ExternalSchemaSearchResponse:
      required:
      - results
      - totalCount
      - provider
      - query
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/ExternalSchemaResult'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        provider:
          type: string
        query:
          type: string
        isPartialResult:
          type: boolean
          default: false
    BlueprintAPI_FileAttachment:
      required:
      - fileName
      - contentType
      - contentBase64
      type: object
      properties:
        fileName:
          type: string
        contentType:
          type: string
        contentBase64:
          type: string
    BlueprintAPI_FileChunkResponse:
      required:
      - chunkId
      - contentBase64
      - contentType
      - size
      type: object
      properties:
        chunkId:
          type: string
        contentBase64:
          type: string
        contentType:
          type: string
        size:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    BlueprintAPI_FileChunkSubmissionRequest:
      required:
      - senderWallet
      - registerAddress
      - chunkIndex
      - totalChunks
      - fileHash
      - contentType
      - contentBase64
      type: object
      properties:
        senderWallet:
          type: string
        registerAddress:
          type: string
        chunkIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        totalChunks:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        fileHash:
          type: string
        contentType:
          type: string
        contentBase64:
          type: string
        uploadSessionId:
          type:
          - null
          - string
    BlueprintAPI_FileChunkSubmissionResponse:
      required:
      - chunkTransactionId
      - chunkIndex
      - timestamp
      - uploadSessionId
      - saltBase64
      type: object
      properties:
        chunkTransactionId:
          type: string
        chunkIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        timestamp:
          type: string
          format: date-time
        uploadSessionId:
          type: string
        saltBase64:
          type: string
    BlueprintAPI_FormRule:
      type: object
      properties:
        effect:
          $ref: '#/components/schemas/RuleEffect'
        condition:
          $ref: '#/components/schemas/SchemaBasedCondition'
    BlueprintAPI_HttpValidationProblemDetails:
      type: object
      properties:
        type:
          type:
          - null
          - string
        title:
          type:
          - null
          - string
        status:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        detail:
          type:
          - null
          - string
        instance:
          type:
          - null
          - string
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
    BlueprintAPI_ImportExternalSchemaRequest:
      required:
      - schemaUrl
      type: object
      properties:
        schemaUrl:
          type: string
        identifier:
          type:
          - null
          - string
        category:
          type: string
          default: External
        overwriteExisting:
          type: boolean
          default: false
    BlueprintAPI_InstanceReferenceTemplate:
      required:
      - prefix
      - components
      type: object
      properties:
        prefix:
          pattern: ^[A-Z]{1,5}$
          type: string
        components:
          maxItems: 5
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/ReferenceComponent'
    BlueprintAPI_InstanceState:
      type: integer
    BlueprintAPI_InstructionSet:
      required:
      - locale
      - source
      type: object
      properties:
        locale:
          maxLength: 10
          type: string
        source:
          maxLength: 500
          type: string
        version:
          maxLength: 20
          type:
          - null
          - string
    BlueprintAPI_JsonDocument: {}
    BlueprintAPI_JsonElement: {}
    BlueprintAPI_JsonNode: {}
    BlueprintAPI_LayoutTypes:
      enum:
      - VerticalLayout
      - HorizontalLayout
      - Group
      - Categorization
    BlueprintAPI_LifecycleCredentialRequest:
      required:
      - issuerWallet
      type: object
      properties:
        issuerWallet:
          type: string
        reason:
          type:
          - null
          - string
    BlueprintAPI_NotificationConfig:
      type: object
      properties:
        summaryTemplate:
          type:
          - null
          - string
        urgencyRule:
          type:
          - null
          - string
        deadlineField:
          type:
          - null
          - string
        groupBy:
          type:
          - null
          - string
    BlueprintAPI_OrganisationSectorPreferencesDto:
      required:
      - organizationId
      - enabledSectors
      - allSectorsEnabled
      - lastModifiedAt
      type: object
      properties:
        organizationId:
          type:
          - null
          - string
        enabledSectors:
          type:
          - null
          - array
          items:
            type: string
        allSectorsEnabled:
          type: boolean
        lastModifiedAt:
          type:
          - null
          - string
          format: date-time
    BlueprintAPI_OutcomeDetailLevel:
      type: integer
    BlueprintAPI_Participant:
      required:
      - id
      - name
      type: object
      properties:
        '@type':
          type:
          - null
          - string
        id:
          maxLength: 64
          type: string
        name:
          maxLength: 100
          minLength: 1
          type: string
        organisation:
          maxLength: 200
          type: string
        walletAddress:
          maxLength: 100
          type:
          - null
          - string
        didUri:
          maxLength: 200
          type:
          - null
          - string
        verifiableCredential:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonNode'
        additionalProperties:
          type:
          - null
          - object
        instructions:
          maxLength: 2000
          type:
          - null
          - string
        useStealthAddress:
          type: boolean
    BlueprintAPI_PresentationSource:
      enum:
      - SorchaInternal
      - HaipExternalWallet
      - SorchaWallet
    BlueprintAPI_ReferenceComponent:
      required:
      - field
      - transform
      type: object
      properties:
        field:
          pattern: ^/[^/]+$
          type: string
        transform:
          $ref: '#/components/schemas/ReferenceTransform'
        chars:
          maximum: 10
          minimum: 2
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    BlueprintAPI_ReferenceTransform:
      enum:
      - FirstWord
      - Truncate
    BlueprintAPI_RefreshCredentialRequest:
      required:
      - issuerWallet
      type: object
      properties:
        issuerWallet:
          type: string
        newExpiryDuration:
          type:
          - null
          - string
    BlueprintAPI_Rehearsal:
      type: object
      properties:
        rehearsalId:
          type: string
          description: Unique rehearsal identifier.
          format: uuid
        blueprintId:
          type: string
          description: The blueprint being rehearsed.
        execDefHash:
          type: string
          description: Executable-definition hash of the rehearsed version (matched against RehearsalPass at publish).
        mode:
          description: Execution mode.
          $ref: '#/components/schemas/RehearsalMode'
        sandboxRegisterId:
          type:
          - null
          - string
          description: The per-org sandbox register the full rehearsal runs on; null for dry-run.
        currentActingRole:
          type: string
          description: The participant role currently acting.
        outcome:
          description: The rehearsal outcome.
          $ref: '#/components/schemas/RehearsalOutcome'
        steps:
          type: array
          items:
            $ref: '#/components/schemas/RehearsalStep'
          description: The walk-through steps in order.
        log:
          type: array
          items:
            $ref: '#/components/schemas/RehearsalEvent'
          description: The activity log, oldest first.
      description: >-
        The state of a rehearsal: status, current acting role, walk-through steps, and log

        (Feature 142). Returned by start / get / role-switch / step-submit.
    BlueprintAPI_RehearsalEvent:
      type: object
      properties:
        at:
          type: string
          description: When the event was recorded (UTC).
          format: date-time
        message:
          type: string
          description: Human-readable message.
        kind:
          description: Classification of the event.
          $ref: '#/components/schemas/RehearsalEventKind'
      description: A single entry in the rehearsal activity log (Feature 142).
    BlueprintAPI_RehearsalEventKind:
      enum:
      - Info
      - Sealed
      - Gate
      - Routed
      - Delivered
      - Error
      description: Classification of a rehearsal log entry (Feature 142).
    BlueprintAPI_RehearsalMode:
      enum:
      - DryRun
      - Full
      description: >-
        Rehearsal execution mode (Feature 142). A RehearsalMode.Full rehearsal runs the real

        execution pipeline against the org sandbox register; a RehearsalMode.DryRun is handled

        entirely client-side (in-WASM engine) and never calls the rehearsal HTTP surface.
    BlueprintAPI_RehearsalOutcome:
      enum:
      - InProgress
      - Passed
      - Abandoned
      - Failed
      description: Terminal/transient outcome of a rehearsal (Feature 142).
    BlueprintAPI_RehearsalStep:
      type: object
      properties:
        actionId:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: The blueprint action this step exercises.
          format: int32
        actingRole:
          type: string
          description: The participant role acting on this step.
        status:
          description: Walk-through status of this step.
          $ref: '#/components/schemas/RehearsalStepStatus'
      description: A single step in the rehearsal walk-through (Feature 142).
    BlueprintAPI_RehearsalStepStatus:
      enum:
      - Pending
      - Current
      - Done
      description: Walk-through status of a single rehearsal step (Feature 142).
    BlueprintAPI_RejectionConfig:
      required:
      - targetActionId
      type: object
      properties:
        targetActionId:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        targetParticipantId:
          type:
          - null
          - string
        requireReason:
          type: boolean
        rejectionSchema:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonElement'
        isTerminal:
          type: boolean
    BlueprintAPI_RevocationCheckPolicy:
      enum:
      - FailClosed
      - FailOpen
    BlueprintAPI_RevokeCredentialRequest:
      required:
      - issuerWallet
      type: object
      properties:
        issuerWallet:
          type: string
        reason:
          type:
          - null
          - string
    BlueprintAPI_RevokeCredentialResponse:
      required:
      - credentialId
      - revokedBy
      - revokedAt
      - status
      type: object
      properties:
        credentialId:
          type: string
        revokedBy:
          type: string
        revokedAt:
          type: string
          format: date-time
        reason:
          type:
          - null
          - string
        status:
          type: string
        statusListUpdated:
          type: boolean
    BlueprintAPI_Route:
      required:
      - id
      - nextActionIds
      type: object
      properties:
        id:
          maxLength: 100
          type: string
        nextActionIds:
          type: array
          items:
            pattern: ^-?(?:0|[1-9]\d*)$
            type:
            - integer
            - string
            format: int32
        condition:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonNode'
        isDefault:
          type: boolean
        description:
          maxLength: 500
          type:
          - null
          - string
        branchDeadline:
          type:
          - null
          - string
        outputMapping:
          type:
          - null
          - object
          additionalProperties:
            type: string
    BlueprintAPI_RouteRequest:
      required:
      - blueprintId
      - actionId
      - data
      type: object
      properties:
        blueprintId:
          type: string
        actionId:
          type: string
        data:
          type: object
    BlueprintAPI_RuleEffect:
      enum:
      - SHOW
      - HIDE
      - ENABLE
      - DISABLE
    BlueprintAPI_SchemaBasedCondition:
      type: object
      properties:
        scope:
          type: string
        schema:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonNode'
    BlueprintAPI_SchemaContentDto:
      required:
      - identifier
      - title
      - description
      - version
      - category
      - status
      - source
      - organizationId
      - isGloballyPublished
      - dateAdded
      - dateModified
      - dateDeprecated
      - content
      type: object
      properties:
        identifier:
          type: string
        title:
          type: string
        description:
          type:
          - null
          - string
        version:
          type: string
        category:
          type: string
        status:
          type: string
        source:
          $ref: '#/components/schemas/SchemaSourceDto'
        organizationId:
          type:
          - null
          - string
        isGloballyPublished:
          type: boolean
        dateAdded:
          type: string
          format: date-time
        dateModified:
          type: string
          format: date-time
        dateDeprecated:
          type:
          - null
          - string
          format: date-time
        content:
          $ref: '#/components/schemas/JsonElement'
    BlueprintAPI_SchemaEntryDto:
      required:
      - identifier
      - title
      - description
      - version
      - category
      - status
      - source
      - organizationId
      - isGloballyPublished
      - dateAdded
      - dateModified
      - dateDeprecated
      type: object
      properties:
        identifier:
          type: string
        title:
          type: string
        description:
          type:
          - null
          - string
        version:
          type: string
        category:
          type: string
        status:
          type: string
        source:
          $ref: '#/components/schemas/SchemaSourceDto'
        organizationId:
          type:
          - null
          - string
        isGloballyPublished:
          type: boolean
        dateAdded:
          type: string
          format: date-time
        dateModified:
          type: string
          format: date-time
        dateDeprecated:
          type:
          - null
          - string
          format: date-time
    BlueprintAPI_SchemaIndexEntryDto:
      required:
      - shortCode
      - sourceProvider
      - sourceUri
      - title
      - description
      - sectorTags
      - fieldCount
      - requiredFieldCount
      - schemaVersion
      - status
      - lastFetchedAt
      type: object
      properties:
        shortCode:
          type: string
        sourceProvider:
          type: string
        sourceUri:
          type: string
        title:
          type: string
        description:
          type:
          - null
          - string
        sectorTags:
          type: array
          items:
            type: string
        fieldCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        requiredFieldCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        schemaVersion:
          type: string
        status:
          type: string
        lastFetchedAt:
          type: string
          format: date-time
        fieldNames:
          type:
          - null
          - array
          items:
            type: string
    BlueprintAPI_SchemaIndexSearchResponse:
      required:
      - results
      - totalCount
      - nextCursor
      - loadingProviders
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/SchemaIndexEntryDto'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        nextCursor:
          type:
          - null
          - string
        loadingProviders:
          type:
          - null
          - array
          items:
            type: string
    BlueprintAPI_SchemaListResponse:
      required:
      - schemas
      - totalCount
      - nextCursor
      type: object
      properties:
        schemas:
          type: array
          items:
            $ref: '#/components/schemas/SchemaEntryDto'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        nextCursor:
          type:
          - null
          - string
    BlueprintAPI_SchemaProviderStatusDto:
      required:
      - providerName
      - isEnabled
      - providerType
      - rateLimitPerSecond
      - refreshIntervalHours
      - lastSuccessfulFetch
      - lastError
      - lastErrorAt
      - schemaCount
      - healthStatus
      - backoffUntil
      type: object
      properties:
        providerName:
          type: string
        isEnabled:
          type: boolean
        providerType:
          type:
          - null
          - string
        rateLimitPerSecond:
          pattern: ^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$
          type:
          - number
          - string
          format: double
        refreshIntervalHours:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        lastSuccessfulFetch:
          type:
          - null
          - string
          format: date-time
        lastError:
          type:
          - null
          - string
        lastErrorAt:
          type:
          - null
          - string
          format: date-time
        schemaCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        healthStatus:
          type: string
        backoffUntil:
          type:
          - null
          - string
          format: date-time
    BlueprintAPI_SchemaSectorDto:
      required:
      - id
      - displayName
      - description
      - icon
      type: object
      properties:
        id:
          type: string
        displayName:
          type: string
        description:
          type: string
        icon:
          type: string
    BlueprintAPI_SchemaSourceDto:
      required:
      - type
      - uri
      - provider
      - fetchedAt
      type: object
      properties:
        type:
          type: string
        uri:
          type:
          - null
          - string
        provider:
          type:
          - null
          - string
        fetchedAt:
          type:
          - null
          - string
          format: date-time
    BlueprintAPI_SetBitRequest:
      type: object
      properties:
        value:
          type: boolean
        reason:
          type:
          - null
          - string
    BlueprintAPI_StartFullRehearsalRequest:
      type: object
      properties:
        mode:
          type: string
    BlueprintAPI_SubmitRehearsalStepBody:
      type: object
      properties:
        actionId:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        payload:
          $ref: '#/components/schemas/JsonElement'
    BlueprintAPI_SwitchRehearsalRoleBody:
      type: object
      properties:
        role:
          type: string
    BlueprintAPI_TargetAudience:
      enum:
      - SorchaInternal
      - HaipExternalWallet
      - SorchaLocalWallet
    BlueprintAPI_TemplateEvaluationRequest:
      required:
      - templateId
      - parameters
      type: object
      properties:
        templateId:
          type: string
        parameters:
          type: object
        validate:
          type: boolean
        includeTrace:
          type: boolean
    BlueprintAPI_TemplateExample:
      type: object
      properties:
        name:
          type: string
        description:
          type:
          - null
          - string
        parameters:
          type: object
        expectedOutput:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonNode'
    BlueprintAPI_TransactionConfirmationNotification:
      required:
      - transactionHash
      - walletAddress
      - registerAddress
      type: object
      properties:
        transactionHash:
          type: string
        walletAddress:
          type: string
        registerAddress:
          type: string
        blueprintId:
          type:
          - null
          - string
        actionId:
          type:
          - null
          - string
        instanceId:
          type:
          - null
          - string
        timestamp:
          type: string
          format: date-time
    BlueprintAPI_TrustAnchor:
      enum:
      - register
      - x509-tenant
      - x509-lotl
    BlueprintAPI_TrustCombinator:
      enum:
      - anyOf
      - allOf
    BlueprintAPI_TrustPolicy:
      type: object
      properties:
        sources:
          type: array
          items:
            $ref: '#/components/schemas/TrustSourceRef'
        combinator:
          $ref: '#/components/schemas/TrustCombinator'
        minAssuranceLevel:
          $ref: '#/components/schemas/AssuranceLevel'
    BlueprintAPI_TrustSourceKind:
      enum:
      - register
      - x509-tenant
      - trustlist
      - did-allowlist
    BlueprintAPI_TrustSourceRef:
      type: object
      properties:
        kind:
          $ref: '#/components/schemas/TrustSourceKind'
        confersAssurance:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/AssuranceLevel'
        allowedIssuers:
          type:
          - null
          - array
          items:
            type: string
        trustListId:
          type:
          - null
          - string
        options:
          type:
          - null
          - object
          additionalProperties:
            type: string
    BlueprintAPI_UpdateSchemaRequest:
      required:
      - title
      - description
      - version
      - content
      type: object
      properties:
        title:
          type:
          - null
          - string
        description:
          type:
          - null
          - string
        version:
          type:
          - null
          - string
        content:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonElement'
    BlueprintAPI_UpdateSectorPreferencesRequest:
      required:
      - enabledSectors
      type: object
      properties:
        enabledSectors:
          type:
          - null
          - array
          items:
            type: string
    BlueprintAPI_UsagePolicy:
      enum:
      - Reusable
      - SingleUse
      - LimitedUse
    BlueprintAPI_ValidateRequest:
      required:
      - blueprintId
      - actionId
      - data
      type: object
      properties:
        blueprintId:
          type: string
        actionId:
          type: string
        data:
          type: object
    TenantService_AcceptInvitationRequest:
      required:
      - invitation_token
      type: object
      properties:
        invitation_token:
          type: string
    TenantService_AddUserToOrganizationRequest:
      required:
      - email
      - displayName
      - externalIdpSubject
      type: object
      properties:
        email:
          type: string
        displayName:
          type: string
        externalIdpSubject:
          type: string
        roles:
          type: array
          items:
            $ref: '#/components/schemas/UserRole'
    TenantService_AddressCandidate:
      required:
      - line1
      - town
      - postcode
      - country
      - displayLabel
      type: object
      properties:
        line1:
          type: string
        line2:
          type:
          - null
          - string
        town:
          type: string
        region:
          type:
          - null
          - string
        postcode:
          type: string
        country:
          type: string
        displayLabel:
          type: string
    TenantService_AddressLookupCapability:
      enum:
      - validate-only
      - full-address
    TenantService_AddressLookupMetadata:
      type: object
      properties:
        town:
          type:
          - null
          - string
        region:
          type:
          - null
          - string
        country:
          type:
          - null
          - string
        latitude:
          pattern: ^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$
          type:
          - null
          - number
          - string
          format: double
        longitude:
          pattern: ^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?$
          type:
          - null
          - number
          - string
          format: double
    TenantService_AddressLookupProviderInfo:
      required:
      - name
      - capability
      - supportedCountries
      - available
      type: object
      properties:
        name:
          type: string
        capability:
          $ref: '#/components/schemas/AddressLookupCapability'
        supportedCountries:
          type: array
          items:
            type: string
        available:
          type: boolean
    TenantService_AddressLookupResult:
      required:
      - postcode
      - isValid
      - provider
      - capability
      type: object
      properties:
        postcode:
          type: string
        isValid:
          type: boolean
        provider:
          type: string
        capability:
          $ref: '#/components/schemas/AddressLookupCapability'
        metadata:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/AddressLookupMetadata'
        candidates:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/AddressCandidate'
    TenantService_AdminCreateOrganizationRequest:
      required:
      - name
      - subdomain
      - adminEmail
      type: object
      properties:
        name:
          type: string
        subdomain:
          type: string
        description:
          type:
          - null
          - string
        adminEmail:
          type: string
        role:
          $ref: '#/components/schemas/UserRole'
        adminPassword:
          type:
          - null
          - string
        adminDisplayName:
          type:
          - null
          - string
        adminEmailVerified:
          type: boolean
    TenantService_AdminProvisionUserRequest:
      required:
      - email
      - displayName
      - organizationId
      - role
      type: object
      properties:
        email:
          type: string
        displayName:
          type: string
        organizationId:
          type: string
          format: uuid
        role:
          type: string
        password:
          type:
          - null
          - string
        skipEmailVerification:
          type: boolean
    TenantService_AdminResetPasswordRequest:
      required:
      - newPassword
      type: object
      properties:
        newPassword:
          type: string
    TenantService_AssertionResponse:
      required:
      - authenticatorData
      - signature
      - clientDataJSON
      type: object
      properties:
        authenticatorData:
          format: byte
        signature:
          format: byte
        clientDataJSON:
          format: byte
        userHandle:
          format: byte
    TenantService_AttestationResponse:
      required:
      - attestationObject
      - clientDataJSON
      - transports
      type: object
      properties:
        attestationObject:
          format: byte
        clientDataJSON:
          format: byte
        transports:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/AuthenticatorTransport'
    TenantService_AuditEventResponse:
      type: object
      properties:
        id:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int64
        timestamp:
          type: string
          format: date-time
        eventType:
          type: string
        identityId:
          type:
          - null
          - string
          format: uuid
        ipAddress:
          type:
          - null
          - string
        success:
          type: boolean
        details:
          type:
          - null
          - object
    TenantService_AuditLogResponse:
      type: object
      properties:
        events:
          type: array
          items:
            $ref: '#/components/schemas/AuditEventResponse'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        page:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        pageSize:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_AuditRetentionResponse:
      type: object
      properties:
        retentionMonths:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_AuthMethodsPasskey:
      required:
      - id
      - displayName
      - deviceType
      - status
      - disabledReason
      - createdAt
      - lastUsedAt
      - canRemove
      - canRename
      type: object
      properties:
        id:
          type: string
          format: uuid
        displayName:
          type: string
        deviceType:
          type:
          - null
          - string
        status:
          $ref: '#/components/schemas/CredentialStatus'
        disabledReason:
          type:
          - null
          - string
        createdAt:
          type: string
          format: date-time
        lastUsedAt:
          type:
          - null
          - string
          format: date-time
        canRemove:
          type: boolean
        canRename:
          type: boolean
    TenantService_AuthMethodsPassword:
      required:
      - isSet
      - lastChangedAt
      - canRemove
      type: object
      properties:
        isSet:
          type: boolean
        lastChangedAt:
          type:
          - null
          - string
          format: date-time
        canRemove:
          type: boolean
    TenantService_AuthMethodsResponse:
      required:
      - email
      - emailVerified
      - password
      - socials
      - passkeys
      type: object
      properties:
        email:
          type: string
        emailVerified:
          type: boolean
        password:
          $ref: '#/components/schemas/AuthMethodsPassword'
        socials:
          type: array
          items:
            $ref: '#/components/schemas/AuthMethodsSocial'
        passkeys:
          type: array
          items:
            $ref: '#/components/schemas/AuthMethodsPasskey'
    TenantService_AuthMethodsSocial:
      required:
      - linkId
      - provider
      - email
      - displayName
      - linkedAt
      - lastUsedAt
      - canRemove
      type: object
      properties:
        linkId:
          type: string
          format: uuid
        provider:
          type: string
        email:
          type:
          - null
          - string
        displayName:
          type:
          - null
          - string
        linkedAt:
          type: string
          format: date-time
        lastUsedAt:
          type:
          - null
          - string
          format: date-time
        canRemove:
          type: boolean
    TenantService_AuthenticationExtensionsClientOutputs:
      type: object
      properties:
        example.extension.bool:
          type:
          - null
          - boolean
        appid:
          type: boolean
        exts:
          type:
          - null
          - array
          items:
            type: string
        uvm:
          type:
          - null
          - array
          items:
            type: array
            items:
              pattern: ^-?(?:0|[1-9]\d*)$
              type:
              - integer
              - string
              format: uint64
        credProps:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/CredentialPropertiesOutput'
        prf:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/AuthenticationExtensionsPRFOutputs'
        largeBlob:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/AuthenticationExtensionsLargeBlobOutputs'
        credProtect:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/CredentialProtectionPolicy'
    TenantService_AuthenticationExtensionsLargeBlobOutputs:
      type: object
      properties:
        supported:
          type: boolean
        blob:
          format: byte
        written:
          type: boolean
    TenantService_AuthenticationExtensionsPRFOutputs:
      type: object
      properties:
        enabled:
          type: boolean
        results:
          $ref: '#/components/schemas/AuthenticationExtensionsPRFValues'
    TenantService_AuthenticationExtensionsPRFValues:
      required:
      - first
      type: object
      properties:
        first:
          format: byte
        second:
          format: byte
    TenantService_AuthenticatorAssertionRawResponse:
      required:
      - id
      - rawId
      - type
      - clientExtensionResults
      type: object
      properties:
        id:
          type:
          - null
          - string
        rawId:
          format: byte
        response:
          $ref: '#/components/schemas/AssertionResponse'
        type:
          $ref: '#/components/schemas/PublicKeyCredentialType'
        extensions:
          $ref: '#/components/schemas/AuthenticationExtensionsClientOutputs'
        clientExtensionResults:
          $ref: '#/components/schemas/AuthenticationExtensionsClientOutputs'
    TenantService_AuthenticatorAttestationRawResponse:
      required:
      - id
      - rawId
      - type
      - response
      - clientExtensionResults
      type: object
      properties:
        id:
          type:
          - null
          - string
        rawId:
          format: byte
        type:
          $ref: '#/components/schemas/PublicKeyCredentialType'
        response:
          $ref: '#/components/schemas/AttestationResponse'
        extensions:
          $ref: '#/components/schemas/AuthenticationExtensionsClientOutputs'
        clientExtensionResults:
          $ref: '#/components/schemas/AuthenticationExtensionsClientOutputs'
    TenantService_AuthenticatorTransport:
      enum:
      - usb
      - nfc
      - ble
      - smart-card
      - hybrid
      - internal
    TenantService_AutoLinkResult:
      type: object
      properties:
        participantCreated:
          type: boolean
        walletLinked:
          type: boolean
        participantId:
          type:
          - null
          - string
          format: uuid
        skipReason:
          type:
          - null
          - string
    TenantService_AutoLinkWalletRequest:
      type: object
      properties:
        userId:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        walletAddress:
          type: string
        publicKey:
          type:
          - null
          - string
          format: byte
        algorithm:
          type:
          - null
          - string
    TenantService_BootstrapRequest:
      type: object
      properties:
        organizationName:
          type: string
        organizationSubdomain:
          type: string
        organizationDescription:
          type:
          - null
          - string
        adminEmail:
          type: string
        adminName:
          type: string
        adminPassword:
          type: string
        createServicePrincipal:
          type: boolean
        servicePrincipalName:
          type:
          - null
          - string
    TenantService_BootstrapResponse:
      type: object
      properties:
        organizationId:
          type: string
          format: uuid
        organizationName:
          type: string
        organizationSubdomain:
          type: string
        adminUserId:
          type: string
          format: uuid
        adminEmail:
          type: string
        adminAccessToken:
          type: string
        adminRefreshToken:
          type: string
        servicePrincipalId:
          type:
          - null
          - string
          format: uuid
        servicePrincipalClientId:
          type:
          - null
          - string
        servicePrincipalClientSecret:
          type:
          - null
          - string
        systemAdminOrgId:
          type: string
          format: uuid
        publicOrgId:
          type: string
          format: uuid
        platformUserId:
          type: string
          format: uuid
        createdAt:
          type: string
          format: date-time
    TenantService_BrandingConfigurationDto:
      type: object
      properties:
        logoUrl:
          type:
          - null
          - string
        primaryColor:
          type:
          - null
          - string
        secondaryColor:
          type:
          - null
          - string
        companyTagline:
          type:
          - null
          - string
    TenantService_CertChainResponse:
      required:
      - orgCertBase64
      - rootCertBase64
      type: object
      properties:
        orgCertBase64:
          type: string
        rootCertBase64:
          type: string
    TenantService_ChallengeInitiateRequest:
      required:
      - scopedOperation
      - preferredMethod
      type: object
      properties:
        scopedOperation:
          $ref: '#/components/schemas/ScopedOperation'
        preferredMethod:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/ChallengeMethod'
    TenantService_ChallengeInitiateResponse:
      required:
      - method
      - payload
      type: object
      properties:
        method:
          $ref: '#/components/schemas/ChallengeMethod'
        payload:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonElement'
    TenantService_ChallengeMethod:
      enum:
      - totp
      - password
      - passkey
      - re-o-auth
    TenantService_ChallengeStatus:
      enum:
      - pending
      - completed
      - expired
      - failed
    TenantService_ChallengeVerifyRequest:
      required:
      - method
      - scopedOperation
      - proof
      type: object
      properties:
        method:
          $ref: '#/components/schemas/ChallengeMethod'
        scopedOperation:
          $ref: '#/components/schemas/ScopedOperation'
        proof:
          $ref: '#/components/schemas/JsonElement'
    TenantService_ChallengeVerifyResponse:
      required:
      - token
      - expiresIn
      type: object
      properties:
        token:
          type: string
        expiresIn:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_ChangeUserRoleRequest:
      required:
      - role
      type: object
      properties:
        role:
          $ref: '#/components/schemas/UserRole'
    TenantService_ChannelHints:
      type: string
    TenantService_CnameInstructionsResponse:
      required:
      - domain
      - cnameTarget
      - instructions
      type: object
      properties:
        domain:
          type: string
        cnameTarget:
          type: string
        instructions:
          type: string
    TenantService_CompleteOrgSelectionRequest:
      required:
      - platform_login_token
      - organization_id
      type: object
      properties:
        platform_login_token:
          type: string
        organization_id:
          type: string
          format: uuid
    TenantService_ConfigureCustomDomainRequest:
      required:
      - domain
      type: object
      properties:
        domain:
          pattern: ^[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9\-]{0,61}[a-zA-Z0-9])?)*\.[a-zA-Z]{2,}$
          type: string
    TenantService_CreateEventRequest:
      required:
      - organizationId
      - userId
      - eventType
      - severity
      - title
      - message
      - sourceService
      type: object
      properties:
        organizationId:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        eventType:
          type: string
        severity:
          type: string
        title:
          type: string
        message:
          type: string
        sourceService:
          type: string
        entityId:
          type:
          - null
          - string
        entityType:
          type:
          - null
          - string
    TenantService_CreateInvitationRequest:
      required:
      - email
      - role
      type: object
      properties:
        email:
          type: string
        role:
          $ref: '#/components/schemas/UserRole'
        expiryDays:
          maximum: 30
          minimum: 1
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_CreateOrganizationRequest:
      required:
      - name
      - subdomain
      type: object
      properties:
        name:
          type: string
        subdomain:
          type: string
        branding:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/BrandingConfigurationDto'
    TenantService_CreateParticipantRequest:
      required:
      - userId
      type: object
      properties:
        userId:
          type: string
          format: uuid
        displayName:
          maxLength: 256
          minLength: 1
          type:
          - null
          - string
    TenantService_CreateRegisterInvitationRequest:
      required:
      - register_id
      - target_org_did
      type: object
      properties:
        register_id:
          type: string
        target_org_did:
          type: string
        expires_in_days:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_CredentialPropertiesOutput:
      type: object
      properties:
        rk:
          type: boolean
        authenticatorDisplayName:
          type:
          - null
          - string
    TenantService_CredentialProtectionPolicy:
      enum:
      - user-verification-optional
      - user-verification-optional-with-credential-id-list
      - user-verification-required
      - 
    TenantService_CredentialStatus:
      enum:
      - active
      - disabled
      - revoked
    TenantService_CurrentUserResponse:
      type: object
      properties:
        userId:
          type:
          - null
          - string
        email:
          type:
          - null
          - string
        displayName:
          type:
          - null
          - string
        organizationId:
          type:
          - null
          - string
        organizationName:
          type:
          - null
          - string
        roles:
          type: array
          items:
            type: string
        tokenType:
          type: string
        scopes:
          type: array
          items:
            type: string
        authMethod:
          type:
          - null
          - string
    TenantService_CustomDomainResponse:
      type: object
      properties:
        domain:
          type:
          - null
          - string
        status:
          type: string
        verifiedAt:
          type:
          - null
          - string
          format: date-time
        cnameTarget:
          type:
          - null
          - string
    TenantService_DashboardResponse:
      type: object
      properties:
        activeUserCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        suspendedUserCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        usersByRole:
          type: object
          additionalProperties:
            pattern: ^-?(?:0|[1-9]\d*)$
            type:
            - integer
            - string
            format: int32
        recentLogins:
          type: array
          items:
            $ref: '#/components/schemas/RecentLoginEntry'
        pendingInvitationCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        idpStatus:
          $ref: '#/components/schemas/IdpStatusInfo'
    TenantService_DelegatedTokenRequest:
      required:
      - clientId
      - clientSecret
      - delegatedUserId
      type: object
      properties:
        clientId:
          type: string
        clientSecret:
          type: string
        delegatedUserId:
          type: string
          format: uuid
        delegatedOrganizationId:
          type:
          - null
          - string
          format: uuid
        scope:
          type:
          - null
          - string
    TenantService_DeviceListResponse:
      type: object
      properties:
        devices:
          type: array
          items:
            $ref: '#/components/schemas/DeviceSummary'
          description: All devices enrolled under the authenticated citizen account.
      description: Response body for `GET /api/v1/wallet/devices` and `GET /api/v1/me/devices`.
    TenantService_DeviceStatus:
      enum:
      - active
      - revoked
      description: Status of an enrolled wallet device.
    TenantService_DeviceSummary:
      type: object
      properties:
        deviceId:
          type: string
          description: Server-assigned device identifier.
          format: uuid
        label:
          type: string
          description: Citizen-set label.
        platform:
          type: string
          description: Free-form platform descriptor at enrolment.
        status:
          description: Active or Revoked.
          $ref: '#/components/schemas/DeviceStatus'
        enrolledAt:
          type: string
          description: UTC time of original enrolment.
          format: date-time
        revokedAt:
          type:
          - null
          - string
          description: UTC time of revocation, if revoked.
          format: date-time
        lastSeenAt:
          type:
          - null
          - string
          description: UTC time of the most recent successful sync (or null if never).
          format: date-time
        delegationExpiresAt:
          type: string
          description: UTC time at which the current delegation credential expires.
          format: date-time
      description: >-
        Citizen-visible summary of an enrolled wallet device. Returned by

        `GET /api/v1/wallet/devices` and `GET /api/v1/me/devices`.
    TenantService_DiscoverIdpRequest:
      required:
      - issuerUrl
      type: object
      properties:
        issuerUrl:
          type: string
    TenantService_DiscoveryResponse:
      type: object
      properties:
        issuer:
          type: string
        authorizationEndpoint:
          type:
          - null
          - string
        tokenEndpoint:
          type:
          - null
          - string
        userInfoEndpoint:
          type:
          - null
          - string
        jwksUri:
          type:
          - null
          - string
        supportedScopes:
          type: array
          items:
            type: string
    TenantService_DomainRestrictionsResponse:
      type: object
      properties:
        allowedDomains:
          type: array
          items:
            type: string
        restrictionsActive:
          type: boolean
    TenantService_DomainVerificationResponse:
      required:
      - message
      type: object
      properties:
        verified:
          type: boolean
        message:
          type: string
    TenantService_EmailVerificationResponse:
      type: object
      properties:
        success:
          type: boolean
        message:
          type:
          - null
          - string
    TenantService_EnrolOrgCertRequest:
      required:
      - orgPublicKeyBase64
      - orgDisplayName
      type: object
      properties:
        orgPublicKeyBase64:
          type: string
        orgDisplayName:
          type: string
    TenantService_EnrolSessionMode:
      enum:
      - gated
      - standalone
    TenantService_HasAnyDeviceResponse:
      type: object
      properties:
        hasAnyDevice:
          type: boolean
          description: >-
            `true` when the calling citizen has at least one
                    ACTIVE (non-revoked) paired device.
        latestEnrolledAt:
          type:
          - null
          - string
          description: >-
            Enrolment timestamp of the most recent active device, or `null`

            when bool HasAnyDeviceResponse.HasAnyDevice is `false`.
          format: date-time
      description: >-
        Response body for `GET /api/v1/me/devices/has-any`. Aggregate read

        used by F128 cold-start surfaces (wallet PWA pairing takeover trigger,

        Sorcha Web nag-banner trigger) — does not leak the per-device list.
    TenantService_HttpValidationProblemDetails:
      type: object
      properties:
        type:
          type:
          - null
          - string
        title:
          type:
          - null
          - string
        status:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        detail:
          type:
          - null
          - string
        instance:
          type:
          - null
          - string
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
    TenantService_IdentityStatus:
      enum:
      - active
      - suspended
      - deleted
    TenantService_IdpConfigurationRequest:
      required:
      - providerPreset
      - issuerUrl
      - clientId
      - clientSecret
      type: object
      properties:
        providerPreset:
          type: string
        issuerUrl:
          type: string
        clientId:
          type: string
        clientSecret:
          type: string
        displayName:
          type:
          - null
          - string
        scopes:
          type: array
          items:
            type: string
    TenantService_IdpConfigurationResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        providerPreset:
          type: string
        displayName:
          type:
          - null
          - string
        issuerUrl:
          type: string
        isEnabled:
          type: boolean
        scopes:
          type: array
          items:
            type: string
        authorizationEndpoint:
          type:
          - null
          - string
        tokenEndpoint:
          type:
          - null
          - string
        userInfoEndpoint:
          type:
          - null
          - string
        discoveryFetchedAt:
          type:
          - null
          - string
          format: date-time
    TenantService_IdpStatusInfo:
      type: object
      properties:
        configured:
          type: boolean
        enabled:
          type: boolean
        providerName:
          type:
          - null
          - string
        lastLoginViaIdp:
          type:
          - null
          - string
          format: date-time
    TenantService_InboxCategory:
      enum:
      - action
      - credential
      - membership
      - security
      - system
      - workflow
      - custom
    TenantService_InboxSeverity:
      enum:
      - info
      - warning
      - action-required
      - critical
    TenantService_InboxWriteRequestDto:
      required:
      - platformUserId
      - category
      - severity
      - correlationKey
      - detailHref
      - sourceEventId
      - occurredAt
      - title
      type: object
      properties:
        platformUserId:
          type: string
          format: uuid
        category:
          $ref: '#/components/schemas/InboxCategory'
        severity:
          $ref: '#/components/schemas/InboxSeverity'
        correlationKey:
          type: string
        detailHref:
          type: string
        sourceEventId:
          type: string
          format: uuid
        occurredAt:
          type: string
          format: date-time
        title:
          type: string
        summary:
          type:
          - null
          - string
        iconKey:
          type:
          - null
          - string
        channelHints:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/ChannelHints'
        writerServiceId:
          type:
          - null
          - string
          format: uuid
    TenantService_InitiateWalletLinkRequest:
      required:
      - walletAddress
      - algorithm
      type: object
      properties:
        walletAddress:
          maxLength: 256
          minLength: 1
          type: string
        algorithm:
          pattern: ^(ED25519|P-256|RSA-4096)$
          type: string
    TenantService_InvitationAcceptedResponse:
      required:
      - subscription_id
      - register_id
      - source_org_did
      - subscription_status
      - accepted_at
      type: object
      properties:
        subscription_id:
          type: string
          format: uuid
        register_id:
          type: string
        register_name:
          type:
          - null
          - string
        source_org_did:
          type: string
        source_org_name:
          type:
          - null
          - string
        subscription_status:
          type: string
        accepted_at:
          type: string
          format: date-time
    TenantService_InvitationCreatedResponse:
      required:
      - invitation_id
      - invitation_token
      - register_id
      - target_org_did
      - expires_at
      - created_at
      type: object
      properties:
        invitation_id:
          type: string
        invitation_token:
          type: string
        register_id:
          type: string
        target_org_did:
          type: string
        expires_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
    TenantService_InvitationListResponse:
      required:
      - invitations
      - total_count
      type: object
      properties:
        invitations:
          type: array
          items:
            $ref: '#/components/schemas/InvitationSummary'
        total_count:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_InvitationResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        email:
          type: string
        assignedRole:
          type: string
        status:
          type: string
        expiresAt:
          type: string
          format: date-time
        invitedBy:
          type: string
        createdAt:
          type: string
          format: date-time
    TenantService_InvitationStatus:
      enum:
      - pending
      - accepted
      - expired
      - revoked
      - 
    TenantService_InvitationSummary:
      required:
      - invitation_id
      - register_id
      - source_org_did
      - target_org_did
      - direction
      - status
      - expires_at
      - created_at
      type: object
      properties:
        invitation_id:
          type: string
        register_id:
          type: string
        register_name:
          type:
          - null
          - string
        source_org_did:
          type: string
        source_org_name:
          type:
          - null
          - string
        target_org_did:
          type: string
        target_org_name:
          type:
          - null
          - string
        direction:
          type: string
        status:
          type: string
        expires_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
    TenantService_JsonElement: {}
    TenantService_LinkedWalletAddressResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        walletAddress:
          type: string
        algorithm:
          type: string
        status:
          $ref: '#/components/schemas/WalletLinkStatus'
        linkedAt:
          type: string
          format: date-time
        revokedAt:
          type:
          - null
          - string
          format: date-time
    TenantService_LoginRequest:
      required:
      - email
      - password
      type: object
      properties:
        email:
          type: string
        password:
          type: string
        organizationSubdomain:
          type:
          - null
          - string
        tier:
          type:
          - null
          - string
        returnTo:
          type:
          - null
          - string
    TenantService_MarkReadRequest:
      required:
      - eventIds
      type: object
      properties:
        eventIds:
          type:
          - null
          - array
          items:
            type: string
            format: uuid
    TenantService_MintEnrolSessionRequest:
      type: object
      properties:
        mode:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/EnrolSessionMode'
    TenantService_MintEnrolSessionResponse:
      required:
      - sessionToken
      - qrUrl
      - expiresAt
      - mode
      type: object
      properties:
        sessionToken:
          type: string
        qrUrl:
          type: string
        expiresAt:
          type: string
          format: date-time
        mode:
          $ref: '#/components/schemas/EnrolSessionMode'
    TenantService_MintPairingShortCodeRequest:
      type: object
      properties:
        route:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PairingShortCodeRoute'
    TenantService_MintPairingShortCodeResponse:
      required:
      - code
      - expiresAt
      type: object
      properties:
        code:
          type: string
        expiresAt:
          type: string
          format: date-time
    TenantService_OidcCallbackResult:
      type: object
      properties:
        success:
          type: boolean
        accessToken:
          type:
          - null
          - string
        refreshToken:
          type:
          - null
          - string
        expiresIn:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        requiresProfileCompletion:
          type: boolean
        requires2FA:
          type: boolean
        partialToken:
          type:
          - null
          - string
        error:
          type:
          - null
          - string
        userId:
          type:
          - null
          - string
          format: uuid
        isFirstLogin:
          type: boolean
    TenantService_OidcCompleteProfileRequest:
      type: object
      properties:
        displayName:
          type:
          - null
          - string
        email:
          type:
          - null
          - string
    TenantService_OidcInitiateRequest:
      required:
      - orgSubdomain
      type: object
      properties:
        orgSubdomain:
          type: string
        redirectUrl:
          type:
          - null
          - string
    TenantService_OidcInitiateResponse:
      required:
      - authorizationUrl
      - state
      type: object
      properties:
        authorizationUrl:
          type: string
        state:
          type: string
    TenantService_OrgCertEnrolmentResponse:
      required:
      - orgWalletAddress
      - serialNumber
      - subjectDn
      - sanUri
      - certificateBase64
      type: object
      properties:
        orgWalletAddress:
          type: string
        serialNumber:
          type: string
        subjectDn:
          type: string
        sanUri:
          type: string
        notBefore:
          type: string
          format: date-time
        notAfter:
          type: string
          format: date-time
        certificateBase64:
          type: string
    TenantService_OrgDidActiveKey:
      required:
      - rotationIndex
      - algorithm
      - publicKeyJwk
      - thumbprint
      type: object
      properties:
        rotationIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Monotonic rotation counter; forms the versioned kid suffix.
          format: int32
        algorithm:
          type: string
          description: Wallet algorithm string (e.g. `ED25519`).
        publicKeyJwk:
          type: string
          description: Pre-built JWK JSON for the public key.
        thumbprint:
          type: string
          description: RFC 7638 SHA-256 base64url thumbprint of the JWK.
      description: Single Active issuance key as seen by Tenant.
    TenantService_OrgDidRegenerateRequest:
      required:
      - organizationId
      - keyEventReason
      - walletAddress
      - activeKeys
      type: object
      properties:
        organizationId:
          type: string
          description: Owning organisation.
          format: uuid
        keyEventReason:
          type: string
          description: What triggered the regeneration (matches `KeyEventReason` on the tenant side).
        walletAddress:
          type: string
          description: Org wallet address used for the canonical `did:sorcha:org:{addr}` identifier.
        activeKeys:
          type: array
          items:
            $ref: '#/components/schemas/OrgDidActiveKey'
          description: Snapshot of every Active issuance key for the org.
      description: >-
        Wallet → Tenant payload describing the active issuance keys to publish in

        the org's DID document (Feature 120 US2). Tenant writes the document

        verbatim from this snapshot — it does NOT call back to Wallet for keys.
    TenantService_OrgMembershipEntry:
      type: object
      properties:
        organizationId:
          type: string
          format: uuid
        organizationName:
          type: string
        subdomain:
          type: string
        role:
          type: string
        isCurrent:
          type: boolean
    TenantService_OrgMembershipListResponse:
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/OrgMembershipEntry'
    TenantService_OrgProvisioningResult:
      type: object
      properties:
        success:
          type: boolean
        organizationId:
          type:
          - null
          - string
          format: uuid
        organizationName:
          type:
          - null
          - string
        subdomain:
          type:
          - null
          - string
        error:
          type:
          - null
          - string
        errorCode:
          type:
          - null
          - string
    TenantService_OrgRecoveryConfigRequest:
      required:
      - recoveryPublicKey
      type: object
      properties:
        recoveryPublicKey:
          type: string
    TenantService_OrgSettingsRequest:
      type: object
      properties:
        selfRegistrationEnabled:
          type:
          - null
          - boolean
        auditRetentionMonths:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
    TenantService_OrgSettingsResponse:
      required:
      - orgType
      type: object
      properties:
        orgType:
          type: string
        selfRegistrationEnabled:
          type: boolean
        allowedEmailDomains:
          type: array
          items:
            type: string
        auditRetentionMonths:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_OrgSummaryResponse:
      type: object
      properties:
        orgId:
          type: string
          format: uuid
        activeUsers:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        pendingInvitations:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        subscribedRegisters:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        recentTransactions:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        timestamp:
          type: string
          format: date-time
    TenantService_OrganizationListResponse:
      type: object
      properties:
        organizations:
          type: array
          items:
            $ref: '#/components/schemas/OrganizationResponse'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_OrganizationResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        subdomain:
          type: string
        status:
          $ref: '#/components/schemas/OrganizationStatus'
        createdAt:
          type: string
          format: date-time
        branding:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/BrandingConfigurationDto'
    TenantService_OrganizationStatsResponse:
      type: object
      properties:
        totalOrganizations:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        totalUsers:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_OrganizationStatus:
      enum:
      - active
      - suspended
      - deleted
    TenantService_PairingShortCodeRoute:
      enum:
      - desktop-handoff
      - mobileweb-handoff
      - pwa-takeover
      - cold-landing
      - 
    TenantService_ParticipantAddressRequest:
      required:
      - walletAddress
      - publicKey
      - algorithm
      type: object
      properties:
        walletAddress:
          type: string
        publicKey:
          type: string
        algorithm:
          type: string
        primary:
          type: boolean
    TenantService_ParticipantDetailResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        displayName:
          type: string
        email:
          type: string
        status:
          $ref: '#/components/schemas/ParticipantIdentityStatus'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        deactivatedAt:
          type:
          - null
          - string
          format: date-time
        linkedWallets:
          type: array
          items:
            $ref: '#/components/schemas/LinkedWalletAddressResponse'
    TenantService_ParticipantIdentityStatus:
      enum:
      - active
      - inactive
      - suspended
    TenantService_ParticipantListResponse:
      type: object
      properties:
        participants:
          type: array
          items:
            $ref: '#/components/schemas/ParticipantResponse'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        page:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        pageSize:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        totalPages:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        hasNextPage:
          type: boolean
        hasPreviousPage:
          type: boolean
    TenantService_ParticipantPublishResult:
      required:
      - transactionId
      - participantId
      - registerId
      - version
      - status
      - message
      type: object
      properties:
        transactionId:
          type: string
        participantId:
          type: string
        registerId:
          type: string
        version:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        status:
          type: string
        message:
          type: string
    TenantService_ParticipantResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        userId:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        displayName:
          type: string
        email:
          type: string
        status:
          $ref: '#/components/schemas/ParticipantIdentityStatus'
        hasLinkedWallet:
          type: boolean
        createdAt:
          type: string
          format: date-time
    TenantService_ParticipantSearchRequest:
      type: object
      properties:
        query:
          maxLength: 256
          minLength: 0
          type:
          - null
          - string
        organizationId:
          type:
          - null
          - string
          format: uuid
        status:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/ParticipantIdentityStatus'
        hasLinkedWallet:
          type:
          - null
          - boolean
        page:
          maximum: 2147483647
          minimum: 1
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        pageSize:
          maximum: 100
          minimum: 1
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_ParticipantSearchResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/ParticipantResponse'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        page:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        pageSize:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        totalPages:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        hasNextPage:
          type: boolean
        hasPreviousPage:
          type: boolean
        query:
          type:
          - null
          - string
    TenantService_PasskeyAssertionOptionsRequest:
      required:
      - login_token
      type: object
      properties:
        login_token:
          type: string
    TenantService_PasskeyAssertionOptionsResponse:
      required:
      - transaction_id
      - options
      type: object
      properties:
        transaction_id:
          type: string
        options:
          $ref: '#/components/schemas/JsonElement'
    TenantService_PasskeyCredentialListResponse:
      required:
      - credentials
      type: object
      properties:
        credentials:
          type: array
          items:
            $ref: '#/components/schemas/PasskeyCredentialResponse'
        max_credentials:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_PasskeyCredentialResponse:
      required:
      - id
      - display_name
      - status
      - created_at
      type: object
      properties:
        id:
          type: string
          format: uuid
        display_name:
          type: string
        device_type:
          type:
          - null
          - string
        status:
          type: string
        created_at:
          type: string
          format: date-time
        last_used_at:
          type:
          - null
          - string
          format: date-time
    TenantService_PasskeyRecoveryKeyResponse:
      required:
      - credential_id
      - public_key_cose
      - algorithm
      type: object
      properties:
        credential_id:
          type: string
        public_key_cose:
          type: string
        algorithm:
          type: string
    TenantService_PasskeyRegisterOptionsRequest:
      required:
      - display_name
      type: object
      properties:
        display_name:
          type: string
    TenantService_PasskeyRegisterVerifyRequest:
      required:
      - transaction_id
      - attestation_response
      type: object
      properties:
        transaction_id:
          type: string
        attestation_response:
          $ref: '#/components/schemas/AuthenticatorAttestationRawResponse'
    TenantService_PasskeyRegistrationOptionsResponse:
      required:
      - transaction_id
      - options
      type: object
      properties:
        transaction_id:
          type: string
        options:
          $ref: '#/components/schemas/JsonElement'
    TenantService_PasskeyRenameRequest:
      required:
      - display_name
      type: object
      properties:
        display_name:
          type: string
    TenantService_PasskeyVerifyRequest:
      required:
      - login_token
      - transaction_id
      - assertion_response
      type: object
      properties:
        login_token:
          type: string
        transaction_id:
          type: string
        assertion_response:
          $ref: '#/components/schemas/AuthenticatorAssertionRawResponse'
    TenantService_PasswordRequest:
      required:
      - password
      type: object
      properties:
        password:
          type: string
    TenantService_PendingInvitationResponse:
      type: object
      properties:
        email:
          type: string
        assignedRole:
          $ref: '#/components/schemas/UserRole'
        invitationStatus:
          type: string
        invitedByUserId:
          type: string
          format: uuid
        expiresAt:
          type: string
          format: date-time
        createdAt:
          type: string
          format: date-time
    TenantService_PersonaAddress:
      required:
      - line1
      - line2
      - city
      - region
      - postalCode
      - country
      - isDefault
      type: object
      properties:
        line1:
          type: string
        line2:
          type:
          - null
          - string
        city:
          type: string
        region:
          type:
          - null
          - string
        postalCode:
          type: string
        country:
          type: string
        isDefault:
          type: boolean
        label:
          type:
          - null
          - string
    TenantService_PersonaAttributeOfDateOnly:
      required:
      - value
      - source
      - verifiedBy
      - lastUpdated
      type: object
      properties:
        value:
          type: string
          format: date
        source:
          $ref: '#/components/schemas/PersonaAttributeSource'
        verifiedBy:
          type:
          - null
          - string
        lastUpdated:
          type: string
          format: date-time
    TenantService_PersonaAttributeOfPersonaAddress:
      required:
      - value
      - source
      - verifiedBy
      - lastUpdated
      type: object
      properties:
        value:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaAddress'
        source:
          $ref: '#/components/schemas/PersonaAttributeSource'
        verifiedBy:
          type:
          - null
          - string
        lastUpdated:
          type: string
          format: date-time
    TenantService_PersonaAttributeOfPersonaEmail:
      required:
      - value
      - source
      - verifiedBy
      - lastUpdated
      type: object
      properties:
        value:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaEmail'
        source:
          $ref: '#/components/schemas/PersonaAttributeSource'
        verifiedBy:
          type:
          - null
          - string
        lastUpdated:
          type: string
          format: date-time
    TenantService_PersonaAttributeOfPersonaPhone:
      required:
      - value
      - source
      - verifiedBy
      - lastUpdated
      type: object
      properties:
        value:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaPhone'
        source:
          $ref: '#/components/schemas/PersonaAttributeSource'
        verifiedBy:
          type:
          - null
          - string
        lastUpdated:
          type: string
          format: date-time
    TenantService_PersonaAttributeOfstring:
      required:
      - value
      - source
      - verifiedBy
      - lastUpdated
      type: object
      properties:
        value:
          type:
          - null
          - string
        source:
          $ref: '#/components/schemas/PersonaAttributeSource'
        verifiedBy:
          type:
          - null
          - string
        lastUpdated:
          type: string
          format: date-time
    TenantService_PersonaAttributeSource:
      enum:
      - self-asserted
      - verified-credential
    TenantService_PersonaAttributesV1:
      type: object
      properties:
        givenName:
          type:
          - null
          - string
        middleName:
          type:
          - null
          - string
        familyName:
          type:
          - null
          - string
        fullName:
          type:
          - null
          - string
        dateOfBirth:
          type:
          - null
          - string
          format: date
        emails:
          type: array
          items:
            $ref: '#/components/schemas/PersonaEmail'
        phones:
          type: array
          items:
            $ref: '#/components/schemas/PersonaPhone'
        addresses:
          type: array
          items:
            $ref: '#/components/schemas/PersonaAddress'
        nationalities:
          type: array
          items:
            type: string
    TenantService_PersonaEmail:
      required:
      - value
      - isDefault
      type: object
      properties:
        value:
          type: string
        isDefault:
          type: boolean
        label:
          type:
          - null
          - string
    TenantService_PersonaPhone:
      required:
      - value
      - isDefault
      type: object
      properties:
        value:
          type: string
        isDefault:
          type: boolean
        label:
          type:
          - null
          - string
        kind:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaPhoneKind'
    TenantService_PersonaPhoneKind:
      enum:
      - mobile
      - home
      - work
      - 
    TenantService_PersonaReadModelV1:
      type: object
      properties:
        givenName:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaAttributeOfstring'
        middleName:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaAttributeOfstring'
        familyName:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaAttributeOfstring'
        fullName:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaAttributeOfstring'
        dateOfBirth:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaAttributeOfDateOnly'
        defaultEmail:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaAttributeOfPersonaEmail'
        allEmails:
          type: array
          items:
            $ref: '#/components/schemas/PersonaEmail'
        defaultPhone:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaAttributeOfPersonaPhone'
        allPhones:
          type: array
          items:
            $ref: '#/components/schemas/PersonaPhone'
        defaultAddress:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaAttributeOfPersonaAddress'
        allAddresses:
          type: array
          items:
            $ref: '#/components/schemas/PersonaAddress'
        defaultNationality:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PersonaAttributeOfstring'
        allNationalities:
          type: array
          items:
            type: string
    TenantService_PlatformSettingsResponse:
      type: object
      properties:
        publicOrgEnabled:
          type: boolean
        maxOrgsPerUser:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        publicOrgId:
          type: string
          format: uuid
        publicOrgStatus:
          type: string
        updatedAt:
          type: string
          format: date-time
    TenantService_PostcodeLookupRequest:
      required:
      - postcode
      type: object
      properties:
        postcode:
          maxLength: 12
          minLength: 3
          type: string
        countryHint:
          maxLength: 2
          minLength: 2
          pattern: ^[A-Za-z]{2}$
          type:
          - null
          - string
    TenantService_ProblemDetails:
      type: object
      properties:
        type:
          type:
          - null
          - string
        title:
          type:
          - null
          - string
        status:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        detail:
          type:
          - null
          - string
        instance:
          type:
          - null
          - string
    TenantService_ProvisionOrgRequest:
      required:
      - name
      - subdomain
      type: object
      properties:
        name:
          type: string
        subdomain:
          type: string
        description:
          type:
          - null
          - string
    TenantService_ProvisionOrgUserRequest:
      required:
      - email
      - displayName
      - password
      type: object
      properties:
        email:
          type: string
        displayName:
          type: string
        password:
          type: string
        roles:
          type: array
          items:
            $ref: '#/components/schemas/UserRole'
        emailVerified:
          type: boolean
    TenantService_PublicKeyCredentialType:
      enum:
      - public-key
      - invalid
    TenantService_PublicPasskeyAssertionOptionsRequest:
      type: object
      properties:
        email:
          type:
          - null
          - string
    TenantService_PublicPasskeyAssertionVerifyRequest:
      required:
      - transaction_id
      - assertion_response
      type: object
      properties:
        transaction_id:
          type: string
        assertion_response:
          $ref: '#/components/schemas/AuthenticatorAssertionRawResponse'
        tier:
          type:
          - null
          - string
    TenantService_PublicPasskeyRegisterOptionsRequest:
      required:
      - display_name
      type: object
      properties:
        display_name:
          type: string
        email:
          type:
          - null
          - string
    TenantService_PublicPasskeyRegisterVerifyRequest:
      required:
      - transaction_id
      - attestation_response
      type: object
      properties:
        transaction_id:
          type: string
        attestation_response:
          $ref: '#/components/schemas/AuthenticatorAttestationRawResponse'
    TenantService_PublicTokenResponse:
      required:
      - access_token
      - refresh_token
      type: object
      properties:
        access_token:
          type: string
        refresh_token:
          type: string
        token_type:
          type: string
        expires_in:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        scope:
          type:
          - null
          - string
        is_new_user:
          type: boolean
    TenantService_PublishParticipantRequest:
      required:
      - registerId
      - participantName
      - organizationName
      - addresses
      - signerWalletAddress
      type: object
      properties:
        registerId:
          type: string
        participantName:
          type: string
        organizationName:
          type: string
        addresses:
          type: array
          items:
            $ref: '#/components/schemas/ParticipantAddressRequest'
        signerWalletAddress:
          type: string
        metadata:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonElement'
    TenantService_PushSubscriptionKeys:
      type: object
      properties:
        p256dh:
          type: string
        auth:
          type: string
    TenantService_PushSubscriptionRequest:
      type: object
      properties:
        endpoint:
          type: string
        keys:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PushSubscriptionKeys'
    TenantService_RecentLoginEntry:
      type: object
      properties:
        userId:
          type: string
          format: uuid
        displayName:
          type: string
        timestamp:
          type: string
          format: date-time
        method:
          type: string
    TenantService_RedeemEnrolSessionErrorBody:
      required:
      - code
      - message
      type: object
      properties:
        code:
          $ref: '#/components/schemas/RedeemEnrolSessionErrorCode'
        message:
          type: string
    TenantService_RedeemEnrolSessionErrorCode:
      enum:
      - malformed-token
      - invalid-signature
      - scope-mismatch
      - already-used
      - expired
    TenantService_RedeemEnrolSessionRequest:
      required:
      - sessionToken
      type: object
      properties:
        sessionToken:
          type: string
    TenantService_RedeemEnrolSessionResponse:
      required:
      - accessToken
      - expiresIn
      - displayName
      - email
      - mode
      type: object
      properties:
        accessToken:
          type: string
        expiresIn:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        displayName:
          type: string
        email:
          type: string
        mode:
          $ref: '#/components/schemas/EnrolSessionMode'
    TenantService_RedeemPairingShortCodeErrorBody:
      required:
      - code
      - message
      type: object
      properties:
        code:
          $ref: '#/components/schemas/RedeemPairingShortCodeErrorCode'
        message:
          type: string
    TenantService_RedeemPairingShortCodeErrorCode:
      enum:
      - malformed-code
      - expired-code
      - already-used-code
      - rate-limited
    TenantService_RedeemPairingShortCodeRequest:
      required:
      - code
      type: object
      properties:
        code:
          type: string
    TenantService_RegisterServicePrincipalRequest:
      required:
      - serviceName
      type: object
      properties:
        serviceName:
          type: string
        scopes:
          type: array
          items:
            type: string
    TenantService_RegisterSubscriptionListResponse:
      required:
      - items
      - total_count
      - page
      - page_size
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/RegisterSubscriptionResponse'
        total_count:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        page:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        page_size:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_RegisterSubscriptionResponse:
      required:
      - id
      - organization_id
      - register_id
      - subscription_type
      - status
      - subscribed_at
      - subscribed_by_user_id
      type: object
      properties:
        id:
          type: string
          format: uuid
        organization_id:
          type: string
          format: uuid
        register_id:
          type: string
        register_name:
          type:
          - null
          - string
        subscription_type:
          type: string
        status:
          type: string
        invitation_id:
          type:
          - null
          - string
        subscribed_at:
          type: string
          format: date-time
        subscribed_by_user_id:
          type: string
          format: uuid
        revoked_at:
          type:
          - null
          - string
          format: date-time
        revoked_by_user_id:
          type:
          - null
          - string
          format: uuid
    TenantService_ResendVerificationRequest:
      required:
      - email
      type: object
      properties:
        email:
          type: string
    TenantService_RevokeOrgCertRequest:
      type: object
      properties:
        reason:
          type:
          - null
          - string
    TenantService_RevokeOrganizationTokensRequest:
      required:
      - organizationId
      type: object
      properties:
        organizationId:
          type: string
          format: uuid
    TenantService_RevokeUserTokensRequest:
      required:
      - userId
      type: object
      properties:
        userId:
          type: string
          format: uuid
    TenantService_RotateSecretRequest:
      required:
      - currentSecret
      type: object
      properties:
        currentSecret:
          type: string
    TenantService_RotateSecretResponse:
      type: object
      properties:
        newClientSecret:
          type: string
        warning:
          type: string
    TenantService_ScopedOperation:
      enum:
      - remove-auth-method
      - change-password
      - set-password
      - remove-password
      - disable2-fa
    TenantService_SelfRegistrationRequest:
      required:
      - orgSubdomain
      - email
      - password
      - displayName
      type: object
      properties:
        orgSubdomain:
          type: string
        email:
          type: string
        password:
          type: string
        displayName:
          type: string
    TenantService_SelfRegistrationResponse:
      type: object
      properties:
        success:
          type: boolean
        userId:
          type:
          - null
          - string
          format: uuid
        message:
          type:
          - null
          - string
    TenantService_ServicePrincipalListResponse:
      type: object
      properties:
        servicePrincipals:
          type: array
          items:
            $ref: '#/components/schemas/ServicePrincipalResponse'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_ServicePrincipalRegistrationResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        serviceName:
          type: string
        clientId:
          type: string
        clientSecret:
          type: string
        scopes:
          type: array
          items:
            type: string
        warning:
          type: string
    TenantService_ServicePrincipalResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        serviceName:
          type: string
        clientId:
          type: string
        scopes:
          type: array
          items:
            type: string
        status:
          type: string
        createdAt:
          type: string
          format: date-time
    TenantService_SetDefaultWalletRequest:
      type: object
      properties:
        walletAddress:
          type: string
          default: ''
    TenantService_SocialLoginCallbackRequest:
      type: object
      properties:
        code:
          type: string
        state:
          type: string
        provider:
          type: string
    TenantService_SocialLoginInitiateRequest:
      type: object
      properties:
        provider:
          type: string
        returnUrl:
          type:
          - null
          - string
        intent:
          type:
          - null
          - string
        surface:
          type:
          - null
          - string
    TenantService_SocialLoginInitiateResponse:
      type: object
      properties:
        authorizationUrl:
          type: string
        state:
          type: string
    TenantService_SocialProvidersResponse:
      required:
      - providers
      type: object
      properties:
        providers:
          type: array
          items:
            type: string
    TenantService_SubdomainValidationResponse:
      type: object
      properties:
        subdomain:
          type: string
        isValid:
          type: boolean
        errorMessage:
          type:
          - null
          - string
    TenantService_SubscribeRequest:
      required:
      - register_id
      type: object
      properties:
        register_id:
          type: string
        register_name:
          type:
          - null
          - string
        description:
          type:
          - null
          - string
        subscription_type:
          type:
          - null
          - string
    TenantService_SuccessResponse:
      type: object
      properties:
        success:
          type: boolean
        message:
          type:
          - null
          - string
    TenantService_SwitchOrgRequest:
      required:
      - organizationId
      type: object
      properties:
        organizationId:
          type: string
          format: uuid
    TenantService_TestConnectionResponse:
      type: object
      properties:
        success:
          type: boolean
        message:
          type:
          - null
          - string
        discoveredScopes:
          type: array
          items:
            type: string
    TenantService_ToggleIdpRequest:
      required:
      - enabled
      type: object
      properties:
        enabled:
          type: boolean
    TenantService_TokenIntrospectionRequest:
      required:
      - token
      type: object
      properties:
        token:
          type: string
        tokenTypeHint:
          type:
          - null
          - string
    TenantService_TokenIntrospectionResponse:
      type: object
      properties:
        active:
          type: boolean
        scope:
          type:
          - null
          - string
        clientId:
          type:
          - null
          - string
        sub:
          type:
          - null
          - string
        exp:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int64
        iat:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int64
        iss:
          type:
          - null
          - string
        aud:
          type:
          - null
          - string
        tokenType:
          type:
          - null
          - string
        jti:
          type:
          - null
          - string
        orgId:
          type:
          - null
          - string
        roles:
          type:
          - null
          - array
          items:
            type: string
    TenantService_TokenRefreshRequest:
      required:
      - refreshToken
      type: object
      properties:
        refreshToken:
          type: string
    TenantService_TokenResponse:
      required:
      - access_token
      - refresh_token
      type: object
      properties:
        access_token:
          type: string
        refresh_token:
          type: string
        token_type:
          type: string
        expires_in:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        scope:
          type:
          - null
          - string
    TenantService_TokenRevocationRequest:
      required:
      - token
      type: object
      properties:
        token:
          type: string
        tokenTypeHint:
          type: string
    TenantService_TotpBackupValidateRequest:
      required:
      - loginToken
      - backupCode
      type: object
      properties:
        loginToken:
          type: string
        backupCode:
          type: string
    TenantService_TotpCodeRequest:
      required:
      - code
      type: object
      properties:
        code:
          type: string
    TenantService_TotpSetupResponse:
      required:
      - secret
      - qrUri
      - backupCodes
      type: object
      properties:
        secret:
          type: string
        qrUri:
          type: string
        backupCodes:
          type: array
          items:
            type: string
    TenantService_TotpStatusResponse:
      type: object
      properties:
        isEnabled:
          type: boolean
        verifiedAt:
          type:
          - null
          - string
          format: date-time
        message:
          type:
          - null
          - string
    TenantService_TotpValidateRequest:
      required:
      - loginToken
      - code
      type: object
      properties:
        loginToken:
          type: string
        code:
          type: string
    TenantService_TotpValidateResponse:
      type: object
      properties:
        success:
          type: boolean
        message:
          type:
          - null
          - string
        accessToken:
          type:
          - null
          - string
        refreshToken:
          type:
          - null
          - string
        expiresIn:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
    TenantService_TotpVerifyResponse:
      type: object
      properties:
        success:
          type: boolean
        message:
          type:
          - null
          - string
    TenantService_TrustAnchorResponse:
      required:
      - tenantId
      - serialNumber
      - subjectDn
      - algorithm
      - certificateBase64
      type: object
      properties:
        tenantId:
          type: string
        serialNumber:
          type: string
        subjectDn:
          type: string
        algorithm:
          type: string
        notBefore:
          type: string
          format: date-time
        notAfter:
          type: string
          format: date-time
        certificateBase64:
          type: string
    TenantService_TrustListSummaryResponse:
      required:
      - trustListId
      - source
      type: object
      properties:
        trustListId:
          type: string
        rootCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        source:
          type: string
        createdAt:
          type: string
          format: date-time
        freshness:
          type: string
          format: date-time
    TenantService_TwoFactorLoginResponse:
      required:
      - login_token
      type: object
      properties:
        requires_two_factor:
          type: boolean
        login_token:
          type: string
        available_methods:
          type: array
          items:
            type: string
        message:
          type: string
    TenantService_UpdateAuditRetentionRequest:
      type: object
      properties:
        retentionMonths:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_UpdateDomainRestrictionsRequest:
      type: object
      properties:
        allowedDomains:
          type: array
          items:
            type: string
    TenantService_UpdateMaxOrgsRequest:
      type: object
      properties:
        maxOrgsPerUser:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_UpdateOrgStatusRequest:
      required:
      - status
      type: object
      properties:
        status:
          $ref: '#/components/schemas/OrganizationStatus'
    TenantService_UpdateOrganizationRequest:
      type: object
      properties:
        name:
          type:
          - null
          - string
        status:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/OrganizationStatus'
        branding:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/BrandingConfigurationDto'
    TenantService_UpdateParticipantRequest:
      type: object
      properties:
        displayName:
          maxLength: 256
          minLength: 1
          type:
          - null
          - string
        status:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/ParticipantIdentityStatus'
    TenantService_UpdatePreferencesRequest:
      type: object
      properties:
        theme:
          type:
          - null
          - string
        language:
          type:
          - null
          - string
        timeFormat:
          type:
          - null
          - string
        defaultWalletAddress:
          type:
          - null
          - string
        notificationsEnabled:
          type:
          - null
          - boolean
        notificationMethod:
          type:
          - null
          - string
        notificationFrequency:
          type:
          - null
          - string
    TenantService_UpdatePublicOrgRequest:
      type: object
      properties:
        enabled:
          type: boolean
    TenantService_UpdatePublishedParticipantRequest:
      required:
      - registerId
      - participantId
      - participantName
      - organizationName
      - addresses
      - signerWalletAddress
      type: object
      properties:
        registerId:
          type: string
        participantId:
          type: string
        participantName:
          type: string
        organizationName:
          type: string
        addresses:
          type: array
          items:
            $ref: '#/components/schemas/ParticipantAddressRequest'
        signerWalletAddress:
          type: string
        status:
          type:
          - null
          - string
        metadata:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonElement'
    TenantService_UpdateUserRequest:
      type: object
      properties:
        displayName:
          type:
          - null
          - string
        roles:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/UserRole'
        status:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/IdentityStatus'
    TenantService_UploadTrustListRequest:
      required:
      - roots
      type: object
      properties:
        source:
          type:
          - null
          - string
        roots:
          type: array
          items:
            type: string
        freshness:
          type:
          - null
          - string
          format: date-time
    TenantService_UserListResponse:
      type: object
      properties:
        users:
          type: array
          items:
            $ref: '#/components/schemas/UserResponse'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        pendingInvitations:
          type: array
          items:
            $ref: '#/components/schemas/PendingInvitationResponse'
        pendingInvitationCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    TenantService_UserResponse:
      type: object
      properties:
        id:
          type: string
          format: uuid
        organizationId:
          type: string
          format: uuid
        email:
          type: string
        displayName:
          type: string
        roles:
          type: array
          items:
            $ref: '#/components/schemas/UserRole'
        status:
          $ref: '#/components/schemas/IdentityStatus'
        createdAt:
          type: string
          format: date-time
        lastLoginAt:
          type:
          - null
          - string
          format: date-time
        emailVerified:
          type: boolean
        emailVerifiedAt:
          type:
          - null
          - string
          format: date-time
        provisionedVia:
          type: string
        invitedByUserId:
          type:
          - null
          - string
          format: uuid
        profileCompleted:
          type: boolean
        invitationStatus:
          type:
          - null
          - string
    TenantService_UserRole:
      enum:
      - system-admin
      - administrator
      - designer
      - auditor
      - consumer
    TenantService_Verify2FaRequest:
      required:
      - login_token
      - code
      type: object
      properties:
        login_token:
          type: string
        code:
          type: string
        is_backup_code:
          type: boolean
        tier:
          type:
          - null
          - string
    TenantService_VerifyEmailRequest:
      required:
      - token
      type: object
      properties:
        token:
          type: string
    TenantService_VerifyWalletLinkRequest:
      required:
      - signature
      - publicKey
      type: object
      properties:
        signature:
          type: string
        publicKey:
          type: string
    TenantService_WalletLinkChallengeResponse:
      type: object
      properties:
        challengeId:
          type: string
          format: uuid
        challenge:
          type: string
        walletAddress:
          type: string
        algorithm:
          type: string
        expiresAt:
          type: string
          format: date-time
        status:
          $ref: '#/components/schemas/ChallengeStatus'
    TenantService_WalletLinkStatus:
      enum:
      - active
      - revoked
    WalletService_AccessCheckResponse:
      required:
      - walletAddress
      - subject
      - requiredRight
      type: object
      properties:
        walletAddress:
          type: string
        subject:
          type: string
        requiredRight:
          type: string
        hasAccess:
          type: boolean
    WalletService_AccountGapStatus:
      type: object
      properties:
        account:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: uint32
        addressType:
          type: string
        unusedCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        maxRecommendedGap:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        isCompliant:
          type: boolean
        lastUsedIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        nextRecommendedIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    WalletService_AddressListResponse:
      required:
      - walletAddress
      type: object
      properties:
        walletAddress:
          type: string
        addresses:
          type: array
          items:
            $ref: '#/components/schemas/WalletAddressDto'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        page:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        pageSize:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        hasMore:
          type: boolean
    WalletService_AssuranceLevel:
      enum:
      - low
      - substantial
      - high
      - 
    WalletService_CachedCredentialPayload:
      type: object
      properties:
        id:
          type: string
          description: >-
            Server-assigned credential identifier. Matches `CredentialEntity.Id`

            (typically a URN like `urn:credential:AssuredIdentityCredential:...`).
        vct:
          type: string
          description: Verifiable Credential Type URI (e.g. Verified Citizen, Assured Identity).
        jwt:
          type: string
          description: Compact-serialised SD-JWT VC, including all selective-disclosure salts.
        issuerDid:
          type: string
          description: Issuer DID, e.g. `did:sorcha:org:{walletAddress}`.
        issuedAt:
          type: string
          description: UTC issuance time.
          format: date-time
        expiresAt:
          type:
          - null
          - string
          description: UTC expiry, if any.
          format: date-time
        statusListUri:
          type:
          - null
          - string
          description: Status list URI for revocation, if the credential is revocable.
        statusListIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          description: Bit position within the credential-type status list.
          format: int32
        displayMeta:
          oneOf:
          - type: null
          - description: >-
              Issuer-supplied display hints, mirroring the Feature 107 `x-review`

              id-card shape (issuerName, credentialName, colourTheme, etc.).
            $ref: '#/components/schemas/JsonObject'
      description: >-
        Wire shape of a credential as delivered from `GET /api/v1/wallet/credentials`

        or as a `credentials.added` entry inside a sync response. The wallet caches

        the JWT after encrypting it locally with the device-bound content key.
    WalletService_ClaimConstraint:
      required:
      - claimName
      type: object
      properties:
        claimName:
          maxLength: 200
          minLength: 1
          type: string
        expectedValue: {}
    WalletService_CreatePresentationRequestBody:
      required:
      - credentialType
      - callbackUrl
      type: object
      properties:
        credentialType:
          type: string
        acceptedIssuers:
          type:
          - null
          - array
          items:
            type: string
        requiredClaims:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/ClaimConstraint'
        callbackUrl:
          type: string
        targetWalletAddress:
          type:
          - null
          - string
        ttlSeconds:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        verifierIdentity:
          type:
          - null
          - string
    WalletService_CreateWalletRequest:
      required:
      - name
      - algorithm
      type: object
      properties:
        name:
          maxLength: 100
          minLength: 1
          type: string
          description: Friendly name for the wallet
        algorithm:
          type: string
          description: Cryptographic algorithm (ED25519, NISTP256, RSA4096)
        wordCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Number of words in mnemonic (12, 15, 18, 21, or 24)
          format: int32
        passphrase:
          type:
          - null
          - string
          description: Optional passphrase for additional security
        pqcAlgorithm:
          type:
          - null
          - string
          description: Optional PQC algorithm for hybrid wallets (e.g., ML-DSA-65, SLH-DSA-128s)
        enableHybrid:
          type: boolean
          description: 'Enable hybrid mode: creates both classical and PQC key pairs for the wallet'
        signingMode:
          type:
          - null
          - string
          description: >-
            Optional signing mode override. When provided and AllowSigningModeOverride is true,

            overrides the policy-determined signing mode.

            Values: "Local" (default — keys stored encrypted locally) or "KmsResident" (keys held in cloud KMS).
        tags:
          type:
          - null
          - object
          additionalProperties:
            type: string
          description: Optional metadata tags
      description: >-
        Request model for creating a new wallet.

        Consolidated DTO shared by Wallet Service and UI.
    WalletService_CreateWalletResponse:
      required:
      - wallet
      - mnemonicWords
      type: object
      properties:
        wallet:
          $ref: '#/components/schemas/WalletDto'
        mnemonicWords:
          type: array
          items:
            type: string
        pqcWalletAddress:
          type:
          - null
          - string
        pqcAlgorithm:
          type:
          - null
          - string
        warning:
          type: string
    WalletService_CredentialEntity:
      required:
      - id
      - type
      - issuerDid
      - subjectDid
      - claimsJson
      - rawToken
      - status
      - walletAddress
      type: object
      properties:
        id:
          type: string
        type:
          type: string
        issuerDid:
          type: string
        subjectDid:
          type: string
        claimsJson:
          type: string
        issuedAt:
          type: string
          format: date-time
        expiresAt:
          type:
          - null
          - string
          format: date-time
        rawToken:
          type: string
        status:
          $ref: '#/components/schemas/CredentialStatus'
        issuanceTxId:
          type:
          - null
          - string
        issuerOrgName:
          type:
          - null
          - string
        issuanceBlueprintId:
          type:
          - null
          - string
        issuanceInstanceId:
          type:
          - null
          - string
        issuanceActionId:
          type:
          - null
          - string
        claimActionId:
          type:
          - null
          - string
        registerId:
          type:
          - null
          - string
        walletAddress:
          type: string
        createdAt:
          type: string
          format: date-time
        usagePolicy:
          type: string
        maxPresentations:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        presentationCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        statusListUrl:
          type:
          - null
          - string
        statusListIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        displayConfigJson:
          type:
          - null
          - string
    WalletService_CredentialFormat:
      enum:
      - sd-jwt-vc
      - mso_mdoc
    WalletService_CredentialListResponse:
      type: object
      properties:
        credentials:
          type: array
          items:
            $ref: '#/components/schemas/CachedCredentialPayload'
          description: Full snapshot of credentials currently issued to the authenticated citizen.
      description: >-
        Response body for `GET /api/v1/wallet/credentials`. Used by a freshly-enrolled

        wallet to seed its cache; subsequent updates flow through `GET /api/v1/wallet/sync`.
    WalletService_CredentialRequirement:
      required:
      - type
      type: object
      properties:
        type:
          maxLength: 200
          minLength: 1
          type: string
        format:
          $ref: '#/components/schemas/CredentialFormat'
        trustPolicy:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/TrustPolicy'
        requiredClaims:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/ClaimConstraint'
        revocationCheckPolicy:
          $ref: '#/components/schemas/RevocationCheckPolicy'
        description:
          maxLength: 500
          type:
          - null
          - string
        presentationSource:
          $ref: '#/components/schemas/PresentationSource'
    WalletService_CredentialRevocationReason:
      type: integer
      description: Reason a credential was revoked.
    WalletService_CredentialStatus:
      enum:
      - Active
      - Expired
      - Revoked
      - Suspended
      - PendingAcceptance
      - Declined
      - Consumed
    WalletService_DecapsulateRequest:
      required:
      - ciphertext
      type: object
      properties:
        ciphertext:
          type: string
    WalletService_DecryptPayloadRequest:
      required:
      - encryptedPayload
      type: object
      properties:
        encryptedPayload:
          type: string
    WalletService_DecryptPayloadResponse:
      required:
      - decryptedPayload
      - decryptedBy
      type: object
      properties:
        decryptedPayload:
          type: string
        decryptedBy:
          type: string
        decryptedAt:
          type: string
          format: date-time
    WalletService_DelegationRenewalRequest:
      type: object
      properties:
        deviceId:
          type: string
          description: The device whose delegation should be renewed.
          format: uuid
      description: >-
        Request body for `POST /api/v1/wallet/devices/renew-delegation`. Idempotent;

        the wallet calls this when its current delegation is within 30 days of expiry.
    WalletService_DelegationRenewalResponse:
      type: object
      properties:
        delegationCredential:
          type: string
          description: The renewed (or existing-and-not-yet-due) compact SD-JWT VC.
        expiresAt:
          type: string
          description: UTC time at which the returned delegation expires.
          format: date-time
      description: Response body for `POST /api/v1/wallet/devices/renew-delegation`.
    WalletService_DelegationReviewItem:
      type: object
      properties:
        delegationId:
          type: string
          format: uuid
        walletAddress:
          type: string
        subject:
          type: string
        accessRight:
          type: string
        grantedAt:
          type: string
          format: date-time
        reason:
          type:
          - null
          - string
    WalletService_DeriveKeyRequest:
      required:
      - userId
      type: object
      properties:
        userId:
          type: string
        departmentId:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: uint32
          default: 0
        keyUsage:
          type: string
          default: Identity
    WalletService_DerivedKeyResult:
      required:
      - derivedKeyId
      - walletAddress
      - derivationPath
      - keyUsage
      - keyIndex
      - status
      - custodyMode
      - createdAt
      type: object
      properties:
        derivedKeyId:
          type: string
          format: uuid
        walletAddress:
          type: string
        derivationPath:
          type: string
        keyUsage:
          $ref: '#/components/schemas/KeyUsage'
        keyIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: uint32
        status:
          type: string
        custodyMode:
          type: string
        createdAt:
          type: string
          format: date-time
        isNewlyCreated:
          type: boolean
          default: true
    WalletService_DeviceEnrolmentRequest:
      type: object
      properties:
        deviceLabel:
          type: string
          description: Citizen-editable label, 1..120 chars.
        devicePublicJwk:
          description: Public half of the device's ECDSA P-256 signing keypair.
          $ref: '#/components/schemas/EcP256PublicJwk'
        platform:
          type: string
          description: Free-form platform descriptor, e.g. `"iOS 19 / Safari 19"`. ≤120 chars.
        userAgent:
          type: string
          description: Raw user-agent at enrolment time, for audit. ≤512 chars.
      description: >-
        Request body for `POST /api/v1/wallet/devices/enrol`. Submitted by the

        citizen wallet PWA after the citizen authenticates and the wallet generates

        its non-extractable device keypair.
    WalletService_DeviceEnrolmentResponse:
      type: object
      properties:
        deviceId:
          type: string
          description: Server-assigned device identifier (Tenant Service's `PlatformUserDevice.Id`).
          format: uuid
        delegationCredential:
          type: string
          description: >-
            Compact-serialised SD-JWT VC. Issuer = the citizen's holder key; subject = this device.

            See `contracts/device-delegation-credential.schema.json`.
        holderPublicJwk:
          description: Public half of the citizen's holder key, for verifier-side cnf-chain validation.
          $ref: '#/components/schemas/EcP256PublicJwk'
        statusListUri:
          type: string
          description: Token Status List 2024 URI for revocation lookup.
        statusListIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Bit position within the status list.
          format: int32
        delegationExpiresAt:
          type: string
          description: UTC time at which the delegation credential expires.
          format: date-time
      description: >-
        Response body for `POST /api/v1/wallet/devices/enrol`. Carries everything

        the wallet needs to make offline presentations: server-assigned device id, the

        signed device delegation credential, the holder's public key (verifier

        convenience), the status-list URI + index for revocation lookup, and the

        delegation expiry.
    WalletService_DeviceLabelUpdateRequest:
      type: object
      properties:
        label:
          type: string
          description: New citizen-visible label, 1..120 chars.
      description: Request body for `PUT /api/v1/wallet/devices/{deviceId}/label`.
    WalletService_DeviceListResponse:
      type: object
      properties:
        devices:
          type: array
          items:
            $ref: '#/components/schemas/DeviceSummary'
          description: All devices enrolled under the authenticated citizen account.
      description: Response body for `GET /api/v1/wallet/devices` and `GET /api/v1/me/devices`.
    WalletService_DeviceStatus:
      enum:
      - Active
      - Revoked
      description: Status of an enrolled wallet device.
    WalletService_DeviceSummary:
      type: object
      properties:
        deviceId:
          type: string
          description: Server-assigned device identifier.
          format: uuid
        label:
          type: string
          description: Citizen-set label.
        platform:
          type: string
          description: Free-form platform descriptor at enrolment.
        status:
          description: Active or Revoked.
          $ref: '#/components/schemas/DeviceStatus'
        enrolledAt:
          type: string
          description: UTC time of original enrolment.
          format: date-time
        revokedAt:
          type:
          - null
          - string
          description: UTC time of revocation, if revoked.
          format: date-time
        lastSeenAt:
          type:
          - null
          - string
          description: UTC time of the most recent successful sync (or null if never).
          format: date-time
        delegationExpiresAt:
          type: string
          description: UTC time at which the current delegation credential expires.
          format: date-time
      description: >-
        Citizen-visible summary of an enrolled wallet device. Returned by

        `GET /api/v1/wallet/devices` and `GET /api/v1/me/devices`.
    WalletService_EcP256PublicJwk:
      type: object
      properties:
        kty:
          type: string
          description: Key type. MUST be `EC`.
        crv:
          type: string
          description: Curve. MUST be `P-256`.
        x:
          type: string
          description: X coordinate, base64url-encoded.
        y:
          type: string
          description: Y coordinate, base64url-encoded.
      description: >-
        JSON Web Key carrying the public half of an EC P-256 keypair, in the shape

        produced by `SubtleCrypto.exportKey("jwk", ...)` on a public key.
    WalletService_EncapsulateRequest:
      required:
      - recipientPublicKey
      type: object
      properties:
        recipientPublicKey:
          type: string
        plaintext:
          type:
          - null
          - string
    WalletService_EncryptPayloadRequest:
      required:
      - payload
      type: object
      properties:
        payload:
          type: string
        recipientAddress:
          type:
          - null
          - string
    WalletService_EncryptPayloadResponse:
      required:
      - encryptedPayload
      - recipientAddress
      type: object
      properties:
        encryptedPayload:
          type: string
        recipientAddress:
          type: string
        encryptedAt:
          type: string
          format: date-time
    WalletService_EnsureIssuanceKeyResponse:
      required:
      - organizationId
      - rotationIndex
      - algorithm
      - thumbprint
      - derivedAt
      type: object
      properties:
        organizationId:
          type: string
          format: uuid
        rotationIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        algorithm:
          type: string
        thumbprint:
          type: string
        derivedAt:
          type: string
          format: date-time
    WalletService_GapStatusResponse:
      required:
      - walletAddress
      type: object
      properties:
        walletAddress:
          type: string
        accounts:
          type: array
          items:
            $ref: '#/components/schemas/AccountGapStatus'
        isCompliant:
          type: boolean
        warning:
          type:
          - null
          - string
    WalletService_GrantAccessRequest:
      required:
      - subject
      - accessRight
      type: object
      properties:
        subject:
          type: string
        accessRight:
          type: string
        reason:
          type:
          - null
          - string
        expiresAt:
          type:
          - null
          - string
          format: date-time
    WalletService_HolderKeysResponse:
      required:
      - holderJwk
      - encryptionPublicKey
      - algorithm
      - walletAddress
      type: object
      properties:
        holderJwk:
          $ref: '#/components/schemas/JsonElement'
        encryptionPublicKey:
          type: string
        algorithm:
          type: string
        walletAddress:
          type: string
    WalletService_HttpValidationProblemDetails:
      type: object
      properties:
        type:
          type:
          - null
          - string
        title:
          type:
          - null
          - string
        status:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        detail:
          type:
          - null
          - string
        instance:
          type:
          - null
          - string
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
    WalletService_IssueCredentialRequest:
      required:
      - credentialType
      - claims
      - recipientWallet
      type: object
      properties:
        credentialType:
          type: string
        claims:
          type: object
        recipientWallet:
          type: string
        expiryDuration:
          type:
          - null
          - string
        disclosableClaims:
          type:
          - null
          - array
          items:
            type: string
        issuanceBlueprintId:
          type:
          - null
          - string
        statusListUrl:
          type:
          - null
          - string
        statusListIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        statusListPurpose:
          type:
          - null
          - string
        statusClaimForm:
          $ref: '#/components/schemas/StatusClaimForm'
        skipRecipientStore:
          type: boolean
        issuerOrgName:
          type:
          - null
          - string
        tenantId:
          type:
          - null
          - string
        holderJwk:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/JsonElement'
    WalletService_IssuedCredentialResponse:
      required:
      - credentialId
      - type
      - issuerDid
      - subjectDid
      - claims
      - issuedAt
      - rawToken
      type: object
      properties:
        credentialId:
          type: string
        type:
          type: string
        issuerDid:
          type: string
        subjectDid:
          type: string
        claims:
          type: object
        issuedAt:
          type: string
          format: date-time
        expiresAt:
          type:
          - null
          - string
          format: date-time
        rawToken:
          type: string
    WalletService_JsonElement: {}
    WalletService_JsonObject:
      type: object
    WalletService_KeyUsage:
      type: integer
    WalletService_OrgMasterKeyProvisionResult:
      required:
      - organizationId
      - masterPublicKey
      - mnemonic
      - algorithm
      type: object
      properties:
        organizationId:
          type: string
        masterPublicKey:
          type: string
        mnemonic:
          type: string
        algorithm:
          type: string
    WalletService_PendingApplicationEnvelope:
      type: object
      properties:
        notice:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/PendingApplicationNotice'
    WalletService_PendingApplicationNotice:
      required:
      - label
      - setAt
      type: object
      properties:
        label:
          type: string
        setAt:
          type: string
          format: date-time
    WalletService_PersonaDecryptRequest:
      required:
      - ciphertext
      - nonce
      - wrappedKeyRef
      type: object
      properties:
        ciphertext:
          type: string
          format: byte
        nonce:
          type: string
          format: byte
        wrappedKeyRef:
          type: string
    WalletService_PersonaDecryptResponse:
      required:
      - plaintext
      type: object
      properties:
        plaintext:
          type: string
          format: byte
    WalletService_PersonaEncryptRequest:
      required:
      - plaintext
      type: object
      properties:
        plaintext:
          type: string
          format: byte
    WalletService_PersonaEncryptResponse:
      required:
      - ciphertext
      - nonce
      - wrappedKeyRef
      type: object
      properties:
        ciphertext:
          type: string
          format: byte
        nonce:
          type: string
          format: byte
        wrappedKeyRef:
          type: string
    WalletService_PresentationHistoryResponse:
      type: object
      properties:
        entries:
          type: array
          items:
            $ref: '#/components/schemas/PresentationLogEntry'
          description: Presentation history entries, newest-first.
      description: >-
        Response body for `GET /api/v1/wallet/presentations` (Feature 114, US5 PR3).

        The citizen's cross-device presentation history, newest-first. Reuses the wire

        PresentationLogEntry shape (carrying disclosed claim names only —

        never values); the vestigial `RegisterId`/`ActionTxId` fields are

        always null for these citizen-owned records.
    WalletService_PresentationLogEntry:
      type: object
      properties:
        id:
          type: string
          description: Wallet-generated identifier; used for server-side dedupe.
          format: uuid
        credentialId:
          type: string
          description: Credential that was presented.
          format: uuid
        verifierDid:
          type:
          - null
          - string
          description: Verifier's declared DID, if the request carried one.
        verifierLabel:
          type:
          - null
          - string
          description: Verifier-supplied display label (untrusted).
        disclosedClaims:
          type: array
          items:
            type: string
          description: Names of disclosed claims.
        presentedAt:
          type: string
          description: UTC time at which the wallet completed the presentation.
          format: date-time
        outcome:
          description: Outcome the wallet observed.
          $ref: '#/components/schemas/PresentationLogOutcome'
        registerId:
          type:
          - null
          - string
          description: Originating register, if known to the wallet (for lifecycle correlation).
        actionTxId:
          type:
          - null
          - string
          description: Originating action transaction id, if known.
      description: >-
        One entry in the wallet's local presentation history, also reported back to the

        platform on the next online sync via `POST /api/v1/wallet/presentations/log`.
    WalletService_PresentationLogOutcome:
      type: integer
      description: Outcome of a single presentation as the wallet recorded it.
    WalletService_PresentationLogReportRequest:
      type: object
      properties:
        entries:
          type: array
          items:
            $ref: '#/components/schemas/PresentationLogEntry'
          description: Pending log entries to report.
      description: >-
        Request body for `POST /api/v1/wallet/presentations/log`. Wallets may batch

        any number of pending entries; the server dedupes on each entry's `Id`.
    WalletService_PresentationSource:
      enum:
      - SorchaInternal
      - HaipExternalWallet
      - SorchaWallet
    WalletService_PreserveDelegationsRequest:
      required:
      - walletAddress
      - delegationIds
      type: object
      properties:
        walletAddress:
          type: string
        delegationIds:
          type: array
          items:
            type: string
            format: uuid
    WalletService_PreserveDelegationsResult:
      type: object
      properties:
        preserved:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    WalletService_RecoverOrgRequest:
      required:
      - userId
      - orgRecoveryKeySignature
      type: object
      properties:
        userId:
          type: string
        orgRecoveryKeySignature:
          type: string
        skipDelegationRevocation:
          type: boolean
    WalletService_RecoverPasskeyRequest:
      required:
      - passkeyCredentialId
      - challengeResponse
      type: object
      properties:
        passkeyCredentialId:
          type: string
        challengeResponse:
          type: string
    WalletService_RecoverSystemWalletRequest:
      required:
      - validatorId
      - mnemonic
      type: object
      properties:
        validatorId:
          type: string
        mnemonic:
          type: string
        algorithm:
          type: string
    WalletService_RecoverWalletRequest:
      required:
      - mnemonicWords
      - name
      - algorithm
      type: object
      properties:
        mnemonicWords:
          maxItems: 24
          minItems: 12
          type: array
          items:
            type: string
        name:
          maxLength: 100
          minLength: 1
          type: string
        algorithm:
          type: string
        passphrase:
          type:
          - null
          - string
    WalletService_RecoveryResult:
      type: object
      properties:
        walletsRecovered:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        walletAddresses:
          type: array
          items:
            type: string
        delegationsRevoked:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        delegationsPendingReview:
          type: array
          items:
            $ref: '#/components/schemas/DelegationReviewItem'
    WalletService_RecoveryStatusResponse:
      type: object
      properties:
        mnemonicRecoveryAvailable:
          type: boolean
        passkeyRecoveryAvailable:
          type: boolean
        orgRecoveryAvailable:
          type: boolean
        walletsWithRecovery:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        walletsWithoutRecovery:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    WalletService_RegisterDerivedAddressRequest:
      required:
      - derivedPublicKey
      - derivedAddress
      - derivationPath
      type: object
      properties:
        derivedPublicKey:
          type: string
        derivedAddress:
          type: string
        derivationPath:
          pattern: ^m/44'/\d+'/\d+'/[01]/\d+$
          type: string
        label:
          type:
          - null
          - string
        notes:
          type:
          - null
          - string
        tags:
          type:
          - null
          - string
        metadata:
          type:
          - null
          - object
          additionalProperties:
            type: string
    WalletService_ReplacedCredentialEntry:
      type: object
      properties:
        oldId:
          type: string
          description: >-
            Identifier of the old (now-superseded) credential. Matches

            `CredentialEntity.Id`.
        newId:
          type: string
          description: Identifier of the new credential. Matches `CredentialEntity.Id`.
        jwt:
          type: string
          description: Compact-serialised SD-JWT VC of the new credential.
        issuedAt:
          type: string
          description: UTC issuance time of the new credential.
          format: date-time
      description: >-
        Sync delta entry: an old credential has been replaced by a new one (e.g. re-issuance

        after attribute change). The wallet should remove string ReplacedCredentialEntry.OldId and add the new payload.
    WalletService_RevocationCheckPolicy:
      enum:
      - FailClosed
      - FailOpen
    WalletService_RevokeIssuanceKeyRequest:
      required:
      - rotationIndex
      - reason
      - governanceOpId
      type: object
      properties:
        rotationIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        reason:
          type: string
        governanceOpId:
          type: string
          format: uuid
    WalletService_RevokeIssuanceKeyResponse:
      required:
      - organizationId
      - rotationIndex
      - status
      - revokedAt
      type: object
      properties:
        organizationId:
          type: string
          format: uuid
        rotationIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        status:
          type: string
        revokedAt:
          type:
          - null
          - string
          format: date-time
    WalletService_RevokedCredentialEntry:
      type: object
      properties:
        id:
          type: string
          description: >-
            Credential identifier the wallet should mark as revoked. Matches

            `CredentialEntity.Id` (typically a URN like

            `urn:credential:AssuredIdentityCredential:...`).
        reason:
          description: Revocation reason.
          $ref: '#/components/schemas/CredentialRevocationReason'
        revokedAt:
          type: string
          description: UTC time of revocation.
          format: date-time
      description: 'Sync delta entry: a credential the wallet was holding has been revoked upstream.'
    WalletService_RotateIssuanceKeyRequest:
      required:
      - governanceOpId
      type: object
      properties:
        governanceOpId:
          type: string
          format: uuid
    WalletService_SetPendingApplicationRequest:
      type: object
      properties:
        label:
          type: string
    WalletService_SignTransactionRequest:
      required:
      - transactionData
      type: object
      properties:
        transactionData:
          type: string
        derivationPath:
          type:
          - null
          - string
        isPreHashed:
          type: boolean
        hybridMode:
          type: boolean
        pqcWalletAddress:
          type:
          - null
          - string
    WalletService_SignTransactionResponse:
      required:
      - signature
      - signedBy
      type: object
      properties:
        signature:
          type: string
        signedBy:
          type: string
        signedAt:
          type: string
          format: date-time
        publicKey:
          type:
          - null
          - string
    WalletService_SignWithIssuanceKeyRequest:
      required:
      - dataBase64Url
      type: object
      properties:
        dataBase64Url:
          type: string
    WalletService_SignWithIssuanceKeyResponse:
      required:
      - signatureBase64Url
      - kid
      - issuerDid
      - algorithm
      - rotationIndex
      type: object
      properties:
        signatureBase64Url:
          type: string
        kid:
          type: string
        issuerDid:
          type: string
        algorithm:
          type: string
        rotationIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    WalletService_StatusClaimForm:
      enum:
      - W3cBitstringStatusListEntry
      - IetfTokenStatusList
    WalletService_StoreCredentialRequest:
      required:
      - credentialId
      - type
      - issuerDid
      - subjectDid
      - claimsJson
      - issuedAt
      - rawToken
      type: object
      properties:
        credentialId:
          type: string
        type:
          type: string
        issuerDid:
          type: string
        subjectDid:
          type: string
        claimsJson:
          type: string
        issuedAt:
          type: string
          format: date-time
        expiresAt:
          type:
          - null
          - string
          format: date-time
        rawToken:
          type: string
        issuanceTxId:
          type:
          - null
          - string
        issuanceBlueprintId:
          type:
          - null
          - string
    WalletService_SubmitPresentationBody:
      required:
      - credentialId
      - vpToken
      type: object
      properties:
        credentialId:
          type: string
        disclosedClaims:
          type:
          - null
          - array
          items:
            type: string
        vpToken:
          type: string
    WalletService_SyncCredentialChanges:
      type: object
      properties:
        added:
          type: array
          items:
            $ref: '#/components/schemas/CachedCredentialPayload'
          description: New credentials to add to the cache.
        revoked:
          type: array
          items:
            $ref: '#/components/schemas/RevokedCredentialEntry'
          description: Credentials to mark as revoked.
        replaced:
          type: array
          items:
            $ref: '#/components/schemas/ReplacedCredentialEntry'
          description: Credentials replaced by re-issuance.
      description: Credential changes since the last sync.
    WalletService_SyncDelegationUpdate:
      type: object
      properties:
        renewed:
          type: boolean
          description: '`true` if a new delegation credential is included.'
        jwt:
          type:
          - null
          - string
          description: The renewed delegation, if bool SyncDelegationUpdate.Renewed is true.
        expiresAt:
          type:
          - null
          - string
          description: UTC expiry of the renewed delegation, if applicable.
          format: date-time
      description: >-
        Delegation update bundled with the sync response. bool SyncDelegationUpdate.Renewed indicates

        whether the server issued a fresh delegation in this sync (silent renewal path).
    WalletService_SyncResponse:
      type: object
      properties:
        syncToken:
          type: string
          description: >-
            Opaque cursor — must be passed back as `since` on the next sync to

            receive the next delta. Server-signed; do not parse client-side.
        credentials:
          description: Credential adds / revokes / replacements since the last sync.
          $ref: '#/components/schemas/SyncCredentialChanges'
        delegation:
          description: Optional delegation renewal piggybacking on this sync response.
          $ref: '#/components/schemas/SyncDelegationUpdate'
        statusListsToRefresh:
          type: array
          items:
            type: string
          description: Status list URIs the wallet should refresh now (cache may be stale).
      description: >-
        Response body for `GET /api/v1/wallet/sync`. Carries the delta since the

        caller's previous sync token, plus any silent delegation renewal and a list

        of status-list URIs the wallet should refresh.
    WalletService_SystemWalletRequest:
      type: object
      properties:
        validatorId:
          type:
          - null
          - string
    WalletService_SystemWalletResponse:
      required:
      - address
      type: object
      properties:
        address:
          type: string
    WalletService_TrustCombinator:
      enum:
      - anyOf
      - allOf
    WalletService_TrustPolicy:
      type: object
      properties:
        sources:
          type: array
          items:
            $ref: '#/components/schemas/TrustSourceRef'
        combinator:
          $ref: '#/components/schemas/TrustCombinator'
        minAssuranceLevel:
          $ref: '#/components/schemas/AssuranceLevel'
    WalletService_TrustSourceKind:
      enum:
      - register
      - x509-tenant
      - trustlist
      - did-allowlist
    WalletService_TrustSourceRef:
      type: object
      properties:
        kind:
          $ref: '#/components/schemas/TrustSourceKind'
        confersAssurance:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/AssuranceLevel'
        allowedIssuers:
          type:
          - null
          - array
          items:
            type: string
        trustListId:
          type:
          - null
          - string
        options:
          type:
          - null
          - object
          additionalProperties:
            type: string
    WalletService_UpdateAddressRequest:
      type: object
      properties:
        label:
          type:
          - null
          - string
        notes:
          type:
          - null
          - string
        tags:
          type:
          - null
          - string
        metadata:
          type:
          - null
          - object
          additionalProperties:
            type: string
    WalletService_UpdateStatusRequest:
      required:
      - status
      type: object
      properties:
        status:
          type: string
    WalletService_UpdateWalletRequest:
      type: object
      properties:
        name:
          maxLength: 100
          minLength: 1
          type:
          - null
          - string
        tags:
          type:
          - null
          - object
          additionalProperties:
            type: string
    WalletService_VerifySignatureRequest:
      required:
      - publicKey
      - data
      - signature
      - algorithm
      type: object
      properties:
        publicKey:
          type: string
        data:
          type: string
        signature:
          type: string
        algorithm:
          type: string
    WalletService_WalletAccessDto:
      required:
      - subject
      - accessRight
      - grantedBy
      type: object
      properties:
        id:
          type: string
          format: uuid
        subject:
          type: string
        accessRight:
          type: string
        grantedBy:
          type: string
        reason:
          type:
          - null
          - string
        grantedAt:
          type: string
          format: date-time
        expiresAt:
          type:
          - null
          - string
          format: date-time
        isActive:
          type: boolean
    WalletService_WalletAddressDto:
      required:
      - parentWalletAddress
      - address
      - derivationPath
      type: object
      properties:
        id:
          type: string
          format: uuid
        parentWalletAddress:
          type: string
        address:
          type: string
        publicKey:
          type:
          - null
          - string
        derivationPath:
          type: string
        index:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        account:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: uint32
        isChange:
          type: boolean
        label:
          type:
          - null
          - string
        notes:
          type:
          - null
          - string
        tags:
          type:
          - null
          - string
        isUsed:
          type: boolean
        createdAt:
          type: string
          format: date-time
        firstUsedAt:
          type:
          - null
          - string
          format: date-time
        lastUsedAt:
          type:
          - null
          - string
          format: date-time
        metadata:
          type: object
          additionalProperties:
            type: string
    WalletService_WalletDto:
      required:
      - address
      - name
      - publicKey
      - algorithm
      - status
      - owner
      - tenant
      type: object
      properties:
        address:
          type: string
        name:
          type: string
        publicKey:
          type: string
        algorithm:
          type: string
        status:
          type: string
        owner:
          type: string
        tenant:
          type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        signingMode:
          type: string
        kmsKeyId:
          type:
          - null
          - string
        metadata:
          type: object
          additionalProperties:
            type: string
    WalletService_WalletExistsResponse:
      type: object
      properties:
        hasWallet:
          type: boolean
          description: >-
            `true` when a wallet resolves for the calling citizen, else
                    `false`.
      description: >-
        Response body for `GET /api/v1/wallet/exists` (Feature 149). Lets the

        Citizen Wallet PWA's pairing takeover distinguish "no wallet yet" (route the

        citizen to web wallet creation) from "wallet exists, no device here" (offer

        the pair flow). Carries a boolean only — never a wallet address or other PII.
    RegisterService_ActionRef:
      type: object
      properties:
        actionId:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Gets or sets the next action identifier.
          format: int32
        branchKey:
          type:
          - null
          - string
          description: Gets or sets an optional branch discriminator for parallel branches.
      description: >-
        A reference to a next action within a routing decision. string? ActionRef.BranchKey

        distinguishes parallel branches where the route graph needs it.
    RegisterService_AdditionalAdminInfo:
      required:
      - userId
      - walletId
      type: object
      properties:
        userId:
          type: string
          description: User identifier
        walletId:
          type: string
          description: Wallet identifier for signing
        role:
          description: Role to grant (defaults to Admin)
          $ref: '#/components/schemas/RegisterRole'
      description: Additional administrator information
    RegisterService_ApprovalSignature:
      required:
      - approverDid
      - signature
      - votedAt
      type: object
      properties:
        approverDid:
          type: string
          description: DID of the approver
        signature:
          type: string
          description: Base64-encoded signature
        isApproval:
          type: boolean
          description: Whether this is an approval (true) or rejection (false)
        votedAt:
          type: string
          description: When the vote was cast (UTC)
          format: date-time
        comment:
          maxLength: 500
          minLength: 0
          type:
          - null
          - string
          description: Optional comment with the vote
      description: A voting approval signature from a roster member
    RegisterService_ApprovedValidator:
      type: object
      properties:
        did:
          type: string
          description: >-
            Decentralized identifier (DID) of the approved validator.

            Must be in DID format and at most 255 characters.
        publicKey:
          type: string
          description: Base64-encoded public key of the approved validator.
        approvedAt:
          type: string
          description: UTC timestamp when this validator was approved.
          format: date-time
        approvedBy:
          type:
          - null
          - string
          description: DID of the participant who approved this validator. Null for genesis entries.
      description: An approved validator entry containing identity and approval metadata.
    RegisterService_ApprovedValidatorsResponse:
      type: object
      properties:
        registerId:
          type: string
        registrationMode:
          $ref: '#/components/schemas/RegistrationMode'
        validators:
          type: array
          items:
            $ref: '#/components/schemas/ApprovedValidator'
        count:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    RegisterService_Attestation:
      type: object
      properties:
        kind:
          description: Gets or sets the attestation variant. Defaults to AttestationKind.SenderSigned.
          $ref: '#/components/schemas/AttestationKind'
        signature:
          type:
          - null
          - string
          description: >-
            Gets or sets the sender wallet signature over the canonical, attestation-free decision

            (byte[] RoutingDecision.ComputeSignableBytes()). Populated for

            AttestationKind.SenderSigned (v1).
      description: >-
        The pluggable trust mechanism for a RoutingDecision (Feature 145, Entity 2).

        v1 ships only AttestationKind.SenderSigned; the other variants are the

        reserved upgrade seam. The instance projection reads

        List&lt;ActionRef&gt; RoutingDecision.NextActions regardless of variant — only validation branches

        on AttestationKind Attestation.Kind.
    RegisterService_AttestationKind:
      enum:
      - SenderSigned
      - ValidatorReEvaluated
      - Proof
      - 
    RegisterService_AttestationSigningData:
      required:
      - role
      - subject
      - registerId
      - registerName
      - grantedAt
      type: object
      properties:
        role:
          description: Role being granted (Owner, Admin, etc.)
          $ref: '#/components/schemas/RegisterRole'
        subject:
          type: string
          description: Subject DID (e.g., "did:sorcha:user-001")
        registerId:
          type: string
          description: Register identifier being attested to
        registerName:
          type: string
          description: Register name (immutable after signing)
        grantedAt:
          type: string
          description: Timestamp when this attestation was granted
          format: date-time
      description: Data structure that each owner/admin signs to attest to register creation
    RegisterService_BatchPublicKeyRequest:
      required:
      - walletAddresses
      type: object
      properties:
        walletAddresses:
          type: array
          items:
            type: string
          description: Wallet addresses to resolve (1-200).
        algorithm:
          type:
          - null
          - string
          description: Optional algorithm filter.
      description: Request for batch public key resolution (FR-008).
    RegisterService_BatchPublicKeyResponse:
      type: object
      properties:
        resolved:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/PublicKeyResolution'
          description: Successfully resolved keys (address → resolution).
        notFound:
          type: array
          items:
            type: string
          description: Addresses with no published participant record.
        revoked:
          type: array
          items:
            type: string
          description: Addresses whose participant record is revoked.
      description: >-
        Response from batch public key resolution.

        Handles mixed results: some found, some not found, some revoked.
    RegisterService_BatchReceiptRequest:
      required:
      - docketNumber
      - receipts
      type: object
      properties:
        docketNumber:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int64
        receipts:
          type: array
          items:
            $ref: '#/components/schemas/TransactionReceipt'
    RegisterService_Challenge:
      type: object
      properties:
        data:
          type:
          - null
          - string
          description: Challenge data (encrypted key material)
        address:
          type:
          - null
          - string
          description: Wallet address this challenge is for
      description: Represents encryption challenge data for wallet-based decryption
    RegisterService_ClassifyChangeRequest:
      required:
      - newBlueprint
      type: object
      properties:
        newBlueprint:
          $ref: '#/components/schemas/JsonElement'
    RegisterService_CryptoPolicy:
      type: object
      properties:
        version:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Policy version (monotonically increasing). Must be &gt;= 1 and &gt; previous version.
          format: uint32
        acceptedSignatureAlgorithms:
          type: array
          items:
            type: string
          description: >-
            Algorithm identifiers accepted for transaction signing.

            At least one must be specified.
        requiredSignatureAlgorithms:
          type: array
          items:
            type: string
          description: >-
            Algorithms that MUST be present on every transaction.

            Must be a subset of string[] CryptoPolicy.AcceptedSignatureAlgorithms.
        acceptedEncryptionSchemes:
          type: array
          items:
            type: string
          description: >-
            Encryption schemes accepted for payload encryption.

            At least one must be specified.
        acceptedHashFunctions:
          type: array
          items:
            type: string
          description: >-
            Hash functions accepted for TxId computation.

            At least one must be specified.
        enforcementMode:
          description: 'Enforcement mode: Permissive (warn) or Strict (reject).'
          $ref: '#/components/schemas/CryptoPolicyEnforcementMode'
        effectiveFrom:
          type: string
          description: UTC timestamp when this policy version takes effect.
          format: date-time
        deprecatedAlgorithms:
          type: array
          items:
            type: string
          description: Algorithms being phased out. Transactions using these generate warnings.
        devMode:
          type: boolean
          description: >-
            DevMode: when `true`, the register skips field-level payload encryption and stores

            payloads as plaintext (still disclosure-filtered, still routed through JSON-Logic and

            calculations). A development / debugging posture for verifying workflow logic without the

            crypto layer; receivers read the plaintext directly without decrypting.
      description: >-
        Per-register cryptographic policy governing which algorithms are accepted.

        Embedded in control transaction payloads and upgradeable via governance.
    RegisterService_CryptoPolicyEnforcementMode:
      enum:
      - Permissive
      - Strict
      description: Policy enforcement mode for cryptographic operations.
    RegisterService_DevModeToggleRequest:
      required:
      - enabled
      type: object
      properties:
        enabled:
          type: boolean
    RegisterService_Docket:
      required:
      - registerId
      - hash
      type: object
      properties:
        id:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Docket identifier (docket height)
          format: uint64
        registerId:
          type: string
          description: Register identifier this docket belongs to
        previousHash:
          type: string
          description: Hash of previous docket for chain integrity
        hash:
          type: string
          description: Hash of this docket
        transactionIds:
          type: array
          items:
            type: string
          description: List of transaction IDs sealed in this docket
        timeStamp:
          type: string
          description: Docket creation timestamp (UTC)
          format: date-time
        state:
          description: Current docket lifecycle state
          $ref: '#/components/schemas/DocketState'
        metaData:
          oneOf:
          - type: null
          - description: Docket metadata
            $ref: '#/components/schemas/TransactionMetaData'
        votes:
          type:
          - null
          - string
          description: Consensus votes (implementation TBD)
      description: Represents a sealed docket of transactions
    RegisterService_DocketState:
      type: integer
      description: Represents the lifecycle state of a docket
    RegisterService_ElectionMechanism:
      enum:
      - Rotating
      - Raft
      - StakeWeighted
      description: Mechanism used to elect the next block proposer among validators
    RegisterService_FinalizeRegisterCreationRequest:
      required:
      - registerId
      - nonce
      - signedAttestations
      type: object
      properties:
        registerId:
          maxLength: 32
          minLength: 32
          pattern: ^[a-f0-9]{32}$
          type: string
          description: Register identifier from initiation phase
        nonce:
          type: string
          description: Nonce from initiation (replay protection)
        signedAttestations:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/SignedAttestation'
          description: Signed attestations from all owners/admins
        controlRecord:
          oneOf:
          - type: null
          - description: 'Legacy field: Control record (deprecated)'
            $ref: '#/components/schemas/RegisterControlRecord'
      description: Request to finalize register creation (Phase 2)
    RegisterService_GovernanceOperationType:
      type: integer
      description: Types of governance operations that can be performed on a register's admin roster
    RegisterService_GovernanceProposalRequest:
      required:
      - operationType
      - proposerDid
      - targetDid
      type: object
      properties:
        operationType:
          $ref: '#/components/schemas/GovernanceOperationType'
        proposerDid:
          type: string
        targetDid:
          type: string
        targetRole:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/RegisterRole'
        justification:
          type:
          - null
          - string
        approvalSignatures:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/ApprovalSignature'
        validatorEntry:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/ValidatorRosterEntry'
    RegisterService_HttpValidationProblemDetails:
      type: object
      properties:
        type:
          type:
          - null
          - string
        title:
          type:
          - null
          - string
        status:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
        detail:
          type:
          - null
          - string
        instance:
          type:
          - null
          - string
        errors:
          type: object
          additionalProperties:
            type: array
            items:
              type: string
    RegisterService_InclusionProofRequest:
      required:
      - txId
      - docketId
      type: object
      properties:
        txId:
          type: string
        docketId:
          type: string
    RegisterService_InitiateRegisterCreationRequest:
      required:
      - name
      - owners
      type: object
      properties:
        name:
          maxLength: 38
          minLength: 1
          type: string
          description: Human-readable register name
        description:
          maxLength: 500
          minLength: 0
          type:
          - null
          - string
          description: Purpose and scope of the register
        owners:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/OwnerInfo'
          description: Register owners (at least one required)
        additionalAdmins:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/AdditionalAdminInfo'
          description: Additional administrators to grant access
        metadata:
          type:
          - null
          - object
          additionalProperties:
            type: string
          description: Additional register metadata
        advertise:
          type: boolean
          description: 'Whether to advertise this register to the peer network (default: false/private)'
        policy:
          oneOf:
          - type: null
          - description: Optional operational policy for the register. When omitted, default policy is applied at genesis.
            $ref: '#/components/schemas/RegisterPolicy'
        registerId:
          maxLength: 32
          minLength: 32
          pattern: ^[a-f0-9]{32}$
          type:
          - null
          - string
          description: >-
            Optional pre-determined register ID. When provided, this ID is used instead of generating a new one.

            Must be a 32-character lowercase hex string. Used by the system register bootstrapper to create

            the system register with a deterministic well-known ID.
        devMode:
          type: boolean
          description: >-
            When true, payloads are stored as plaintext with disclosure filtering at read time.

            When false (default), payloads use envelope encryption with disclosure groups.
        purpose:
          description: Classification of the register's intended use (defaults to General)
          $ref: '#/components/schemas/RegisterPurpose'
      description: Request to initiate register creation (Phase 1)
    RegisterService_JsonElement: {}
    RegisterService_MerkleInclusionProof:
      required:
      - transactionHash
      - docketNumber
      - merkleRoot
      - proofPath
      - leafIndex
      - treeSize
      type: object
      properties:
        transactionHash:
          type: string
          description: SHA-256 hash of the proven transaction.
        docketNumber:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Docket height where the transaction was sealed.
          format: int64
        merkleRoot:
          type: string
          description: Expected Merkle root hash of the docket.
        proofPath:
          type: array
          items:
            $ref: '#/components/schemas/MerkleProofStep'
          description: Sibling hashes from leaf to root.
        leafIndex:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Position of the transaction in the tree (0-based).
          format: int32
        treeSize:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Total number of leaves (transactions) in the docket.
          format: int32
      description: >-
        A compact proof that a transaction hash is a leaf in a docket's Merkle tree.

        Contains the sibling hashes from leaf to root (log2(n) steps).
    RegisterService_MerkleProofStep:
      required:
      - hash
      - position
      type: object
      properties:
        hash:
          type: string
          description: Sibling hash at this tree level.
        position:
          description: Whether the sibling is to the left or right.
          $ref: '#/components/schemas/ProofPosition'
      description: A single step in a Merkle inclusion proof path.
    RegisterService_OperationalValidatorInfo:
      type: object
      properties:
        did:
          type: string
        lastHeartbeat:
          type: string
          format: date-time
        isLeader:
          type: boolean
    RegisterService_OperationalValidatorsResponse:
      type: object
      properties:
        registerId:
          type: string
        validators:
          type: array
          items:
            $ref: '#/components/schemas/OperationalValidatorInfo'
        count:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    RegisterService_OwnerInfo:
      required:
      - userId
      - walletId
      type: object
      properties:
        userId:
          type: string
          description: User identifier (DID)
        walletId:
          type: string
          description: Wallet identifier for signing
      description: Owner information for register initialization
    RegisterService_PayloadModel:
      required:
      - hash
      - data
      type: object
      properties:
        walletAccess:
          type: array
          items:
            type: string
          description: Wallet addresses authorized to decrypt this payload
        payloadSize:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Size of encrypted payload in bytes
          format: uint64
        hash:
          type: string
          description: SHA-256 hash of payload for integrity
        data:
          type: string
          description: Encrypted data (Base64 encoded)
        payloadFlags:
          type:
          - null
          - string
          description: Encryption metadata flags
        iv:
          oneOf:
          - type: null
          - description: Initialization vector for encryption
            $ref: '#/components/schemas/Challenge'
        challenges:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/Challenge'
          description: Per-wallet encryption challenges
        contentType:
          type:
          - null
          - string
          description: >-
            MIME type describing the plaintext data format (e.g., "application/json", "application/pdf").

            When absent (legacy payloads), inferred as "application/octet-stream".
        contentEncoding:
          type:
          - null
          - string
          description: >-
            Encoding scheme for the Data field. Supported values: "identity" (native JSON),

            "base64url" (RFC 4648 §5), "base64" (legacy read-only), "br+base64url", "gzip+base64url".

            When absent (legacy payloads), inferred as "base64".
      description: Encrypted payload within a transaction
    RegisterService_PolicyConsensusConfig:
      type: object
      properties:
        signatureThresholdMin:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Minimum number of validator signatures required per docket.

            Must be &gt;= 1.
          format: int32
        signatureThresholdMax:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Maximum number of validator signatures accepted per docket.

            Must be &gt;= int PolicyConsensusConfig.SignatureThresholdMin.
          format: int32
        maxTransactionsPerDocket:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Maximum number of transactions that can be batched into a single docket.

            Must be &gt;= 1 and &lt;= 10000.
          format: int32
        docketBuildIntervalMs:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Interval in milliseconds between docket build cycles.

            Must be &gt;= 10 and &lt;= 60000.
          format: int32
        docketTimeoutSeconds:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Timeout in seconds for docket completion before retry.

            Must be &gt;= 5 and &lt;= 300.
          format: int32
      description: >-
        Consensus configuration controlling signature thresholds, docket capacity,

        and timing parameters.
    RegisterService_PolicyGovernanceConfig:
      type: object
      properties:
        quorumFormula:
          description: Formula used to calculate quorum requirements for governance proposals.
          $ref: '#/components/schemas/QuorumFormula'
        proposalTtlDays:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Number of days a governance proposal remains active before expiring.

            Must be &gt;= 1 and &lt;= 90.
          format: int32
        ownerCanBypassQuorum:
          type: boolean
          description: Whether the register owner can bypass quorum requirements.
        blueprintVersion:
          type: string
          description: >-
            Version identifier for the governance blueprint schema.

            Must be non-empty and at most 100 characters.
      description: >-
        Governance configuration controlling quorum rules, proposal lifecycle,

        and owner override capabilities.
    RegisterService_PolicyHistoryResponse:
      type: object
      properties:
        registerId:
          type: string
        versions:
          type: array
          items:
            $ref: '#/components/schemas/PolicyVersionEntry'
        page:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        pageSize:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        totalPages:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
    RegisterService_PolicyLeaderElectionConfig:
      type: object
      properties:
        mechanism:
          description: Mechanism used for leader election among validators.
          $ref: '#/components/schemas/ElectionMechanism'
        heartbeatIntervalMs:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Interval in milliseconds between leader heartbeat messages.

            Must be &gt;= 100 and &lt;= 30000.
          format: int32
        leaderTimeoutMs:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Timeout in milliseconds before a leader is considered unresponsive.

            Must be &gt; int PolicyLeaderElectionConfig.HeartbeatIntervalMs.
          format: int32
        termDurationSeconds:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          description: >-
            Duration in seconds for a leader's term. Null for indefinite terms.

            Must be &gt;= 10 when set.
          format: int32
      description: >-
        Leader election configuration controlling the mechanism, heartbeat intervals,

        timeout thresholds, and term duration.
    RegisterService_PolicyUpdateRequest:
      type: object
      properties:
        policy:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/RegisterPolicy'
        transitionMode:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/TransitionMode'
        updatedBy:
          type: string
    RegisterService_PolicyUpdateResponse:
      type: object
      properties:
        registerId:
          type: string
        proposedVersion:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: uint32
        currentVersion:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: uint32
        requiresGovernanceVote:
          type: boolean
        message:
          type: string
    RegisterService_PolicyValidatorConfig:
      type: object
      properties:
        registrationMode:
          description: >-
            How validators are registered: Public (open self-registration) or Consent (permissioned —

            explicit roster approval required). Feature 138 US3 / FR-011 defaults this to Consent so a

            register is not silently open to self-admitting validators.
          $ref: '#/components/schemas/RegistrationMode'
        approvedValidators:
          type: array
          items:
            $ref: '#/components/schemas/ApprovedValidator'
          description: >-
            List of pre-approved validators when RegistrationMode PolicyValidatorConfig.RegistrationMode is Approved.

            Maximum 100 entries.
        minValidators:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Minimum number of validators required for the register to operate.

            Must be &gt;= 1.
          format: int32
        maxValidators:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Maximum number of validators allowed on the register.

            Must be &gt;= int PolicyValidatorConfig.MinValidators and &lt;= 100.
          format: int32
        requireStake:
          type: boolean
          description: Whether validators must stake tokens to participate.
        stakeAmount:
          pattern: ^-?(?:0|[1-9]\d*)(?:\.\d+)?$
          type:
          - null
          - number
          - string
          description: >-
            Amount of stake required when bool PolicyValidatorConfig.RequireStake is true.

            Must be &gt; 0 when staking is required.
          format: double
        operationalTtlSeconds:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Time-to-live in seconds for a validator's operational heartbeat.

            Must be &gt;= 10 and &lt;= 600.
          format: int32
      description: >-
        Validator configuration controlling registration mode, approval lists,

        capacity limits, staking, and operational parameters.
    RegisterService_PolicyVersionEntry:
      type: object
      properties:
        version:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: uint32
        policy:
          $ref: '#/components/schemas/RegisterPolicy'
        updatedAt:
          type: string
          format: date-time
        updatedBy:
          type:
          - null
          - string
    RegisterService_ProofPosition:
      type: integer
      description: Position of a sibling hash in the Merkle proof path.
    RegisterService_PublicKeyResolution:
      required:
      - participantId
      - participantName
      - walletAddress
      - publicKey
      - algorithm
      - status
      type: object
      properties:
        participantId:
          type: string
          description: Identifier of the participant.
        participantName:
          type: string
          description: The participant name.
        walletAddress:
          type: string
          description: The wallet address.
        publicKey:
          type: string
          description: Public key material.
        algorithm:
          type: string
          description: Cryptographic algorithm identifier.
        status:
          type: string
          description: Current status of the resource.
      description: Public key resolution result
    RegisterService_PublishBlueprintRequest:
      required:
      - blueprintId
      - blueprint
      type: object
      properties:
        blueprintId:
          type: string
        blueprint:
          $ref: '#/components/schemas/JsonElement'
        previousTransactionId:
          type:
          - null
          - string
        metadata:
          type:
          - null
          - object
          additionalProperties:
            type: string
    RegisterService_PublishBlueprintResponse:
      required:
      - transactionId
      - blueprintId
      type: object
      properties:
        transactionId:
          type: string
        blueprintId:
          type: string
        version:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int64
        publishedAt:
          type: string
          format: date-time
    RegisterService_PublishBlueprintToRegisterRequest:
      required:
      - blueprintId
      - blueprintJson
      - publishedBy
      type: object
      properties:
        blueprintId:
          type: string
        blueprintJson:
          type: string
        publishedBy:
          type: string
    RegisterService_QuorumFormula:
      enum:
      - StrictMajority
      - Supermajority
      - Unanimous
      description: Formula used to calculate the quorum threshold for governance proposals
    RegisterService_RegisterAttestation:
      required:
      - role
      - subject
      - publicKey
      - signature
      - algorithm
      - grantedAt
      type: object
      properties:
        role:
          description: Administrative role being attested
          $ref: '#/components/schemas/RegisterRole'
        subject:
          maxLength: 255
          minLength: 0
          type: string
          description: DID or user identifier (e.g., did:sorcha:user-123)
        publicKey:
          type: string
          description: Base64-encoded public key for verification
        signature:
          type: string
          description: Cryptographic signature of the control record hash
        algorithm:
          description: Signature algorithm used
          $ref: '#/components/schemas/SignatureAlgorithm'
        grantedAt:
          type: string
          description: When this role was granted (UTC)
          format: date-time
      description: Cryptographic attestation of an administrative role in a register
    RegisterService_RegisterControlRecord:
      required:
      - registerId
      - name
      - createdAt
      - attestations
      type: object
      properties:
        registerId:
          maxLength: 32
          minLength: 32
          pattern: ^[a-f0-9]{32}$
          type: string
          description: Unique register identifier (GUID without hyphens)
        name:
          maxLength: 38
          minLength: 1
          type: string
          description: Human-readable register name
        description:
          maxLength: 500
          minLength: 0
          type:
          - null
          - string
          description: Purpose and scope of the register
        createdAt:
          type: string
          description: ISO 8601 creation timestamp (UTC)
          format: date-time
        attestations:
          maxItems: 25
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/RegisterAttestation'
          description: Cryptographic attestations of administrative roles
        cryptoPolicy:
          oneOf:
          - type: null
          - description: >-
              Cryptographic policy governing which algorithms are accepted on this register.

              Null for backward compatibility with pre-PQC registers (defaults apply).
            $ref: '#/components/schemas/CryptoPolicy'
        registerPolicy:
          oneOf:
          - type: null
          - description: >-
              Operational policy governing validators, consensus, governance, and leader election.

              Null for backward compatibility with pre-feature registers (defaults apply at read time).
            $ref: '#/components/schemas/RegisterPolicy'
        routingAttestation:
          oneOf:
          - type: null
          - description: >-
              Routing-decision governance policy (Feature 145): the minimum attestation strength the

              register requires on a carried RoutingDecision before its sealing validator

              will accept it. Sibling of CryptoPolicy? RegisterControlRecord.CryptoPolicy. Null defaults to

              AttestationKind.SenderSigned (the v1 baseline). A register can govern itself

              up to AttestationKind.ValidatorReEvaluated / AttestationKind.Proof,

              but those strengths are not yet implemented and the validator refuses them in v1

              (`VAL_ROUTING_002`).
            $ref: '#/components/schemas/AttestationKind'
        validators:
          oneOf:
          - type: null
          - description: >-
              Authorized validator signing keys and threshold parameters.

              Declares which validators are authorized to sign dockets for this register.

              Null for backward compatibility with pre-086 registers only (preproduction, clean break).
            $ref: '#/components/schemas/ValidatorRoster'
        metadata:
          type:
          - null
          - object
          additionalProperties:
            type: string
          description: Additional register metadata (tags, category, etc.)
      description: >-
        Represents a register control record with cryptographic attestations

        establishing administrative control and ownership of a register.
    RegisterService_RegisterLocalRelationship:
      required:
      - registerId
      - roles
      - controlRecordVersion
      - derivedAt
      type: object
      properties:
        registerId:
          type: string
          description: The register this relationship describes.
        roles:
          description: Flag set of attestation + roster roles the local node holds.
          $ref: '#/components/schemas/RegisterRoleSet'
        controlRecordVersion:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Docket number of the control transaction this relationship was derived from.

            Consumers use this to detect stale cached copies after governance ops.
          format: int32
        derivedAt:
          type: string
          description: When this derivation was computed.
          format: date-time
        isOwner:
          type: boolean
          description: True when the node's wallet signed the Owner attestation.
        isAdmin:
          type: boolean
          description: True when the node's wallet signed an Admin attestation.
        isAuditor:
          type: boolean
          description: True when the node's wallet signed an Auditor attestation.
        isDesigner:
          type: boolean
          description: True when the node's wallet signed a Designer attestation.
        isValidator:
          type: boolean
          description: True when the node's validator public key is on the control record's roster.
        isSubscriber:
          type: boolean
          description: >-
            True when the node has no sealing or governance authority for this register —

            i.e. it is not an Owner, Admin, or Validator. Auditor-only and Designer-only nodes

            also report `IsSubscriber == true` because they can neither seal dockets nor

            change governance; operationally they behave as read-only subscribers.
      description: >-
        Derived view of the local node's relationship to a register (Feature 108).

        Not persisted — recomputed from the latest control record on demand and cached

        in-process until the next control-transaction seal on the register.
    RegisterService_RegisterPolicy:
      type: object
      properties:
        version:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Policy version (monotonically increasing). Must be &gt;= 1 and &gt; previous version.
          format: uint32
        governance:
          description: Governance configuration controlling quorum rules and proposal lifecycle.
          $ref: '#/components/schemas/PolicyGovernanceConfig'
        validators:
          description: Validator configuration controlling registration, approval, and operational parameters.
          $ref: '#/components/schemas/PolicyValidatorConfig'
        consensus:
          description: Consensus configuration controlling signature thresholds and docket building.
          $ref: '#/components/schemas/PolicyConsensusConfig'
        leaderElection:
          description: Leader election configuration controlling mechanism, heartbeat, and term duration.
          $ref: '#/components/schemas/PolicyLeaderElectionConfig'
        updatedAt:
          type: string
          description: UTC timestamp when this policy version was last updated.
          format: date-time
        updatedBy:
          type:
          - null
          - string
          description: DID of the participant who last updated this policy. Null for genesis policy.
      description: >-
        Per-register operational policy governing governance, validators, consensus,

        and leader election. Embedded in control transaction payloads and upgradeable

        via governance proposals.
    RegisterService_RegisterPolicyResponse:
      type: object
      properties:
        registerId:
          type: string
        policy:
          $ref: '#/components/schemas/RegisterPolicy'
        isDefault:
          type: boolean
    RegisterService_RegisterPurpose:
      enum:
      - General
      - System
      description: Classification of a register's intended use
    RegisterService_RegisterRole:
      enum:
      - Owner
      - Admin
      - Auditor
      - Designer
      description: Administrative roles within a register
    RegisterService_RegisterRoleSet:
      type: integer
      description: >-
        Flag set of roles the local node holds on a register, derived from the latest

        `RegisterControlRecord` + local identity (wallet addresses + validator key).

        Multiple flags may be set simultaneously — Owner + Validator is the common case

        for a node that created a register and self-rosters as its validator.
    RegisterService_RegisterStatus:
      type: integer
    RegisterService_RegisterSyncState:
      type: integer
      description: >-
        Typed lifecycle for a register's sync state on this installation (Feature 108).

        Replaces the legacy free-text string that lived on RegisterSyncState? Register.SyncState.
    RegisterService_RegisterSyncStateView:
      required:
      - registerId
      - state
      - localHeight
      - networkHeightHighWaterMark
      - distinctPeerObservers
      - lastAdvertAt
      - singlePeerMode
      - lastErrorMessage
      - validatorSnapshot
      type: object
      properties:
        registerId:
          type: string
          description: The register described.
        state:
          description: The derived sync state.
          $ref: '#/components/schemas/RegisterSyncState'
        localHeight:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Latest docket height stored locally.
          format: int64
        networkHeightHighWaterMark:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          description: Highest height claimed by any peer within the staleness window; null when no recent adverts.
          format: int64
        distinctPeerObservers:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Count of distinct peers with observations inside the staleness window.
          format: int32
        lastAdvertAt:
          type:
          - null
          - string
          description: Timestamp of the freshest observation; null when none are fresh.
          format: date-time
        singlePeerMode:
          type: boolean
          description: True when only one peer has been observed — sync confidence is reduced.
        lastErrorMessage:
          type:
          - null
          - string
          description: Populated when RegisterSyncState RegisterSyncStateView.State is RegisterSyncState.Error.
        validatorSnapshot:
          oneOf:
          - type: null
          - description: Populated when the local node is the validator for this register.
            $ref: '#/components/schemas/ValidatorSealingSnapshot'
      description: >-
        Operator-facing view of a register's sync state and the evidence that produced it

        (Feature 108). Returned by `GET /api/registers/{registerId}/sync-state`.
    RegisterService_RegistrationMode:
      enum:
      - Public
      - Consent
      description: Controls how new validators join a register's peer network
    RegisterService_RevocationReason:
      type: integer
    RegisterService_RevokeTransactionRequest:
      type: object
      properties:
        originalTxId:
          type: string
        reason:
          type: string
        supersededByTxId:
          type:
          - null
          - string
        metadata:
          type:
          - null
          - object
          additionalProperties:
            type: string
        signerWalletAddress:
          type:
          - null
          - string
    RegisterService_RoutingDecision:
      type: object
      properties:
        completedActionId:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Gets or sets the identifier of the action this transaction completes.
          format: int32
        nextActions:
          type: array
          items:
            $ref: '#/components/schemas/ActionRef'
          description: >-
            Gets or sets the full set of next actions. Empty means this branch terminates.

            Multiple entries express parallel/fan-out branches (preserved end-to-end, FR-007).
        attestation:
          oneOf:
          - type: null
          - description: Gets or sets the trust attestation for this decision (Entity 2 / FR-009).
            $ref: '#/components/schemas/Attestation'
      description: >-
        A routing decision carried on an action transaction's clear metadata (Feature 145).

        Records the action this transaction completes and the <b>full</b> set of next actions

        (preserving parallel branches), trusted via a pluggable Attestation? RoutingDecision.Attestation.

        Replaces the legacy singular next-action hint (Feature 145 — fully removed).
    RegisterService_SignatureAlgorithm:
      description: Cryptographic signature algorithms supported
    RegisterService_SignedAttestation:
      required:
      - attestationData
      - publicKey
      - signature
      - algorithm
      type: object
      properties:
        attestationData:
          description: The attestation data that was signed
          $ref: '#/components/schemas/AttestationSigningData'
        publicKey:
          type: string
          description: Public key used for signing (Base64)
        signature:
          type: string
          description: Signature of the attestation data hash (Base64)
        algorithm:
          description: Algorithm used for signing
          $ref: '#/components/schemas/SignatureAlgorithm'
      description: A signed attestation from an owner or admin
    RegisterService_TransactionGraphNodeDto:
      required:
      - txId
      - prevTxId
      - senderWallet
      - timeStamp
      - docketNumber
      - blueprintId
      - instanceId
      - transactionType
      type: object
      properties:
        txId:
          type: string
        prevTxId:
          type: string
        senderWallet:
          type: string
        timeStamp:
          type: string
          format: date-time
        docketNumber:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: uint64
        blueprintId:
          type:
          - null
          - string
        instanceId:
          type:
          - null
          - string
        transactionType:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
    RegisterService_TransactionGraphResponse:
      required:
      - registerId
      - nodes
      - totalCount
      - hasMore
      type: object
      properties:
        registerId:
          type: string
        nodes:
          type: array
          items:
            $ref: '#/components/schemas/TransactionGraphNodeDto'
        totalCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int32
        hasMore:
          type: boolean
    RegisterService_TransactionLifecycleStatus:
      type: integer
      description: Lifecycle status of a transaction on the register.
    RegisterService_TransactionMetaData:
      type: object
      properties:
        registerId:
          type: string
          description: Register this transaction belongs to
        transactionType:
          description: Type of transaction
          $ref: '#/components/schemas/TransactionType'
        blueprintId:
          type:
          - null
          - string
          description: Blueprint definition identifier
        instanceId:
          type:
          - null
          - string
          description: Blueprint instance identifier
        actionId:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          description: Current action/step in blueprint
          format: uint32
        routingDecision:
          oneOf:
          - type: null
          - description: >-
              Routing decision carried on this action transaction (Feature 145) — the complete

              next-action set plus its trust attestation, in the clear so every node can advance

              instance control state without decrypting the payload (FR-007/FR-010).
            $ref: '#/components/schemas/RoutingDecision'
        trackingData:
          type:
          - null
          - object
          additionalProperties:
            type: string
          description: Custom tracking data (JSON serialized)
      description: Metadata for blueprint workflow tracking
    RegisterService_TransactionModel:
      required:
      - registerId
      - txId
      - senderWallet
      - signature
      type: object
      properties:
        '@context':
          type:
          - null
          - string
          description: JSON-LD context for semantic web integration
        '@type':
          type:
          - null
          - string
          description: JSON-LD type designation
        '@id':
          type:
          - null
          - string
          description: >-
            JSON-LD universal identifier (DID URI)

            Format: did:sorcha:register:{registerId}/tx/{txId}
        registerId:
          type: string
          description: Register identifier this transaction belongs to
        txId:
          maxLength: 64
          minLength: 64
          type: string
          description: Transaction identifier (64 character hex hash)
        prevTxId:
          maxLength: 64
          minLength: 64
          type: string
          description: Previous transaction ID for blockchain chain
        docketNumber:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          description: Docket number this transaction is sealed in
          format: uint64
        version:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Transaction format version
          format: uint32
        senderWallet:
          type: string
          description: Sender wallet address (Base58 encoded)
        recipientsWallets:
          type: array
          items:
            type: string
          description: Recipient wallet addresses
        timeStamp:
          type: string
          description: Transaction timestamp (UTC)
          format: date-time
        metaData:
          oneOf:
          - type: null
          - description: Blueprint and workflow metadata
            $ref: '#/components/schemas/TransactionMetaData'
        payloadCount:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Number of payloads in transaction
          format: uint64
        payloads:
          type: array
          items:
            $ref: '#/components/schemas/PayloadModel'
          description: Encrypted data payloads
        signature:
          type: string
          description: Cryptographic signature of transaction
      description: Represents a signed transaction in a register with JSON-LD support
    RegisterService_TransactionReceipt:
      required:
      - receiptId
      - transactionId
      - registerId
      - docketNumber
      - merkleRoot
      - inclusionProof
      - signatures
      - sealedAt
      type: object
      properties:
        receiptId:
          type: string
          description: Deterministic receipt ID (SHA-256 hash of receipt content).
        transactionId:
          type: string
          description: Transaction this receipt proves.
        registerId:
          type: string
          description: Register containing the transaction.
        docketNumber:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Docket height where the transaction was sealed.
          format: int64
        merkleRoot:
          type: string
          description: Merkle root of the docket.
        inclusionProof:
          description: Merkle inclusion proof from leaf to root.
          $ref: '#/components/schemas/MerkleInclusionProof'
        signatures:
          type: array
          items:
            $ref: '#/components/schemas/ValidatorSignature'
          description: >-
            Validator signature(s) over receipt content.

            Array format to accommodate future multi-validator consensus (TRUST-6).
        sealedAt:
          type: string
          description: When the docket was confirmed/sealed.
          format: date-time
        version:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Receipt format version.
          format: int32
      description: >-
        A cryptographically signed attestation that a transaction was sealed in a specific docket.

        Immutable once created. Contains an embedded Merkle inclusion proof.
    RegisterService_TransactionStatusResponse:
      required:
      - transactionId
      - status
      type: object
      properties:
        transactionId:
          type: string
          description: The queried transaction ID.
        status:
          description: Current lifecycle status.
          $ref: '#/components/schemas/TransactionLifecycleStatus'
        revocationTxId:
          type:
          - null
          - string
          description: ID of the revocation transaction (if revoked or superseded).
        supersededByTxId:
          type:
          - null
          - string
          description: ID of the replacement transaction (if superseded).
        revokedAt:
          type:
          - null
          - string
          description: When the revocation was sealed (if revoked or superseded).
          format: date-time
        reason:
          oneOf:
          - type: null
          - description: Revocation reason (if revoked or superseded).
            $ref: '#/components/schemas/RevocationReason'
      description: >-
        Derived view of a transaction's lifecycle state, combining active/revoked/superseded

        status with pointers to any revocation or superseding transactions.
    RegisterService_TransactionType:
      type: integer
      description: Represents the type of transaction
    RegisterService_TransitionMode:
      enum:
      - Immediate
      - GracePeriod
      - 
    RegisterService_UpdateRegisterRequest:
      type: object
      properties:
        name:
          type:
          - null
          - string
        status:
          oneOf:
          - type: null
          - $ref: '#/components/schemas/RegisterStatus'
        advertise:
          type:
          - null
          - boolean
    RegisterService_ValidatorEjectionReason:
      enum:
      - Equivocation
      - LivenessTimeout
      - 
    RegisterService_ValidatorKeyInfo:
      required:
      - address
      - publicKey
      - algorithm
      type: object
      properties:
        address:
          type: string
          description: Bech32 wallet address of the validator.
        publicKey:
          type: string
          description: Base64-encoded public key.
        algorithm:
          type: string
          description: Key algorithm (ED25519, NISTP256, RSA4096).
      description: Public key information for a validator, used in verification bundles.
    RegisterService_ValidatorKeyStatus:
      enum:
      - Active
      - Rotated
      - Revoked
      - Ejected
      description: Status of a validator's signing key within the validator roster.
    RegisterService_ValidatorRoster:
      required:
      - validators
      - requiredSignatures
      - version
      type: object
      properties:
        validators:
          type: array
          items:
            $ref: '#/components/schemas/ValidatorRosterEntry'
          description: Authorized validator entries. Must contain at least 1 and at most 10 entries.
        requiredSignatures:
          maximum: 10
          minimum: 1
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Minimum number of valid signatures required per docket.

            Defaults to 1 (single-signer mode). Future n-of-m enforcement

            will use this field without schema changes.
          format: int32
        version:
          maximum: 2147483647
          minimum: 1
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: >-
            Roster version, incremented on each governance update.

            Genesis roster is version 1.
          format: int32
      description: >-
        The collection of authorized validator signing keys for a register,

        plus threshold parameters for future n-of-m signing enforcement.

        Stored in the RegisterControlRecord and updated via governance transactions.
    RegisterService_ValidatorRosterEntry:
      required:
      - validatorId
      - publicKey
      - algorithm
      - derivationContext
      - status
      - authorizedAt
      type: object
      properties:
        validatorId:
          maxLength: 255
          minLength: 1
          type: string
          description: Unique identifier for the validator (wallet address or DID).
        publicKey:
          type: string
          description: >-
            Base64-encoded purpose-derived public key for docket signing.

            This is NOT the system wallet's master key — it is derived via the derivation context.
        algorithm:
          description: Cryptographic algorithm used by this signing key.
          $ref: '#/components/schemas/SignatureAlgorithm'
        derivationContext:
          type: string
          description: >-
            Derivation path or context used to derive this key from the system wallet

            (e.g., "sorcha:docket-signing"). Recorded for auditability.
        status:
          description: Current status of this validator key.
          $ref: '#/components/schemas/ValidatorKeyStatus'
        authorizedAt:
          type: string
          description: When this key was authorized for the register.
          format: date-time
        revokedAt:
          type:
          - null
          - string
          description: When this key was rotated or revoked. Null if still Active.
          format: date-time
        ejectionRef:
          type:
          - null
          - string
          description: >-
            Feature 138 US3 — transaction id of the sealing `control.validator.eject` or

            `control.validator.liveness-violation` that moved this entry to

            ValidatorKeyStatus.Ejected. Null unless ejected. Lets any node trace the

            ejection back to its on-chain evidence.
        ejectionReason:
          oneOf:
          - type: null
          - description: >-
              Feature 138 US3 — why this validator was ejected (`Equivocation` or

              `LivenessTimeout`). Null unless ejected.
            $ref: '#/components/schemas/ValidatorEjectionReason'
      description: >-
        An authorized validator's signing key declaration within a register's control record.

        Each entry represents a single validator and its purpose-derived signing key.
    RegisterService_ValidatorSealingSnapshot:
      required:
      - lastSealedHeight
      - mempoolDepth
      - observedAt
      type: object
      properties:
        lastSealedHeight:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Latest docket height this validator has sealed locally.
          format: int64
        mempoolDepth:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Current unverified-pool depth for this register.
          format: int32
        observedAt:
          type: string
          description: When the snapshot was observed by the validator.
          format: date-time
      description: Point-in-time snapshot of local-validator sealing progress for a register.
    RegisterService_ValidatorSignature:
      required:
      - validatorAddress
      - signatureValue
      - algorithm
      - signedAt
      type: object
      properties:
        validatorAddress:
          type: string
          description: Bech32 wallet address of the signing validator.
        signatureValue:
          type: string
          description: Raw signature bytes (Base64-encoded for serialization).
          format: byte
        algorithm:
          type: string
          description: Signing algorithm (ED25519, NISTP256, RSA4096).
        signedAt:
          type: string
          description: When the signature was produced.
          format: date-time
      description: A validator's cryptographic signature on a receipt.
    RegisterService_VerificationBundle:
      required:
      - transactionId
      - registerId
      - credential
      - receipt
      - revocationStatus
      - exportedAt
      - validatorPublicKeys
      type: object
      properties:
        version:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          description: Bundle format version.
          format: int32
        transactionId:
          type: string
          description: Transaction ID being verified.
        registerId:
          type: string
          description: Register containing the transaction.
        credential:
          description: The verifiable credential / payload data.
          $ref: '#/components/schemas/JsonElement'
        receipt:
          description: Signed receipt with embedded inclusion proof.
          $ref: '#/components/schemas/TransactionReceipt'
        revocationStatus:
          description: Point-in-time revocation status snapshot.
          $ref: '#/components/schemas/TransactionStatusResponse'
        exportedAt:
          type: string
          description: When this bundle was exported.
          format: date-time
        validatorPublicKeys:
          type: array
          items:
            $ref: '#/components/schemas/ValidatorKeyInfo'
          description: Public keys for verifying validator signatures.
      description: >-
        A portable verification bundle for offline credential verification.

        Contains all data needed to verify a credential's authenticity, ledger inclusion,

        and revocation status without network access or register access.
    RegisterService_VerifyInclusionProofRequest:
      required:
      - docketId
      - merkleRoot
      - commitment
      - proofData
      - merkleProofPath
      - verificationKey
      type: object
      properties:
        docketId:
          type: string
        merkleRoot:
          type: string
        commitment:
          type: string
        proofData:
          type: string
        merkleProofPath:
          type: array
          items:
            type: string
        verificationKey:
          type: string
    RegisterService_VerifyMerkleInclusionProofRequest:
      type: object
      properties:
        transactionHash:
          type: string
        merkleRoot:
          type: string
        proofPath:
          type: array
          items:
            $ref: '#/components/schemas/MerkleProofStep'
    RegisterService_VerifyReceiptRequest:
      required:
      - receipt
      - validatorPublicKey
      type: object
      properties:
        receipt:
          $ref: '#/components/schemas/TransactionReceipt'
        validatorPublicKey:
          type: string
    RegisterService_WriteDocketRequest:
      required:
      - docketId
      - docketNumber
      - previousHash
      - docketHash
      - createdAt
      - transactionIds
      - proposerValidatorId
      - merkleRoot
      type: object
      properties:
        docketId:
          type: string
        docketNumber:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int64
        previousHash:
          type:
          - null
          - string
        docketHash:
          type: string
        createdAt:
          type: string
          format: date-time
        transactionIds:
          type: array
          items:
            type: string
        proposerValidatorId:
          type: string
        merkleRoot:
          type: string
        transactions:
          type:
          - null
          - array
          items:
            $ref: '#/components/schemas/TransactionModel'
    PeerService_AdvertiseRegisterRequest:
      type: object
      properties:
        isPublic:
          type: boolean
        name:
          type:
          - null
          - string
        description:
          type:
          - null
          - string
    PeerService_AdvertisementItem:
      type: object
      properties:
        registerId:
          type: string
        name:
          type:
          - null
          - string
        description:
          type:
          - null
          - string
        isPublic:
          type: boolean
        latestVersion:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int64
        latestDocketVersion:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - integer
          - string
          format: int64
      description: A single advertisement entry within a bulk request.
    PeerService_BanRequest:
      type: object
      properties:
        reason:
          type:
          - null
          - string
        durationMinutes:
          pattern: ^-?(?:0|[1-9]\d*)$
          type:
          - null
          - integer
          - string
          format: int32
    PeerService_BulkAdvertiseRequest:
      type: object
      properties:
        advertisements:
          type: array
          items:
            $ref: '#/components/schemas/AdvertisementItem'
        fullSync:
          type: boolean
      description: Request body for bulk advertising multiple registers at once.
    PeerService_SubscribeRequest:
      type: object
      properties:
        mode:
          type: string
tags:
- name: Gateway
  description: API Gateway endpoints for health, stats, and client management
- name: Blueprint API/Blueprints
- name: Blueprint API/Actions
- name: Blueprint API/Health
- name: Blueprint API/Statistics
- name: Blueprint API/Operations
- name: Blueprint API/Rehearsals
- name: Blueprint API/Schemas
- name: Blueprint API/Schema Index
- name: Blueprint API/Sectors
- name: Blueprint API/Provider Health
- name: Blueprint API/Credentials
- name: Blueprint API/StatusLists
- name: Blueprint API/FileChunks
- name: Blueprint API/Presentations
- name: Blueprint API/Templates
- name: Blueprint API/Execution
- name: Blueprint API/Notifications
- name: Blueprint API/Instances
- name: Tenant Service/Passkey
- name: Tenant Service/Auth Methods
- name: Tenant Service/OrgDidDocumentEndpoints
- name: Tenant Service/Dashboard
- name: Tenant Service/Register Subscriptions
- name: Tenant Service/Internal
- name: Tenant Service/Inbox
- name: Tenant Service/Bootstrap
- name: Tenant Service/Organizations
- name: Tenant Service/Participants
- name: Tenant Service/User Profile
- name: Tenant Service/Participants (Service)
- name: Tenant Service/Participants (Internal)
- name: Tenant Service/Authentication
- name: Tenant Service/Auth Challenge
- name: Tenant Service/Password
- name: Tenant Service/Public Passkey Registration
- name: Tenant Service/Public Passkey Authentication
- name: Tenant Service/Service Authentication
- name: Tenant Service/Service Principals
- name: Tenant Service/UserPreferences
- name: Tenant Service/Citizen Wallet Devices
- name: Tenant Service/Persona
- name: Tenant Service/AddressLookup
- name: Tenant Service/TOTP Two-Factor Authentication
- name: Tenant Service/Identity Provider Configuration
- name: Tenant Service/OIDC Authentication
- name: Tenant Service/Social Login
- name: Tenant Service/Platform Settings
- name: Tenant Service/Platform Organisations
- name: Tenant Service/Platform User Management
- name: Tenant Service/Organization Settings
- name: Tenant Service/Domain Restrictions
- name: Tenant Service/Audit Log
- name: Tenant Service/Invitations
- name: Tenant Service/Custom Domain
- name: Tenant Service/PushSubscriptions
- name: Tenant Service/Events
- name: Tenant Service/Register Invitations
- name: Tenant Service/Trust
- name: Tenant Service/EnrolSession
- name: Tenant Service/PairingShortCode
- name: Tenant Service/PairingResumption
- name: Wallet Service/IssuanceKeyEndpoints
- name: Wallet Service/Statistics
- name: Wallet Service/Wallets
- name: Wallet Service/Delegation
- name: Wallet Service/Credentials
- name: Wallet Service/Presentations
- name: Wallet Service/Org Key Management
- name: Wallet Service/IssuanceKey
- name: Wallet Service/FileDownload
- name: Wallet Service/Persona Crypto (Internal)
- name: Wallet Service/Citizen Wallet — Status Lists
- name: Wallet Service/Citizen Wallet
- name: Register Service/Health
- name: Register Service/Registers — Feature 108
- name: Register Service/Verification
- name: Register Service/Revocation
- name: Register Service/Blueprints
- name: Register Service/Sorcha.Register.Service
- name: Register Service/Registers
- name: Register Service/Statistics
- name: Register Service/System Register
- name: Register Service/Register Policy
- name: Register Service/Validator Queries
- name: Register Service/Register Creation
- name: Register Service/Transactions
- name: Register Service/Query
- name: Register Service/Dockets
- name: Register Service/Governance
- name: Register Service/CryptoPolicy
- name: Register Service/Participants
- name: Register Service/ZK Proofs
- name: Register Service/Receipts
- name: Register Service/Admin
- name: Peer Service/Info
- name: Peer Service/Peers
- name: Peer Service/Monitoring
- name: Peer Service/Registers
- name: Peer Service/Management
- name: Peer Service/Health
