openapi: 3.0.3
info:
  title: Truthlocks API
  description: |
    Truthlocks is a universal verification infrastructure for documents, credentials, and digital assets.
    This specification defines the canonical API for interacting with Truthlocks services.

    ## Base URLs
    - **Production**: `https://api.truthlocks.com`
    - **Sandbox**: `https://sandbox-api.truthlocks.com`

    ## Authentication
    - **API Keys**: Use `X-API-Key` header for machine-to-machine operations
    - **Bearer Tokens**: Use `Authorization: Bearer <jwt>` for user-initiated operations

    ## Tenant Identity
    In production, tenant identity is derived from the authenticated context (API key or JWT).
    The `X-Tenant-ID` header is ignored in production to prevent spoofing.
  version: 1.0.0
  contact:
    name: Truthlocks Support
    url: https://truthlocks.com/support
    email: support@truthlocks.com
externalDocs:
  description: Transparency read-only API (separate service spec)
  url: https://github.com/truthlocks/truthlock/blob/main/docs/transparency/openapi.yaml

servers:
  - url: https://api.truthlocks.com
    description: Production API
  - url: https://sandbox-api.truthlocks.com
    description: Sandbox Environment

tags:
  - name: Authentication
    description: API key and token management
  - name: Issuers
    description: Issuer registration and trust management
  - name: Keys
    description: Cryptographic key management for issuers
  - name: Attestations
    description: Attestation lifecycle (mint, revoke, supersede)
  - name: Verification
    description: Attestation verification and proof bundles
  - name: Governance
    description: Issuer governance workflows (admin only)
  - name: Identity
    description: Organization, user, and role management
  - name: Audit
    description: Audit event queries
  - name: Platform
    description: Platform administration (super admin only)
  - name: Platform Review
    description: Staff review workflows for issuer applications
  - name: Tenant Console
    description: Tenant profile and lifecycle endpoints
  - name: Health
    description: Service health and readiness endpoints

components:
  securitySchemes:
    APIKey:
      type: apiKey
      in: header
      name: X-API-Key
      description: API key for machine-to-machine authentication
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT for user-initiated operations

  schemas:
    ErrorEnvelope:
      type: object
      required:
        - code
        - message
        - http_status
      properties:
        code:
          type: string
          description: Machine-readable error code
          enum:
            - AUTH_REQUIRED
            - AUTH_INVALID
            - PERMISSION_DENIED
            - TENANT_IDENTITY_UNVERIFIED
            - NOT_FOUND
            - VALIDATION_ERROR
            - CONFLICT
            - PAYLOAD_TOO_LARGE
            - RATE_LIMIT_EXCEEDED
            - QUOTA_EXCEEDED
            - SERVICE_UNAVAILABLE
            - INTERNAL_ERROR
        message:
          type: string
          description: Human-readable error message
        http_status:
          type: integer
          description: HTTP status code
        retry_after_ms:
          type: integer
          description: Milliseconds to wait before retrying (for rate limits)
        details:
          type: object
          description: Additional error context
      example:
        code: AUTH_REQUIRED
        message: "Authentication required"
        http_status: 401

    Issuer:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
        domain:
          type: string
        status:
          type: string
          enum: [PENDING, APPROVED, SUSPENDED, REVOKED]
        trust_level:
          type: string
          enum: [BASIC, VERIFIED, ENTERPRISE]
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    SigningAlgorithm:
      type: string
      enum: [Ed25519, ES256, ES384, ES512, RS256, RS384, RS512, PS256, PS384, PS512]
      description: Signing algorithm for key generation

    Key:
      type: object
      properties:
        kid:
          type: string
          description: Key identifier
        issuer_id:
          type: string
          format: uuid
        algorithm:
          $ref: '#/components/schemas/SigningAlgorithm'
        public_key:
          type: string
          description: Base64-encoded public key
        status:
          type: string
          enum: [ACTIVE, DISABLED, EXPIRED]
        not_before:
          type: string
          format: date-time
        expires_at:
          type: string
          format: date-time

    Attestation:
      type: object
      properties:
        id:
          type: string
          format: uuid
        issuer_id:
          type: string
          format: uuid
        kid:
          type: string
        status:
          type: string
          enum: [VALID, REVOKED, SUPERSEDED]
        payload:
          type: object
        signature:
          type: string
        log_index:
          type: integer
        created_at:
          type: string
          format: date-time

    ProofBundle:
      type: object
      properties:
        attestation:
          $ref: "#/components/schemas/Attestation"
        issuer:
          $ref: "#/components/schemas/Issuer"
        key:
          $ref: "#/components/schemas/Key"
        inclusion_proof:
          type: object
          properties:
            log_index:
              type: integer
            root_hash:
              type: string
            hashes:
              type: array
              items:
                type: string
        signed_tree_head:
          type: object
          properties:
            tree_size:
              type: integer
            root_hash:
              type: string
            signature:
              type: string

    VerifyRequest:
      type: object
      required:
        - attestation_id
      properties:
        attestation_id:
          type: string
          format: uuid
          description: The unique identifier of the attestation to verify.
        payload_b64url:
          type: string
          description: |
            Base64url-encoded payload for signature verification. If provided, the system verifies
            that the SHA-256 hash of this payload matches the stored payload_hash. Use this to
            confirm you hold the exact original content that was attested.
        document_hash_hex:
          type: string
          description: |
            SHA-256 hex hash of the original document for integrity verification. If provided,
            compared against the stored document_hash. Use this when you want to verify a file's
            integrity without sending the full payload over the wire.

    VerifyResponse:
      type: object
      properties:
        verdict:
          $ref: "#/components/schemas/Verdict"
        valid:
          type: boolean
        details:
          type: object
          properties:
            issuer_id:
              type: string
              format: uuid
            issuer_name:
              type: string
            log_index:
              type: integer
            checked_at:
              type: string
              format: date-time

    Verdict:
      type: string
      enum: [VALID, INVALID, REVOKED, ALTERED, SUPERSEDED, UNKNOWN]
      description: |
        - **VALID**: Signature verified and attestation is active
        - **REVOKED**: Attestation was explicitly revoked
        - **SUPERSEDED**: Attestation replaced by a newer version
        - **ALTERED**: Signature verification failed (tampered)
        - **INVALID**: General validation failure
        - **UNKNOWN**: Attestation not found

    Organization:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
        slug:
          type: string
        status:
          type: string
          enum: [ACTIVE, SUSPENDED]
        created_at:
          type: string
          format: date-time

    User:
      type: object
      properties:
        id:
          type: string
          format: uuid
        org_id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        name:
          type: string
        status:
          type: string
          enum: [ACTIVE, INVITED, SUSPENDED]
        created_at:
          type: string
          format: date-time

    Role:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        permissions:
          type: array
          items:
            type: string

    APIKey:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        prefix:
          type: string
          description: First 8 characters of the key
        status:
          type: string
          enum: [ACTIVE, REVOKED]
        scopes:
          type: array
          items:
            type: string
        daily_quota:
          type: integer
        rate_limit_per_minute:
          type: integer
        created_at:
          type: string
          format: date-time

    AuditEvent:
      type: object
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        actor_id:
          type: string
        actor_type:
          type: string
          enum: [USER, API_KEY, SYSTEM]
        action:
          type: string
        resource_type:
          type: string
        resource_id:
          type: string
        metadata:
          type: object
        timestamp:
          type: string
          format: date-time

    Tenant:
      type: object
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
        slug:
          type: string
        status:
          type: string
          enum: [PENDING, ONBOARDING, ACTIVE, SUSPENDED]
        tier:
          type: string
          enum: [FREE, STARTER, PROFESSIONAL, ENTERPRISE]
        created_at:
          type: string
          format: date-time

