openapi: 3.1.0
info:
  title: Receipt Authority API
  version: 1.0.0
  description: Provider-neutral authorization and evidence API. No endpoint invokes an external provider or moves funds.
servers:
  - url: https://receiptprotocol.com/api/partner/v1
    description: Receipt Authority API. Test credentials create only test authority. The API represents Test mode with the literal `sandbox` value.
security:
  - PartnerKey: []
paths:
  /action-profiles/validate:
    post:
      operationId: validateActionProfile
      x-receipt-scope: profiles:write
      description: Deterministically validates a compiled language-neutral artifact. Receipt never executes developer code.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [artifact]
              properties: { artifact: { $ref: "#/components/schemas/ActionProfileArtifact" } }
      responses:
        "200": { $ref: "#/components/responses/ActionProfileValidationSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "422": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
  /action-profiles:
    get:
      operationId: listApplicationProfiles
      x-receipt-scope: profiles:read
      description: Lists only profiles owned by the authenticated application.
      responses:
        "200": { $ref: "#/components/responses/ActionProfileListSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
    post:
      operationId: publishTestProfile
      x-receipt-scope: profiles:write
      description: Publishes one immutable Test profile version. This never grants Live access.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [artifact]
              properties: { artifact: { $ref: "#/components/schemas/ActionProfileArtifact" } }
      responses:
        "201": { $ref: "#/components/responses/ActionProfileSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "409": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "422": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
  /action-profiles/{profile_reference}/{profile_version}:
    get:
      operationId: getActionProfile
      x-receipt-scope: profiles:read
      parameters:
        - { $ref: "#/components/parameters/ProfileReference" }
        - { $ref: "#/components/parameters/ProfileVersion" }
      responses:
        "200": { $ref: "#/components/responses/ActionProfileSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
  /action-profiles/{profile_reference}/{profile_version}/retire:
    post:
      operationId: retireTestProfile
      x-receipt-scope: profiles:write
      description: Retires an owned Test profile version without mutating its contract.
      parameters:
        - { $ref: "#/components/parameters/ProfileReference" }
        - { $ref: "#/components/parameters/ProfileVersion" }
      responses:
        "200": { $ref: "#/components/responses/ActionProfileRetirementSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
  /action-profiles/{profile_reference}/{profile_version}/validate-action:
    post:
      operationId: validateActionAgainstProfile
      x-receipt-scope: profiles:read
      parameters:
        - { $ref: "#/components/parameters/ProfileReference" }
        - { $ref: "#/components/parameters/ProfileVersion" }
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [action]
              properties: { action: { type: object, additionalProperties: true } }
      responses:
        "200": { $ref: "#/components/responses/ActionValidationSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "422": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
  /mandate-intents:
    post:
      operationId: createMandateIntent
      x-receipt-scope: mandate_intents:create
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/MandateIntent" }
      responses:
        "201": { $ref: "#/components/responses/MandateIntentSuccess" }
        "400": { $ref: "#/components/responses/Error" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "422": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
  /mandates/{reference}:
    get:
      operationId: getMandate
      x-receipt-scope: mandates:read
      parameters: [{ $ref: "#/components/parameters/Reference" }]
      responses:
        "200": { $ref: "#/components/responses/MandateSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "409": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
  /proposals:
    post:
      operationId: createProposal
      x-receipt-scope: proposals:create
      requestBody:
        required: true
        content:
          application/json:
            schema: { $ref: "#/components/schemas/Proposal" }
      responses:
        "200": { $ref: "#/components/responses/ProposalSuccess" }
        "201": { $ref: "#/components/responses/ProposalSuccess" }
        "400": { $ref: "#/components/responses/Error" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "409": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "422": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
  /decisions/{reference}:
    get:
      operationId: getDecision
      x-receipt-scope: decisions:read
      parameters: [{ $ref: "#/components/parameters/Reference" }]
      responses:
        "200": { $ref: "#/components/responses/DecisionSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
  /approvals/{reference}:
    get:
      operationId: getApproval
      x-receipt-scope: approvals:read
      parameters: [{ $ref: "#/components/parameters/Reference" }]
      responses:
        "200": { $ref: "#/components/responses/ApprovalSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
  /admissions/{reference}/claim:
    post:
      operationId: claimAdmission
      x-receipt-scope: admissions:claim
      parameters: [{ $ref: "#/components/parameters/Reference" }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required:
                [admission, action, provider_reference, agent_connection_reference, idempotency_key]
              properties:
                admission: { $ref: "#/components/schemas/SignedArtifact" }
                action:
                  type: object
                  description: Exact closed action validated against the admission's bound Action Profile.
                  additionalProperties: true
                provider_reference: { type: string }
                agent_connection_reference: { type: string }
                idempotency_key: { type: string, minLength: 8, maxLength: 200 }
      responses:
        "200": { $ref: "#/components/responses/ClaimSuccess" }
        "400": { $ref: "#/components/responses/Error" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "409": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
  /admissions/{reference}/abandon:
    post:
      operationId: abandonAdmission
      x-receipt-scope: admissions:claim
      parameters: [{ $ref: "#/components/parameters/Reference" }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [reason]
              properties:
                reason: { type: string, minLength: 1, maxLength: 200 }
      responses:
        "200": { $ref: "#/components/responses/AbandonSuccess" }
        "400": { $ref: "#/components/responses/Error" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "409": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
  /executions/{reference}/report:
    post:
      operationId: reportExecution
      x-receipt-scope: executions:report
      parameters: [{ $ref: "#/components/parameters/Reference" }]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [event_type, report, idempotency_key]
              properties:
                event_type:
                  enum:
                    [
                      provider_entry,
                      provider_response,
                      observed_effect,
                      indeterminate,
                      complete,
                      definitive_no_effect,
                    ]
                report: { type: object, additionalProperties: true }
                idempotency_key: { type: string, minLength: 8, maxLength: 200 }
      responses:
        "200": { $ref: "#/components/responses/ExecutionReportSuccess" }
        "400": { $ref: "#/components/responses/Error" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "409": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
  /executions/{reference}:
    get:
      operationId: getExecution
      x-receipt-scope: executions:read
      parameters: [{ $ref: "#/components/parameters/Reference" }]
      responses:
        "200": { $ref: "#/components/responses/ExecutionSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
  /reconciliations:
    post:
      operationId: reconcileExecution
      x-receipt-scope: reconciliations:create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [execution_reference, outcome, evidence, idempotency_key]
              properties:
                execution_reference: { type: string }
                outcome: { enum: [confirmed_effect, confirmed_no_effect, still_unknown] }
                evidence: { type: object, additionalProperties: true }
                idempotency_key: { type: string, minLength: 8, maxLength: 200 }
      responses:
        "200": { $ref: "#/components/responses/ReconciliationSuccess" }
        "201": { $ref: "#/components/responses/ReconciliationSuccess" }
        "400": { $ref: "#/components/responses/Error" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "409": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
  /artifacts/{reference}:
    get:
      operationId: getArtifact
      x-receipt-scope: artifacts:read
      parameters: [{ $ref: "#/components/parameters/Reference" }]
      responses:
        "200": { $ref: "#/components/responses/ArtifactSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
  /signing-keys:
    get:
      operationId: getSigningKeys
      x-receipt-scope: artifacts:read
      responses:
        "200": { $ref: "#/components/responses/SigningKeysSuccess" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
  /webhooks:
    put:
      operationId: configureWebhooks
      x-receipt-scope: webhooks:manage
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [url, events]
              properties:
                url: { type: [string, "null"], format: uri }
                events: { type: array, uniqueItems: true, items: { type: string } }
                rotate_secret: { type: boolean, default: false }
      responses:
        "200": { $ref: "#/components/responses/WebhookSuccess" }
        "400": { $ref: "#/components/responses/Error" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
  /credentials/rotate:
    post:
      operationId: rotateCredential
      x-receipt-scope: credentials:rotate
      description: Atomically creates a successor while leaving the authenticating credential active for an explicit cutover. The new secret is returned once; this mutation is never implicitly retried.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              required: [expires_at]
              properties:
                expires_at: { type: [string, "null"], format: date-time }
      responses:
        "201": { $ref: "#/components/responses/CredentialRotationSuccess" }
        "400": { $ref: "#/components/responses/Error" }
        "401": { $ref: "#/components/responses/Error" }
        "403": { $ref: "#/components/responses/Error" }
        "404": { $ref: "#/components/responses/Error" }
        "409": { $ref: "#/components/responses/Error" }
        "413": { $ref: "#/components/responses/Error" }
        "429": { $ref: "#/components/responses/Error" }
        "500": { $ref: "#/components/responses/Error" }
        "503": { $ref: "#/components/responses/Error" }
components:
  securitySchemes:
    PartnerKey:
      type: apiKey
      in: header
      name: X-Receipt-Partner-Key
  parameters:
    Reference:
      name: reference
      in: path
      required: true
      schema: { type: string, minLength: 20, maxLength: 100 }
    ProfileReference:
      name: profile_reference
      in: path
      required: true
      schema: { type: string, pattern: "^[a-z][a-z0-9_]*(\\.[a-z0-9_]+)+$", maxLength: 160 }
    ProfileVersion:
      name: profile_version
      in: path
      required: true
      schema: { type: integer, minimum: 1 }
  responses:
    ActionProfileSuccess:
      description: Exact immutable profile version
      content:
        { application/json: { schema: { $ref: "#/components/schemas/ActionProfileResponse" } } }
    ActionProfileListSuccess:
      description: Tenant-isolated application profile list
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ActionProfileListResponse" }
    ActionProfileValidationSuccess:
      description: Valid compiled profile
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ActionProfileValidationResponse" }
    ActionValidationSuccess:
      description: Action validates against the exact profile version
      content:
        { application/json: { schema: { $ref: "#/components/schemas/ActionValidationResponse" } } }
    ActionProfileRetirementSuccess:
      description: Test profile retired; its immutable contract remains stored
      content:
        {
          application/json:
            { schema: { $ref: "#/components/schemas/ActionProfileRetirementResponse" } },
        }
    MandateIntentSuccess:
      description: Hosted mandate intent created
      content:
        { application/json: { schema: { $ref: "#/components/schemas/MandateIntentResponse" } } }
    MandateSuccess:
      description: Current canonical mandate facade
      content: { application/json: { schema: { $ref: "#/components/schemas/MandateResponse" } } }
    ProposalSuccess:
      description: Canonical proposal decision, including an idempotent replay
      content: { application/json: { schema: { $ref: "#/components/schemas/ProposalResponse" } } }
    DecisionSuccess:
      description: Signed policy decision
      content: { application/json: { schema: { $ref: "#/components/schemas/DecisionResponse" } } }
    ApprovalSuccess:
      description: Exact-action approval state
      content: { application/json: { schema: { $ref: "#/components/schemas/ApprovalResponse" } } }
    ClaimSuccess:
      description: First and only successful provider-entry custody claim
      content: { application/json: { schema: { $ref: "#/components/schemas/ClaimResponse" } } }
    AbandonSuccess:
      description: Unclaimed admission invalidated and reservation released
      content: { application/json: { schema: { $ref: "#/components/schemas/AbandonResponse" } } }
    ExecutionReportSuccess:
      description: Canonical execution report result
      content:
        { application/json: { schema: { $ref: "#/components/schemas/ExecutionReportResponse" } } }
    ExecutionSuccess:
      description: Current execution state and observations
      content: { application/json: { schema: { $ref: "#/components/schemas/ExecutionResponse" } } }
    ReconciliationSuccess:
      description: Canonical reconciliation result or exact replay
      content:
        { application/json: { schema: { $ref: "#/components/schemas/ReconciliationResponse" } } }
    ArtifactSuccess:
      description: Signed authority artifact
      content: { application/json: { schema: { $ref: "#/components/schemas/ArtifactResponse" } } }
    SigningKeysSuccess:
      description: Active public verification keys
      content:
        { application/json: { schema: { $ref: "#/components/schemas/SigningKeysResponse" } } }
    WebhookSuccess:
      description: Webhook endpoint configuration
      content: { application/json: { schema: { $ref: "#/components/schemas/WebhookResponse" } } }
    CredentialRotationSuccess:
      description: Successor credential; secret is returned once
      content:
        {
          application/json: { schema: { $ref: "#/components/schemas/CredentialRotationResponse" } },
        }
    Error:
      description: Fail-closed error
      content:
        application/json:
          schema: { $ref: "#/components/schemas/ErrorResponse" }
  schemas:
    ActionProfileScalarSchema:
      type: object
      additionalProperties: false
      required: [type]
      properties:
        type: { enum: [string, integer, boolean] }
        description: { type: string }
        enum:
          type: array
          minItems: 1
          items: { type: [string, integer, boolean] }
        const: { type: [string, integer, boolean] }
        minLength: { type: integer, minimum: 0 }
        maxLength: { type: integer, minimum: 0 }
        pattern: { type: string }
        format: { const: date-time }
        minimum: { type: integer, minimum: 0 }
        maximum: { type: integer, minimum: 0 }
    ActionProfileActionSchema:
      type: object
      additionalProperties: false
      required: [$schema, type, additionalProperties, required, properties]
      properties:
        $schema: { const: "https://json-schema.org/draft/2020-12/schema" }
        title: { type: string }
        description: { type: string }
        type: { const: object }
        additionalProperties: { const: false }
        required: { type: array, minItems: 1, uniqueItems: true, items: { type: string } }
        properties:
          type: object
          minProperties: 1
          maxProperties: 100
          additionalProperties: { $ref: "#/components/schemas/ActionProfileScalarSchema" }
    ActionProfileDisplayField:
      type: object
      additionalProperties: false
      required: [pointer, label, formatter, accessibility_label]
      properties:
        pointer: { type: string }
        label: { type: string, minLength: 1, maxLength: 80 }
        description: { type: string, maxLength: 300 }
        formatter:
          enum: [text, counterparty, money_minor, currency, provider, timestamp, boolean]
        accessibility_label: { type: string, minLength: 1, maxLength: 160 }
        currency_pointer: { type: string }
    ActionProfileDisplayManifest:
      type: object
      additionalProperties: false
      required: [manifest_version, fields, hidden_pointers]
      properties:
        manifest_version: { const: 1 }
        fields:
          type: array
          minItems: 1
          items: { $ref: "#/components/schemas/ActionProfileDisplayField" }
        hidden_pointers: { type: array, maxItems: 0, items: { type: string } }
    ActionProfilePolicyDimensions:
      type: object
      additionalProperties: false
      required: [amount, currency, counterparty, provider, target]
      properties:
        amount: { type: string }
        currency: { type: string }
        counterparty: { type: string }
        provider: { type: string }
        target: { type: string }
    ActionProfileExpiry:
      type: object
      additionalProperties: false
      required: [pointer, format, comparison, clock]
      properties:
        pointer: { type: string }
        format: { const: date-time }
        comparison: { const: exclusive }
        clock: { const: utc }
    ActionProfileExecution:
      type: object
      additionalProperties: false
      required: [mode, provider_pointer, target_pointer, provider_credentials_in_receipt]
      properties:
        mode: { const: bring_your_own_executor }
        provider_pointer: { type: string }
        target_pointer: { type: string }
        provider_credentials_in_receipt: { const: false }
    ActionProfileReconciliation:
      type: object
      additionalProperties: false
      required: [occurrence_pointer, idempotency_pointer, partner_reported_evidence]
      properties:
        occurrence_pointer: { type: string }
        idempotency_pointer: { type: string }
        partner_reported_evidence: { const: true }
    ActionProfileCanonicalization:
      type: object
      additionalProperties: false
      required: [scheme, object_keys, numbers, strings, unknown_fields]
      properties:
        scheme: { const: receipt.canonical-json.v1 }
        object_keys: { const: lexicographic_utf16 }
        numbers: { const: finite_json_numbers }
        strings: { const: preserve }
        unknown_fields: { const: reject }
    ActionProfileCreationMetadata:
      type: object
      additionalProperties: false
      required: [source, compiler]
      properties:
        source: { enum: [code_first_typescript, receipt_reference_profile] }
        compiler: { type: string, minLength: 1 }
    ActionProfileActivationMetadata:
      type: object
      additionalProperties: false
      required: [mode, activated_at]
      properties:
        mode: { enum: [test_self_service, receipt_live_review] }
        activated_at: { type: string, format: date-time }
    ActionProfileArtifact:
      type: object
      additionalProperties: false
      required:
        [
          artifact_type,
          artifact_version,
          profile_reference,
          profile_version,
          title,
          description,
          action_schema,
          material_field_pointers,
          display_manifest,
          policy_dimensions,
          occurrence_field,
          idempotency_field,
          expiry,
          execution,
          reconciliation,
          profile_environment,
          profile_status,
          canonicalization,
          canonical_profile_hash,
          creation_metadata,
          activation_metadata,
        ]
      properties:
        artifact_type: { const: com.receiptprotocol.action-profile.v1 }
        artifact_version: { const: 1 }
        profile_reference: { type: string }
        profile_version: { type: integer, minimum: 1 }
        title: { type: string, minLength: 1, maxLength: 120 }
        description: { type: string, minLength: 1, maxLength: 1000 }
        action_schema: { $ref: "#/components/schemas/ActionProfileActionSchema" }
        material_field_pointers:
          { type: array, minItems: 1, uniqueItems: true, items: { type: string } }
        display_manifest: { $ref: "#/components/schemas/ActionProfileDisplayManifest" }
        policy_dimensions: { $ref: "#/components/schemas/ActionProfilePolicyDimensions" }
        occurrence_field: { type: string }
        idempotency_field: { type: string }
        expiry: { $ref: "#/components/schemas/ActionProfileExpiry" }
        execution: { $ref: "#/components/schemas/ActionProfileExecution" }
        reconciliation: { $ref: "#/components/schemas/ActionProfileReconciliation" }
        profile_environment: { enum: [test, live] }
        profile_status: { enum: [draft, active, retired] }
        canonicalization: { $ref: "#/components/schemas/ActionProfileCanonicalization" }
        canonical_profile_hash: { type: string, pattern: "^[a-f0-9]{64}$" }
        creation_metadata: { $ref: "#/components/schemas/ActionProfileCreationMetadata" }
        activation_metadata:
          oneOf:
            - { $ref: "#/components/schemas/ActionProfileActivationMetadata" }
            - { type: "null" }
    ActionProfileResponse:
      type: object
      additionalProperties: false
      required:
        [
          profile_reference,
          profile_version,
          profile_environment,
          profile_status,
          canonical_profile_hash,
          title,
          description,
          artifact,
          activated_at,
          retired_at,
          created_at,
        ]
      properties:
        profile_reference: { type: string }
        profile_version: { type: integer, minimum: 1 }
        profile_environment: { enum: [test, live] }
        profile_status: { enum: [active, retired] }
        canonical_profile_hash: { type: string, pattern: "^[a-f0-9]{64}$" }
        title: { type: string }
        description: { type: string }
        artifact: { $ref: "#/components/schemas/ActionProfileArtifact" }
        activated_at: { type: [string, "null"], format: date-time }
        retired_at: { type: [string, "null"], format: date-time }
        created_at: { type: string, format: date-time }
        immutable: { const: true }
        live_access_granted: { const: false }
    ActionProfileListResponse:
      type: object
      additionalProperties: false
      required: [profiles]
      properties:
        profiles: { type: array, items: { $ref: "#/components/schemas/ActionProfileResponse" } }
    ActionProfileValidationResponse:
      type: object
      additionalProperties: false
      required: [valid, canonical_profile_hash, artifact]
      properties:
        valid: { const: true }
        canonical_profile_hash: { type: string, pattern: "^[a-f0-9]{64}$" }
        artifact: { $ref: "#/components/schemas/ActionProfileArtifact" }
    ActionValidationResponse:
      type: object
      additionalProperties: false
      required:
        [
          valid,
          profile_reference,
          profile_version,
          canonical_profile_hash,
          canonical_action,
          canonical_action_hash,
        ]
      properties:
        valid: { const: true }
        profile_reference: { type: string }
        profile_version: { type: integer, minimum: 1 }
        canonical_profile_hash: { type: string, pattern: "^[a-f0-9]{64}$" }
        canonical_action: { type: object, additionalProperties: true }
        canonical_action_hash: { type: string, pattern: "^[a-f0-9]{64}$" }
    ActionProfileRetirementResponse:
      type: object
      additionalProperties: false
      required: [profile_reference, profile_version, profile_status]
      properties:
        profile_reference: { type: string }
        profile_version: { type: integer, minimum: 1 }
        profile_status: { const: retired }
    ErrorResponse:
      type: object
      additionalProperties: false
      required: [error]
      properties:
        error: { type: string }
        details: { type: object, additionalProperties: true }
    MandateIntentResponse:
      type: object
      additionalProperties: false
      required: [intent_reference, hosted_review_url, expires_at, status]
      properties:
        intent_reference: { type: string, pattern: "^mi_" }
        hosted_review_url: { type: string, format: uri }
        expires_at: { type: string, format: date-time }
        status: { const: pending }
    MandateResponse:
      type: object
      additionalProperties: false
      required:
        [
          public_ref,
          application_reference,
          agent_definition_reference,
          agent_reference,
          principal_agent_connection_reference,
          principal_reference,
          agent_connection_reference,
          mandate_reference,
          mandate_version,
          action_profile_reference,
          action_profile_version,
          action_profile_hash,
          environment,
          created_at,
          updated_at,
          status,
          revocation_epoch,
          canonical_authority,
          current_version,
          current_usage,
        ]
      properties:
        public_ref: { type: string, pattern: "^md_" }
        application_reference: { type: string, pattern: "^pt_" }
        agent_definition_reference: { type: string, pattern: "^agd_" }
        agent_reference: { type: string, pattern: "^ag_" }
        principal_agent_connection_reference: { type: string, pattern: "^pac_" }
        principal_reference: { type: string, pattern: "^pr_" }
        agent_connection_reference: { type: string, pattern: "^cn_" }
        mandate_reference: { type: string, pattern: "^md_" }
        mandate_version: { type: integer, minimum: 1 }
        action_profile_reference: { type: string }
        action_profile_version: { type: integer, minimum: 1 }
        action_profile_hash: { type: string, pattern: "^[a-f0-9]{64}$" }
        environment: { enum: [sandbox, production] }
        created_at: { type: string, format: date-time }
        updated_at: { type: string, format: date-time }
        status: { enum: [active, paused, revoked, expired, unavailable] }
        revocation_epoch: { type: [integer, "null"] }
        canonical_authority: { type: [object, "null"], additionalProperties: true }
        current_version: { type: object, additionalProperties: true }
        current_usage:
          type: object
          additionalProperties: false
          required: [spentMinor, reservedMinor, occurrenceCount]
          properties:
            spentMinor: { type: integer, minimum: 0 }
            reservedMinor: { type: integer, minimum: 0 }
            occurrenceCount: { type: integer, minimum: 0 }
    PolicyDisposition:
      enum:
        [
          permitted,
          approval_required,
          denied,
          paused,
          expired,
          revoked,
          insufficient_authority,
          malformed,
          superseded,
          indeterminate,
        ]
    ProposalResponse:
      type: object
      additionalProperties: false
      required:
        [
          proposal_reference,
          policy_decision,
          reason_code,
          decision_record,
          reservation_status,
          approval_status,
          approval,
          execution_admission_status,
          execution_admission,
          evidence_available,
          executed,
        ]
      properties:
        proposal_reference: { type: string, pattern: "^pp_" }
        policy_decision: { $ref: "#/components/schemas/PolicyDisposition" }
        reason_code: { type: string }
        decision_record: { $ref: "#/components/schemas/SignedArtifact" }
        reservation_status: { enum: [reserved, none] }
        approval_status: { enum: [pending, approved, denied, consumed, expired, not_required] }
        approval:
          oneOf:
            - type: "null"
            - type: object
              additionalProperties: false
              required: [approval_reference, expires_at]
              properties:
                approval_reference: { type: string, pattern: "^pa_" }
                approval_url: { type: string, format: uri }
                expires_at: { type: string, format: date-time }
        execution_admission_status: { enum: [issued, none] }
        execution_admission:
          oneOf:
            - type: "null"
            - { $ref: "#/components/schemas/SignedArtifact" }
        evidence_available: { const: true }
        executed: { const: false }
        idempotent_replayed: { const: true }
        issues: { type: array, items: { type: string } }
    DecisionResponse:
      type: object
      additionalProperties: false
      required:
        [public_ref, decision, reason_code, matched_constraint, artifact, expires_at, issued_at]
      properties:
        public_ref: { type: string, pattern: "^pd_" }
        decision: { $ref: "#/components/schemas/PolicyDisposition" }
        reason_code: { type: string }
        matched_constraint: { type: [string, "null"] }
        artifact: { $ref: "#/components/schemas/SignedArtifact" }
        expires_at: { type: string, format: date-time }
        issued_at: { type: string, format: date-time }
    ApprovalResponse:
      type: object
      additionalProperties: false
      required:
        [public_ref, status, approval_artifact, expires_at, approved_at, denied_at, created_at]
      properties:
        public_ref: { type: string, pattern: "^pa_" }
        status: { type: string }
        approval_artifact:
          oneOf:
            - type: "null"
            - { $ref: "#/components/schemas/SignedArtifact" }
        expires_at: { type: string, format: date-time }
        approved_at: { type: [string, "null"], format: date-time }
        denied_at: { type: [string, "null"], format: date-time }
        created_at: { type: string, format: date-time }
    ClaimResponse:
      type: object
      additionalProperties: false
      required: [execution_reference, state, provider_entry_permitted, occurrence_id]
      properties:
        execution_reference: { type: string, pattern: "^ex_" }
        state: { const: invoking }
        provider_entry_permitted: { const: true }
        occurrence_id: { type: string }
    AbandonResponse:
      type: object
      additionalProperties: false
      required: [admission_reference, status, reservation_status, provider_entry_permitted]
      properties:
        admission_reference: { type: string, pattern: "^ea_" }
        status: { const: invalidated }
        reservation_status: { const: released }
        provider_entry_permitted: { const: false }
    ExecutionReportResponse:
      type: object
      additionalProperties: false
      required: [execution_reference, state, outcome_evidence]
      properties:
        execution_reference: { type: string, pattern: "^ex_" }
        state: { type: string }
        outcome_evidence: { $ref: "#/components/schemas/SignedArtifact" }
    ExecutionResponse:
      type: object
      additionalProperties: false
      required: [public_ref, state, provider_ref, occurrence_id, updated_at, created_at]
      properties:
        public_ref: { type: string, pattern: "^ex_" }
        state: { type: string }
        provider_ref: { type: string }
        occurrence_id: { type: string }
        provider_entry_report: { type: [object, "null"], additionalProperties: true }
        provider_response_report: { type: [object, "null"], additionalProperties: true }
        observed_effect_report: { type: [object, "null"], additionalProperties: true }
        provider_entered_at: { type: [string, "null"], format: date-time }
        provider_responded_at: { type: [string, "null"], format: date-time }
        observed_effect_at: { type: [string, "null"], format: date-time }
        indeterminate_at: { type: [string, "null"], format: date-time }
        completed_at: { type: [string, "null"], format: date-time }
        failed_at: { type: [string, "null"], format: date-time }
        updated_at: { type: string, format: date-time }
        created_at: { type: string, format: date-time }
    ReconciliationResponse:
      type: object
      additionalProperties: false
      required:
        [
          reconciliation_reference,
          occurrence_id,
          execution_state,
          provider_reentry_permitted,
          outcome_evidence,
        ]
      properties:
        reconciliation_reference: { type: string, pattern: "^rc_" }
        occurrence_id: { type: string }
        execution_state: { enum: [completed, failed, indeterminate] }
        provider_reentry_permitted: { const: false }
        outcome_evidence: { $ref: "#/components/schemas/SignedArtifact" }
    ArtifactResponse:
      type: object
      additionalProperties: false
      required: [artifact]
      properties: { artifact: { $ref: "#/components/schemas/SignedArtifact" } }
    SigningKeysResponse:
      type: object
      additionalProperties: false
      required: [keys]
      properties:
        keys:
          type: array
          items:
            type: object
            additionalProperties: false
            required: [purpose, environment, key_id, algorithm, public_jwk]
            properties:
              purpose: { type: string }
              environment: { enum: [sandbox, production] }
              key_id: { type: string }
              algorithm: { const: Ed25519 }
              public_jwk: { type: object, additionalProperties: true }
    WebhookResponse:
      type: object
      additionalProperties: false
      required: [webhook_url, events, secret_version]
      properties:
        webhook_url: { type: [string, "null"], format: uri }
        events: { type: array, items: { type: string } }
        secret_version: { type: integer, minimum: 1 }
        signing_secret: { type: string, writeOnly: true }
    CredentialRotationResponse:
      type: object
      additionalProperties: false
      required: [credential_id, secret, expires_at, predecessor_revoked]
      properties:
        credential_id: { type: string, format: uuid }
        secret: { type: string, writeOnly: true }
        expires_at: { type: [string, "null"], format: date-time }
        predecessor_revoked: { const: false }
    SignedArtifact:
      type: object
      required: [type, version, issuer, environment, signature]
      properties:
        type: { type: string }
        version: { type: integer }
        issuer: { type: string, format: uri }
        environment: { enum: [sandbox, production] }
        warning: { type: string }
        signature:
          type: object
          required: [alg, key_id, value]
          properties:
            alg: { const: Ed25519 }
            key_id: { type: string }
            value: { type: string, contentEncoding: base64 }
      additionalProperties: true
    ReferenceAction:
      type: object
      additionalProperties: false
      required:
        [
          action_kind,
          counterparty_ref,
          amount_minor,
          currency,
          execution_provider_ref,
          resource_ref,
          occurrence_id,
          idempotency_key,
          action_expires_at,
        ]
      properties:
        action_kind: { type: string }
        counterparty_ref: { type: string }
        amount_minor: { type: integer, minimum: 0 }
        currency: { type: string, pattern: "^[A-Za-z]{3}$" }
        execution_provider_ref: { type: string }
        resource_ref: { type: string }
        occurrence_id: { type: string }
        idempotency_key: { type: string }
        action_expires_at: { type: string, format: date-time }
    MandateTerms:
      type: object
      additionalProperties: false
      required:
        [
          provider_refs,
          counterparty_refs,
          currency_codes,
          resource_refs,
          daily_limit_minor,
          per_action_limit_minor,
          evidence_requirement_ids,
          effective_at,
          expires_at,
        ]
      properties:
        provider_refs: { type: array, minItems: 1, items: { type: string } }
        counterparty_refs: { type: array, minItems: 1, items: { type: string } }
        currency_codes: { type: array, minItems: 1, items: { type: string } }
        resource_refs: { type: array, items: { type: string } }
        daily_limit_minor: { type: integer, minimum: 0, maximum: 2147483647 }
        per_action_limit_minor: { type: integer, minimum: 0, maximum: 2147483647 }
        evidence_requirement_ids: { type: array, items: { type: string } }
        effective_at: { type: string, format: date-time }
        expires_at: { type: string, format: date-time }
    MandateIntent:
      type: object
      additionalProperties: false
      required:
        [
          partner_reference,
          agent_display_name,
          action_profile_reference,
          action_profile_version,
          terms,
          redirect_uri,
        ]
      properties:
        partner_reference: { type: string }
        agent_display_name: { type: string }
        action_profile_reference: { type: string, maxLength: 160 }
        action_profile_version: { type: integer, minimum: 1 }
        terms: { $ref: "#/components/schemas/MandateTerms" }
        redirect_uri: { type: string, format: uri }
        partner_state_reference: { type: string }
        intent_expires_in_seconds: { type: integer, minimum: 300, maximum: 3600 }
        amendment_of_mandate_reference: { type: string, pattern: "^md_" }
        expected_current_version: { type: integer, minimum: 1 }
    Proposal:
      type: object
      additionalProperties: false
      required:
        [
          partner_reference,
          principal_reference,
          agent_connection_reference,
          mandate_reference,
          expected_mandate_version,
          action_profile_reference,
          action_profile_version,
          proposed_action,
          occurrence_id,
          idempotency_key,
          proposal_expires_at,
        ]
      properties:
        partner_reference: { type: string }
        principal_reference: { type: string }
        agent_connection_reference: { type: string }
        mandate_reference: { type: string }
        expected_mandate_version: { type: integer, minimum: 1 }
        action_profile_reference: { type: string, maxLength: 160 }
        action_profile_version: { type: integer, minimum: 1 }
        proposed_action: { type: object, additionalProperties: true }
        occurrence_id: { type: string }
        idempotency_key: { type: string }
        proposal_expires_at: { type: string, format: date-time }
        partner_metadata: { type: object, additionalProperties: true }