paths:
  # ========================================
  # Authentication & API Keys
  # ========================================
  /v1/api-keys:
    get:
      summary: List API Keys
      description: Returns all API keys for the authenticated organization. Secrets are masked.
      tags: [Authentication]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: List of API keys
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/APIKey"
        "401":
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
              example:
                code: AUTH_REQUIRED
                message: "Authentication required"
                http_status: 401
    post:
      summary: Create API Key
      description: Creates a new API key. The secret is returned once and cannot be retrieved again.
      tags: [Authentication]
      security:
        - APIKey: []
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name]
              properties:
                name:
                  type: string
                  description: Human-readable name for the key
                scopes:
                  type: array
                  items:
                    type: string
                  description: Permission scopes (default is wildcard)
            example:
              name: "Production API Key"
              scopes: ["attestations:mint", "attestations:read"]
      responses:
        "201":
          description: API key created
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                  name:
                    type: string
                  secret:
                    type: string
                    description: Full API key (shown once)
              example:
                id: "550e8400-e29b-41d4-a716-446655440000"
                name: "Production API Key"
                secret: "tl_live_abc123xyz789..."

  /v1/api-keys/{id}:
    delete:
      summary: Revoke API Key
      description: Permanently revokes an API key. This action cannot be undone.
      tags: [Authentication]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "204":
          description: API key revoked
        "404":
          description: API key not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"

  # ========================================
  # Issuers & Trust Registry
  # ========================================
  /v1/issuers:
    get:
      summary: List Issuers
      description: Returns all issuers for the authenticated tenant.
      tags: [Issuers]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: List of issuers
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Issuer"
    post:
      summary: Create Issuer
      description: Registers a new issuer. Newly created issuers start in PENDING status.
      tags: [Issuers]
      security:
        - APIKey: []
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name, domain]
              properties:
                name:
                  type: string
                domain:
                  type: string
            example:
              name: "Acme University"
              domain: "acme.edu"
      responses:
        "201":
          description: Issuer created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Issuer"
        "409":
          description: Issuer with this domain already exists
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
              example:
                code: CONFLICT
                message: "Issuer with domain acme.edu already exists"
                http_status: 409

  /v1/issuers/{id}:
    get:
      summary: Get Issuer
      description: Returns details for a specific issuer.
      tags: [Issuers]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Issuer details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Issuer"
        "404":
          description: Issuer not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"

  /v1/issuers/{id}/trust:
    post:
      summary: Mark Issuer Trusted
      description: Marks an issuer as trusted within the tenant's trust registry.
      tags: [Issuers]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Issuer marked as trusted
        "404":
          description: Issuer not found

  /v1/issuers/{id}/keys:
    get:
      summary: List Issuer Keys
      description: Returns all cryptographic keys registered for an issuer.
      tags: [Keys]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: List of keys
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Key"
    post:
      summary: Register Key
      description: Registers a new cryptographic key for an issuer. Only Ed25519 is supported.
      tags: [Keys]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [kid, algorithm, public_key]
              properties:
                kid:
                  type: string
                algorithm:
                  $ref: '#/components/schemas/SigningAlgorithm'
                public_key:
                  type: string
                  description: Base64-encoded public key
                expires_at:
                  type: string
                  format: date-time
            example:
              kid: "ed-key-1"
              algorithm: "Ed25519"
              public_key: "MCowBQYDK2VwAyEA..."
      responses:
        "201":
          description: Key registered
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Key"
        "400":
          description: Invalid algorithm or key format
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
              example:
                code: VALIDATION_ERROR
                message: "Only Ed25519 algorithm is supported"
                http_status: 400

  # ========================================
  # Attestations
  # ========================================
  /v1/attestations:
    get:
      summary: List Attestations
      description: Returns attestations for the authenticated tenant with pagination.
      tags: [Attestations]
      security:
        - APIKey: []
      parameters:
        - name: issuer_id
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
            maximum: 100
        - name: cursor
          in: query
          schema:
            type: string
      responses:
        "200":
          description: List of attestations
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: "#/components/schemas/Attestation"
                  next_cursor:
                    type: string
    post:
      summary: Mint Attestation
      description: |
        Creates a new cryptographically signed attestation.
        Use the `Idempotency-Key` header to ensure safe retries.
      tags: [Attestations]
      security:
        - APIKey: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [issuer_id, kid, alg, schema, claims]
              properties:
                issuer_id:
                  type: string
                  format: uuid
                  description: The UUID of the issuer creating the attestation
                  example: "550e8400-e29b-41d4-a716-446655440000"
                kid:
                  type: string
                  description: Key identifier for the signing key
                  example: "ed-key-1"
                alg:
                  $ref: '#/components/schemas/SigningAlgorithm'
                  description: Cryptographic algorithm used for signing
                  example: "Ed25519"
                schema:
                  type: string
                  description: >
                    Credential schema type (e.g. verifiable-id, passport, degree, aml-kyc).
                    See full list below.
                  enum:
                    - verifiable-id
                    - passport
                    - drivers-license
                    - government-id
                    - self-sovereign-id
                    - employment-verification
                    - professional-role
                    - membership-card
                    - professional-certification
                    - license
                    - accreditation
                    - degree
                    - completion-cert
                    - course-credit
                    - transcript
                    - micro-credential
                    - training-completion
                    - medical-license
                    - dea-registration
                    - board-certification
                    - health-credential
                    - vaccination-record
                    - aml-kyc
                    - security-clearance
                    - sam-gov
                    - jurisdiction-approval
                    - attestation-of-will
                    - bank-verification
                    - credit-attestation
                    - income-verification
                    - skill-badge
                    - competency
                    - industry-cert
                    - product-authenticity
                    - chain-of-custody
                    - origin-verification
                    - custom
                    - attestation
                  example: verifiable-id
                claims:
                  type: object
                  additionalProperties:
                    type: string
                  description: >
                    The structured claims for this credential. Fields depend on the selected schema.
                    See schema catalogue below.
                  example:
                    full_name: ""
                    employee_id: ""
                    department: ""
                    title: ""
                    start_date: ""
                recipient_email:
                  type: string
                  format: email
                  description: >
                    Email address of the credential recipient. When provided, the platform sends
                    a notification email with a link to view the attestation on the consumer portal
                    (verify.truthlocks.com). If the recipient does not have a consumer portal account,
                    they receive an invitation to sign up. This enables B2C credential delivery workflows.
                document_hash:
                  type: string
                  description: >
                    Hex-encoded SHA-256 hash of the document or file being attested. Used for document
                    integrity verification — verifiers can recompute the hash of the original file and
                    compare it against this stored value. If omitted, the system checks for
                    claims.document.sha256 in the payload, and if that is also absent, auto-computes
                    the SHA-256 of the raw payload bytes. For best results, compute the hash client-side
                    before base64url-encoding the payload.
                pack_id:
                  type: string
                  format: uuid
                  description: >
                    UUID of the verification pack to link this attestation to. The pack must be in
                    'active' status. When provided, the pack's verifications_count is automatically
                    incremented. Use this to organize attestations by verification program and track
                    analytics per pack.
                content_type:
                  type: string
                  description: >
                    MIME type of the payload. Supported: application/json (default), application/pdf,
                    image/png, image/jpeg, image/webp, image/tiff, video/mp4, video/webm, audio/mpeg,
                    audio/wav, application/octet-stream. Max payload size: 50 MB.
                  example: "application/json"
      responses:
        "201":
          description: Attestation minted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Attestation"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
        "413":
          description: Payload too large
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
        "429":
          description: Rate limit or quota exceeded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"

  /v1/attestations/mint:
    post:
      summary: Mint Attestation
      description: |
        Legacy alias for `POST /v1/attestations`.
        Kept for backward compatibility and rewritten by the gateway.
      tags: [Attestations]
      security:
        - APIKey: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [issuer_id, kid, alg, schema, claims]
              properties:
                issuer_id:
                  type: string
                  format: uuid
                  description: The UUID of the issuer creating the attestation
                  example: "550e8400-e29b-41d4-a716-446655440000"
                kid:
                  type: string
                  description: Key identifier for the signing key
                  example: "ed-key-1"
                alg:
                  $ref: '#/components/schemas/SigningAlgorithm'
                  description: Cryptographic algorithm used for signing
                  example: "Ed25519"
                schema:
                  type: string
                  description: >
                    Credential schema type (e.g. verifiable-id, passport, degree, aml-kyc).
                    See full list below.
                  enum:
                    - verifiable-id
                    - passport
                    - drivers-license
                    - government-id
                    - self-sovereign-id
                    - employment-verification
                    - professional-role
                    - membership-card
                    - professional-certification
                    - license
                    - accreditation
                    - degree
                    - completion-cert
                    - course-credit
                    - transcript
                    - micro-credential
                    - training-completion
                    - medical-license
                    - dea-registration
                    - board-certification
                    - health-credential
                    - vaccination-record
                    - aml-kyc
                    - security-clearance
                    - sam-gov
                    - jurisdiction-approval
                    - attestation-of-will
                    - bank-verification
                    - credit-attestation
                    - income-verification
                    - skill-badge
                    - competency
                    - industry-cert
                    - product-authenticity
                    - chain-of-custody
                    - origin-verification
                    - custom
                    - attestation
                  example: verifiable-id
                claims:
                  type: object
                  additionalProperties:
                    type: string
                  description: >
                    The structured claims for this credential. Fields depend on the selected schema.
                    See schema catalogue below.
                  example:
                    full_name: ""
                    employee_id: ""
                    department: ""
                    title: ""
                    start_date: ""
                recipient_email:
                  type: string
                  format: email
                  description: >
                    Email address of the credential recipient. When provided, the platform sends
                    a notification email with a link to view the attestation on the consumer portal
                    (verify.truthlocks.com). If the recipient does not have a consumer portal account,
                    they receive an invitation to sign up. This enables B2C credential delivery workflows.
                document_hash:
                  type: string
                  description: >
                    Hex-encoded SHA-256 hash of the document or file being attested. Used for document
                    integrity verification — verifiers can recompute the hash of the original file and
                    compare it against this stored value. If omitted, the system checks for
                    claims.document.sha256 in the payload, and if that is also absent, auto-computes
                    the SHA-256 of the raw payload bytes. For best results, compute the hash client-side
                    before base64url-encoding the payload.
                pack_id:
                  type: string
                  format: uuid
                  description: >
                    UUID of the verification pack to link this attestation to. The pack must be in
                    'active' status. When provided, the pack's verifications_count is automatically
                    incremented. Use this to organize attestations by verification program and track
                    analytics per pack.
                content_type:
                  type: string
                  description: >
                    MIME type of the payload. Supported: application/json (default), application/pdf,
                    image/png, image/jpeg, image/webp, image/tiff, video/mp4, video/webm, audio/mpeg,
                    audio/wav, application/octet-stream. Max payload size: 50 MB.
                  example: "application/json"
      responses:
        "201":
          description: Attestation minted
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Attestation"
              example:
                id: "660e8400-e29b-41d4-a716-446655440001"
                issuer_id: "550e8400-e29b-41d4-a716-446655440000"
                kid: "ed-key-1"
                status: "VALID"
                log_index: 42
                created_at: "2026-01-13T12:00:00Z"
        "400":
          description: Invalid request
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
        "413":
          description: Payload too large
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
              example:
                code: PAYLOAD_TOO_LARGE
                message: "Request body exceeds maximum size of 1MB"
                http_status: 413
        "429":
          description: Rate limit or quota exceeded
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
              example:
                code: RATE_LIMIT_EXCEEDED
                message: "Rate limit exceeded"
                http_status: 429
                retry_after_ms: 60000

  /v1/attestations/{id}:
    get:
      summary: Get Attestation
      description: Returns details for a specific attestation.
      tags: [Attestations]
      security:
        - APIKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Attestation details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Attestation"
        "404":
          description: Attestation not found

  /v1/attestations/{id}/proof-bundle:
    get:
      summary: Get Proof Bundle
      description: |
        Returns a complete proof bundle for offline verification. Includes:
        - The attestation itself
        - Issuer information
        - Public key used for signing
        - Transparency log inclusion proof
        - Signed tree head
      tags: [Verification]
      security:
        - APIKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Proof bundle
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProofBundle"
        "404":
          description: Attestation not found

  /v1/attestations/{id}/revoke:
    post:
      summary: Revoke Attestation
      description: |
        Revokes an attestation, marking it as invalid for future verification.
        This action is recorded in the transparency log and cannot be undone.
      tags: [Attestations]
      security:
        - APIKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
                  description: Optional reason for revocation
            example:
              reason: "Certificate holder no longer employed"
      responses:
        "200":
          description: Attestation revoked
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Attestation"
        "404":
          description: Attestation not found
        "409":
          description: Attestation already revoked

  /v1/attestations/{id}/supersede:
    post:
      summary: Supersede Attestation
      description: |
        Creates a new attestation that supersedes an existing one.
        The original attestation is marked as SUPERSEDED.
      tags: [Attestations]
      security:
        - APIKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [payload]
              properties:
                payload:
                  type: object
                  description: Updated payload for the new attestation
            example:
              payload:
                subject: "user:12345"
                claim: "verified_email"
                value: "newemail@example.com"
      responses:
        "201":
          description: New attestation created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Attestation"

  # ========================================
  # Verification
  # ========================================
  /v1/verify:
    post:
      summary: Verify Attestation
      description: |
        Performs a full cryptographic and status verification of an attestation.

        ## Verdict Truth Table
        | Verdict | Valid | Description |
        |---------|-------|-------------|
        | VALID | true | Signature correct, attestation active |
        | REVOKED | false | Attestation explicitly revoked |
        | SUPERSEDED | false | Replaced by newer attestation |
        | ALTERED | false | Signature verification failed |
        | UNKNOWN | false | Attestation not found |
      tags: [Verification]
      security:
        - APIKey: []
        - {}
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/VerifyRequest"
            example:
              attestation_id: "660e8400-e29b-41d4-a716-446655440001"
              payload_b64url: "eyJzdWJqZWN0IjoiZGlkOnRydXRobG9jazoxMjMiLCJ2ZXJpZmllZCI6dHJ1ZX0"
              document_hash_hex: "a1b2c3d4e5f6..."
      responses:
        "200":
          description: Verification result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/VerifyResponse"
              examples:
                valid:
                  summary: Valid attestation
                  value:
                    verdict: VALID
                    valid: true
                    details:
                      issuer_id: "550e8400-e29b-41d4-a716-446655440000"
                      issuer_name: "Acme University"
                      log_index: 42
                revoked:
                  summary: Revoked attestation
                  value:
                    verdict: REVOKED
                    valid: false
                    details:
                      revoked_at: "2026-01-13T15:00:00Z"
                      reason: "Certificate holder no longer employed"

  # ========================================
  # Governance
  # ========================================
  /v1/governance/issuer-requests:
    get:
      summary: List issuer governance requests
      description: Lists governance requests for issuer approval workflows.
      tags: [Governance]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: Requests listed
          content:
            application/json:
              schema:
                type: object
    post:
      summary: Create issuer governance request
      description: Creates a new governance request for issuer approval/changes.
      tags: [Governance]
      security:
        - APIKey: []
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
      responses:
        "201":
          description: Request created

  /v1/governance/issuer-requests/{requestId}:
    get:
      summary: Get issuer governance request
      tags: [Governance]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: requestId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Request details
        "404":
          description: Request not found

  /v1/governance/issuer-requests/{requestId}/approve:
    post:
      summary: Approve governance request
      description: Marks a governance request as approved.
      tags: [Governance]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: requestId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Request approved
        "403":
          description: Permission denied
        "404":
          description: Request not found

  /v1/governance/issuer-requests/{requestId}/execute:
    post:
      summary: Execute approved governance request
      description: Executes a previously approved governance request.
      tags: [Governance]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: requestId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Request executed
        "403":
          description: Permission denied
        "404":
          description: Request not found

  # ========================================
  # Identity & RBAC
  # ========================================
  /v1/orgs:
    get:
      summary: List Organizations
      description: Returns organizations for the authenticated tenant.
      tags: [Identity]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: List of organizations
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Organization"

  /v1/users:
    get:
      summary: List Users
      description: Returns users for the authenticated organization.
      tags: [Identity]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: List of users
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/User"
    post:
      summary: Invite User
      description: Invites a new user to the organization.
      tags: [Identity]
      security:
        - APIKey: []
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, role_id]
              properties:
                email:
                  type: string
                  format: email
                name:
                  type: string
                role_id:
                  type: string
                  format: uuid
      responses:
        "201":
          description: User invited
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/User"

  /v1/roles:
    get:
      summary: List Roles
      description: Returns available roles for the organization.
      tags: [Identity]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: List of roles
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Role"

  # ========================================
  # Audit
  # ========================================
  /v1/audit:
    get:
      summary: Query Audit Events
      description: Returns audit events for the authenticated tenant.
      tags: [Audit]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: actor_id
          in: query
          schema:
            type: string
        - name: action
          in: query
          schema:
            type: string
        - name: resource_type
          in: query
          schema:
            type: string
        - name: from
          in: query
          schema:
            type: string
            format: date-time
        - name: to
          in: query
          schema:
            type: string
            format: date-time
        - name: limit
          in: query
          schema:
            type: integer
            default: 50
      responses:
        "200":
          description: Audit events
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: "#/components/schemas/AuditEvent"
                  next_cursor:
                    type: string

  # ========================================
  # Platform Administration
  # ========================================
  /v1/platform/tenants:
    get:
      summary: List Tenants
      description: Returns all tenants. Requires platform admin privileges.
      tags: [Platform]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: List of tenants
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Tenant"
        "403":
          description: Platform admin privileges required

  /v1/platform/tenants/{id}/suspend:
    post:
      summary: Suspend Tenant
      description: Suspends a tenant. All API operations by this tenant will be blocked.
      tags: [Platform]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
      responses:
        "200":
          description: Tenant suspended
        "403":
          description: Platform admin privileges required
        "404":
          description: Tenant not found

  /v1/platform/tenants/{id}/reinstate:
    post:
      summary: Reinstate Tenant
      description: Reinstates a suspended tenant.
      tags: [Platform]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Tenant reinstated
        "403":
          description: Platform admin privileges required
        "404":
          description: Tenant not found

  /v1/platform/tenants/{id}/approve:
    post:
      summary: Approve Tenant
      description: Approves a tenant for onboarding (default) or direct activation (override).
      tags: [Platform]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                override:
                  type: boolean
                  description: If true, approve directly to ACTIVE.
                reason:
                  type: string
      responses:
        "200":
          description: Tenant approved
        "409":
          description: Invalid transition
        "404":
          description: Tenant not found

  /v1/platform/review/issuer-applications:
    get:
      summary: List issuer applications for platform review
      tags: [Platform Review]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum: [DRAFT, SUBMITTED, IN_REVIEW, APPROVED, REJECTED, SUSPENDED]
        - name: q
          in: query
          schema:
            type: string
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
        - name: offset
          in: query
          schema:
            type: integer
            default: 0
      responses:
        "200":
          description: Review queue response
          content:
            application/json:
              schema:
                type: object

  /v1/platform/review/issuer-applications/{id}:
    get:
      summary: Get issuer application for review
      tags: [Platform Review]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Application details
        "404":
          description: Application not found

  /v1/platform/review/issuer-applications/{id}/approve:
    post:
      summary: Approve issuer application
      tags: [Platform Review]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
                notes:
                  type: string
      responses:
        "200":
          description: Application approved

  /v1/platform/review/issuer-applications/{id}/reject:
    post:
      summary: Reject issuer application
      tags: [Platform Review]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Application rejected

  /v1/platform/review/issuer-applications/{id}/request-changes:
    post:
      summary: Request changes on issuer application
      tags: [Platform Review]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Changes requested

  /v1/platform/review/issuer-applications/{id}/suspend:
    post:
      summary: Suspend issuer application
      tags: [Platform Review]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Application suspended

  /v1/platform/review/issuer-applications/{id}/reinstate:
    post:
      summary: Reinstate issuer application
      tags: [Platform Review]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Application reinstated

  /v1/tenants/me:
    get:
      summary: Get current tenant profile
      tags: [Tenant Console]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: Tenant profile
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Tenant"
    patch:
      summary: Update current tenant profile
      tags: [Tenant Console]
      security:
        - APIKey: []
        - BearerAuth: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
      responses:
        "200":
          description: Tenant updated

  /v1/tenants/me/activate:
    post:
      summary: Activate tenant after onboarding
      tags: [Tenant Console]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: Tenant activated
        "409":
          description: Invalid transition
        "412":
          description: Prerequisites not met

  # ========================================
  # Health Endpoints
  # ========================================
  /healthz:
    get:
      summary: Health Check
      description: Returns service health status. No authentication required.
      tags: [Health]
      responses:
        "200":
          description: Service is healthy
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum: [ok]
              example:
                status: ok

  /readyz:
    get:
      summary: Readiness Check
      description: Returns service readiness. No authentication required.
      tags: [Health]
      responses:
        "200":
          description: Service is ready
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum: [ready]
        "503":
          description: Service not ready
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    enum: [not_ready]

  # ========================================
  # Attestation Packs (Verification Packs)
  # ========================================
  /v1/attestation-packs:
    get:
      summary: List Verification Packs
      description: Returns all verification packs for the authenticated tenant, including built-in enterprise templates and custom packs.
      tags: [Attestations]
      security:
        - APIKey: []
      responses:
        "200":
          description: List of verification packs
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                          format: uuid
                        tenant_id:
                          type: string
                          format: uuid
                        name:
                          type: string
                        description:
                          type: string
                        category:
                          type: string
                        region:
                          type: string
                        status:
                          type: string
                          enum: [active, inactive, archived]
                        is_template:
                          type: boolean
                        verifications_count:
                          type: integer
                        created_at:
                          type: string
                          format: date-time
                        updated_at:
                          type: string
                          format: date-time
                  total:
                    type: integer
        "401":
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
    post:
      summary: Create Verification Pack
      description: Creates a new custom verification pack for the tenant.
      tags: [Attestations]
      security:
        - APIKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [name]
              properties:
                name:
                  type: string
                description:
                  type: string
                category:
                  type: string
                region:
                  type: string
            example:
              name: "KYC Identity Verification"
              description: "Know Your Customer identity proofing package"
              category: "Identity"
              region: "Global"
      responses:
        "201":
          description: Pack created
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
        "401":
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"

  /v1/attestation-packs/{id}:
    get:
      summary: Get Verification Pack
      description: Returns details of a specific verification pack.
      tags: [Attestations]
      security:
        - APIKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Pack details
          content:
            application/json:
              schema:
                type: object
        "404":
          description: Pack not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"
    put:
      summary: Update Verification Pack
      description: Updates a verification pack's name, description, or configuration.
      tags: [Attestations]
      security:
        - APIKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                description:
                  type: string
                category:
                  type: string
      responses:
        "200":
          description: Pack updated
          content:
            application/json:
              schema:
                type: object

  /v1/attestation-packs/{id}/status:
    put:
      summary: Update Verification Pack Status
      description: Activates, deactivates, or archives a verification pack.
      tags: [Attestations]
      security:
        - APIKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [status]
              properties:
                status:
                  type: string
                  enum: [active, inactive, archived]
      responses:
        "200":
          description: Status updated
          content:
            application/json:
              schema:
                type: object

  # ========================================
  # Consumer (B2C) Endpoints
  # ========================================
  /v1/consumer/signup:
    post:
      summary: Consumer Signup
      description: Creates a new consumer account. No authentication required.
      tags: [Consumer]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, password, name]
              properties:
                email:
                  type: string
                  format: email
                password:
                  type: string
                  format: password
                name:
                  type: string
                signup_type:
                  type: string
                  description: "Set to 'tenant' for console signups"
                company_name:
                  type: string
      responses:
        "201":
          description: Account created
          content:
            application/json:
              schema:
                type: object
                properties:
                  user_id:
                    type: string
                    format: uuid
                  tenant_id:
                    type: string
                    format: uuid
                  session_token:
                    type: string

  /v1/consumer/login:
    post:
      summary: Consumer Login
      description: Authenticates a consumer and returns a session token. No API key required.
      tags: [Consumer]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [email, password]
              properties:
                email:
                  type: string
                  format: email
                password:
                  type: string
                  format: password
            example:
              email: "user@example.com"
              password: "password123"
      responses:
        "200":
          description: Login successful
          content:
            application/json:
              schema:
                type: object
                properties:
                  session_token:
                    type: string
                  user:
                    type: object
                    properties:
                      id:
                        type: string
                        format: uuid
                      email:
                        type: string
                      name:
                        type: string
                      realm:
                        type: string

  /v1/consumer/inbox:
    get:
      summary: Consumer Inbox
      description: Returns pending credential deliveries for the authenticated consumer.
      tags: [Consumer]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: Inbox items
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                  total:
                    type: integer

  /v1/consumer/inbox/deliver:
    post:
      summary: Deliver Credential to Consumer
      description: Delivers an attestation to a consumer's inbox via email address. Requires API key (issuer-facing).
      tags: [Consumer]
      security:
        - APIKey: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [attestation_id, recipient_email]
              properties:
                attestation_id:
                  type: string
                  format: uuid
                recipient_email:
                  type: string
                  format: email
      responses:
        "200":
          description: Delivery queued
          content:
            application/json:
              schema:
                type: object
                properties:
                  delivery_id:
                    type: string
                    format: uuid
                  status:
                    type: string

  /v1/consumer/mint:
    post:
      summary: Protect Content (Consumer Mint)
      description: Mint a cryptographic attestation for content you want to protect. Your personal issuer and signing key are resolved automatically. Hash the content client-side (SHA-256) and submit the hash with file metadata.
      tags: [Consumer]
      security:
        - APIKey: []
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [content_hash]
              properties:
                content_hash:
                  type: string
                  description: SHA-256 hash of the file content, computed client-side.
                title:
                  type: string
                  description: Human-readable title for the protection.
                description:
                  type: string
                  description: Optional description of the protected content.
                content_type:
                  type: string
                  description: MIME type of the content (e.g. image/png).
                file_name:
                  type: string
                  description: Original file name including extension.
                file_size:
                  type: integer
                  description: File size in bytes.
                category:
                  type: string
                  enum: [code, research, design, media, dataset, ai-output, writing, digital-art, other]
                  description: Content category. Defaults to other.
                ai_metadata:
                  type: object
                  description: Optional AI-extracted metadata object.
                visibility:
                  type: string
                  enum: [public, private]
                  description: Whether the protection appears on your public portfolio. Defaults to private.
      responses:
        "201":
          description: Content protected
          content:
            application/json:
              schema:
                type: object
                properties:
                  protection_id:
                    type: string
                    format: uuid
                  attestation_id:
                    type: string
                    format: uuid
                  verify_url:
                    type: string
                    format: uri
                  share_url:
                    type: string
                    format: uri
                  status:
                    type: string
                    enum: [protected]
        "400":
          description: Missing required field
        "401":
          description: Unauthorized
        "429":
          description: Monthly protection limit reached

  /v1/consumer/protections:
    get:
      summary: List Consumer Protections
      description: Returns all content protections (attestations) for the authenticated consumer.
      tags: [Consumer]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: List of protections
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      $ref: "#/components/schemas/Attestation"
                  total:
                    type: integer

  /v1/consumer/portfolio/{username}:
    get:
      summary: Public Portfolio
      description: Returns the public portfolio for a consumer by username. No authentication required.
      tags: [Consumer]
      parameters:
        - name: username
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Public portfolio
          content:
            application/json:
              schema:
                type: object
                properties:
                  username:
                    type: string
                  display_name:
                    type: string
                  items:
                    type: array
                    items:
                      type: object
        "404":
          description: Portfolio not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"

  /v1/consumer/stats:
    get:
      summary: Consumer Stats
      description: Returns statistics for the authenticated consumer's protections and portfolio.
      tags: [Consumer]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: Consumer statistics
          content:
            application/json:
              schema:
                type: object
                properties:
                  total_protections:
                    type: integer
                  total_verifications:
                    type: integer
                  portfolio_views:
                    type: integer

  # ========================================
  # Consumer Privacy
  # ========================================
  /v1/consumer/privacy/export:
    post:
      summary: Request Data Export
      description: Request a full export of all data associated with your account. Exports are delivered in JSON format and include your profile, protections, credentials, and activity history.
      tags: [Consumer]
      security:
        - APIKey: []
        - BearerAuth: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                format:
                  type: string
                  enum: [json]
                  description: Export format. Currently only json is supported.
                reason:
                  type: string
                  description: Optional reason for the export request, recorded in the audit log.
      responses:
        "201":
          description: Export requested
          content:
            application/json:
              schema:
                type: object
                properties:
                  job_id:
                    type: string
                  status:
                    type: string
                    enum: [PENDING]
                  created_at:
                    type: string
                    format: date-time
        "401":
          description: Unauthorized
        "429":
          description: An export is already in progress

  /v1/consumer/privacy/delete-account:
    post:
      summary: Request Account Deletion
      description: Request permanent deletion of your account and all associated data. Deletion requests are processed within 30 days in compliance with data protection regulations.
      tags: [Consumer]
      security:
        - APIKey: []
        - BearerAuth: []
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
                  description: Optional reason for the deletion request, recorded in the audit log.
      responses:
        "201":
          description: Deletion requested
          content:
            application/json:
              schema:
                type: object
                properties:
                  job_id:
                    type: string
                  status:
                    type: string
                    enum: [PENDING]
                  created_at:
                    type: string
                    format: date-time
        "401":
          description: Unauthorized
        "409":
          description: A deletion request is already pending

  /v1/consumer/privacy/jobs:
    get:
      summary: List Privacy Jobs
      description: List all privacy requests for the authenticated consumer. Returns export and deletion jobs sorted by creation date with real-time status updates.
      tags: [Consumer]
      security:
        - APIKey: []
        - BearerAuth: []
      responses:
        "200":
          description: List of privacy jobs
          content:
            application/json:
              schema:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    job_type:
                      type: string
                      enum: [EXPORT, DELETE]
                    target_type:
                      type: string
                    status:
                      type: string
                      enum: [PENDING, APPROVED, PROCESSING, COMPLETED, FAILED, EXPIRED]
                    created_at:
                      type: string
                      format: date-time
                    updated_at:
                      type: string
                      format: date-time
                    reason:
                      type: string
                    result:
                      type: object
                      properties:
                        download_url:
                          type: string
                          format: uri
                        expires_at:
                          type: string
                          format: date-time
        "401":
          description: Unauthorized

  # ========================================
  # Additional Issuer Endpoints
  # ========================================
  /v1/issuers/{id}/events:
    get:
      summary: Issuer Event History
      description: Returns the event history for a specific issuer.
      tags: [Issuers]
      security:
        - APIKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Event list
          content:
            application/json:
              schema:
                type: object
                properties:
                  items:
                    type: array
                    items:
                      type: object
                      properties:
                        event_type:
                          type: string
                        timestamp:
                          type: string
                          format: date-time
                        details:
                          type: object

  /v1/issuers/keys/{kid}/rotate:
    post:
      summary: Rotate Issuer Key
      description: Rotates a cryptographic key, creating a new key and disabling the old one.
      tags: [Keys]
      security:
        - APIKey: []
      parameters:
        - name: kid
          in: path
          required: true
          schema:
            type: string
      responses:
        "200":
          description: Key rotated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Key"

  /v1/issuers/keys/{kid}/compromise:
    post:
      summary: Report Key Compromise
      description: Reports a key as compromised. Immediately disables the key and flags all attestations signed with it for review.
      tags: [Keys]
      security:
        - APIKey: []
      parameters:
        - name: kid
          in: path
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
      responses:
        "200":
          description: Key marked as compromised
          content:
            application/json:
              schema:
                type: object
                properties:
                  kid:
                    type: string
                  status:
                    type: string
                  affected_attestations:
                    type: integer

  # ========================================
  # Additional Audit Endpoints
  # ========================================
  /v1/audit/exports:
    post:
      summary: Create Audit Export
      description: Creates an asynchronous audit event export job.
      tags: [Audit]
      security:
        - APIKey: []
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                start_date:
                  type: string
                  format: date-time
                end_date:
                  type: string
                  format: date-time
                format:
                  type: string
                  enum: [csv, json]
      responses:
        "202":
          description: Export job created
          content:
            application/json:
              schema:
                type: object
                properties:
                  export_id:
                    type: string
                    format: uuid
                  status:
                    type: string

  # ========================================
  # Additional Identity Endpoints
  # ========================================
  /v1/orgs/{id}:
    get:
      summary: Get Organization
      description: Returns details for a specific organization.
      tags: [Identity]
      security:
        - APIKey: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Organization details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Organization"
        "404":
          description: Organization not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorEnvelope"

  # ========================================
  # Additional Governance Endpoints
  # ========================================
  /v1/platform/issuers/{id}/suspend:
    post:
      summary: Suspend Issuer (Platform Admin)
      description: Suspends an issuer at the platform level. Requires platform admin privileges.
      tags: [Platform]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                reason:
                  type: string
      responses:
        "200":
          description: Issuer suspended
          content:
            application/json:
              schema:
                type: object

  # ========================================
  # API Key Revoke
  # ========================================
  /v1/api-keys/{id}/revoke:
    post:
      summary: Revoke API Key
      description: Permanently revokes an API key. This action cannot be undone.
      tags: [Authentication]
      security:
        - APIKey: []
        - BearerAuth: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          description: Key revoked
          content:
            application/json:
              schema:
                type: object
                properties:
                  id:
                    type: string
                    format: uuid
                  status:
                    type: string
                    enum: [REVOKED]
