# Code generated by make generate-api-gateway-spec. DO NOT EDIT.
openapi: 3.0.3
info:
  title: Polygon OMS Public API
  version: v26.11.3-0001
  description: >-
    Unified API for moving money between crypto and fiat. Three ways to move
    money: Transactions (instant, wallet or card funded, including Cash-In for
    in-person cash deposits), Deposit Addresses (reusable crypto deposit
    configurations), and Virtual Accounts (dedicated bank accounts that
    auto-convert fiat to crypto). Standard transactions follow a two-step flow:
    create a Quote (pricing), then create a Transaction (execution). Cash-in
    codes generate a one-time deposit code for in-person cash deposits at retail
    locations.
  contact:
    name: Polygon OMS
    url: 'https://oms.polygon.technology'
servers:
  - url: 'https://sandbox-api.polygon.technology/v0.13'
    description: Sandbox
  - url: 'https://api.polygon.technology/v0.13'
    description: Production
security:
  - BearerAuth: []
tags:
  - name: Auth
    description: Authentication via OMS API key and secret
  - name: Customers
    description: Customer management and KYC
  - name: Customer
  - name: Wallet
  - name: Quote
  - name: Transaction
  - name: Transfer
  - name: CashIns
  - name: CashLocation
  - name: Sandbox
  - name: VirtualAccount
  - name: Counterparty
  - name: ExternalAccount
  - name: Reference
  - name: DepositAddress
  - name: Indexer
    description: >-
      Read token balances, prices, and transaction history across EVM networks,
      Solana, and Tron. Indexer methods are webRPC calls: each is a `POST` with
      a JSON body, served at `/v1/{Service}/{Method}` on the API host rather
      than under the `/v0.13` base path. Authenticate with a publishable key in
      the `Api-Key` header, or with a bearer token from `POST /auth/token`.
paths:
  /risk/config:
    get:
      operationId: getRiskConfig
      summary: Get browser risk configuration
      description: >-
        Returns only provider identifiers for the publishable key's project. No
        customer identity is returned. Missing provisioning returns
        RiskConfigUnavailable.
      security:
        - PublishableKey: []
      responses:
        '200':
          description: Browser provider configuration
          headers:
            Cache-Control:
              schema:
                type: string
                enum:
                  - no-store
          content:
            application/json:
              schema:
                type: object
                additionalProperties: false
                required:
                  - clientId
                  - partnerId
                properties:
                  clientId:
                    type: string
                  partnerId:
                    type: string
        '401':
          description: Invalid or revoked publishable key
        '403':
          description: Publishable key mode does not match the API host
        '429':
          description: Rate limit exceeded
        '503':
          description: Risk configuration unavailable
  /auth/token:
    post:
      tags:
        - Auth
      operationId: authorize
      summary: Get bearer token
      description: >-
        Exchanges an OMS API key + secret for a bearer token valid for 60
        minutes. The token is signed by the OMS issuer and must be presented as
        `Authorization Bearer <token>` on every other endpoint.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AuthorizeRequest'
      responses:
        '200':
          description: Token issued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AuthorizeResponse'
        '400':
          description: Malformed request body
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Invalid or revoked credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: >-
            Too many requests from this client IP. Retry after the interval in
            the `Retry-After` header.
          headers:
            Retry-After:
              description: Seconds to wait before retrying.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      security: []
  '/customers/{customerId}/beneficiaries':
    parameters:
      - name: customerId
        in: path
        required: true
        schema:
          type: string
    post:
      tags:
        - Business onboarding
      operationId: createBusinessBeneficiary
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BusinessBeneficiaryInput'
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '201':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BusinessBeneficiary'
        '400':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    get:
      tags:
        - Business onboarding
      operationId: listBusinessBeneficiaries
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BusinessBeneficiariesList'
        '400':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/customers/{customerId}/beneficiaries/{beneficiaryId}':
    parameters:
      - name: customerId
        in: path
        required: true
        schema:
          type: string
      - name: beneficiaryId
        in: path
        required: true
        schema:
          type: string
    get:
      tags:
        - Business onboarding
      operationId: getBusinessBeneficiary
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BusinessBeneficiary'
        '400':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    put:
      tags:
        - Business onboarding
      operationId: updateBusinessBeneficiary
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BusinessBeneficiaryUpdate'
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BusinessBeneficiary'
        '400':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      tags:
        - Business onboarding
      operationId: deleteBusinessBeneficiary
      responses:
        '204':
          description: Deleted
        '400':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
      parameters:
        - name: version
          in: query
          required: true
          schema:
            type: integer
            minimum: 1
  '/customers/{customerId}/onboardings':
    parameters:
      - name: customerId
        in: path
        required: true
        schema:
          type: string
    post:
      tags:
        - Business onboarding
      operationId: submitCustomerOnboarding
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerOnboardingRequest'
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '201':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerOnboarding'
        '400':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    get:
      tags:
        - Business onboarding
      operationId: listCustomerOnboardings
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerOnboardingsList'
        '400':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/customers/{customerId}/onboardings/{onboardingId}':
    parameters:
      - name: customerId
        in: path
        required: true
        schema:
          type: string
      - name: onboardingId
        in: path
        required: true
        schema:
          type: string
    get:
      tags:
        - Business onboarding
      operationId: getCustomerOnboarding
      responses:
        '200':
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerOnboarding'
        '400':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Request failed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /customers:
    get:
      tags:
        - Customers
      operationId: listCustomers
      summary: List customers
      description: Returns a paginated list of customers under the current Project.
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum:
              - pending
              - actionRequired
              - active
              - rejected
              - offboarded
          description: >-
            Filter by status. Default returns all. A page holds only the
            customers that match, so it can hold fewer than `limit`; keep paging
            while `hasMore` is true.
        - name: email
          in: query
          schema:
            type: string
          description: Filter by exact email match.
        - name: externalId
          in: query
          schema:
            type: string
          description: Filter by externalId.
        - name: createdAfter
          in: query
          schema:
            type: string
            format: date-time
          description: Filter customers created after this timestamp.
        - name: createdBefore
          in: query
          schema:
            type: string
            format: date-time
          description: Filter customers created before this timestamp.
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: cursor
          in: query
          schema:
            type: string
      responses:
        '200':
          description: List of customers
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomersList'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      tags:
        - Customers
      operationId: createCustomer
      summary: Create a customer
      description: >-
        Creation can outlast the request. When it does, the response is 202 with
        the id the customer will have, and the customer reads as 404 until
        creation finishes. Repeat the same request with the same Idempotency-Key
        to follow it: the repeat answers 202 while creation is still running and
        201 with the customer once it is done.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerRequest'
      responses:
        '201':
          description: Customer created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '202':
          description: Customer creation accepted and still running
          headers:
            Retry-After:
              description: Seconds to wait before repeating the request.
              schema:
                type: integer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerCreateAccepted'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/customers/{customerId}':
    get:
      tags:
        - Customers
      operationId: getCustomer
      summary: Get customer by ID
      description: >-
        Returns the customer. List the customer's wallets with GET
        /wallets?customerId={customerId}.
      parameters:
        - name: customerId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Customer details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      tags:
        - Customers
      operationId: updateCustomer
      summary: Update a customer
      description: >-
        Partial update. Only include fields you want to change.
        Compliance-relevant changes (residentialAddress, lastName,
        identifyingInformation, ipAddress) may trigger endorsement
        re-evaluation. Including endorsement names in the endorsements array
        explicitly triggers re-evaluation.
      parameters:
        - name: customerId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CustomerUpdate'
      responses:
        '200':
          description: Customer updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      tags:
        - Customers
      operationId: deleteCustomer
      summary: Delete a customer
      description: >-
        Soft delete. The customer's status becomes offboarded. An offboarded
        customer cannot create new transactions but data is retained for
        compliance purposes.
      parameters:
        - name: customerId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Customer soft-deleted (status offboarded)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Customer'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /webhooks:
    get:
      tags:
        - Webhooks
      operationId: listWebhooks
      summary: List webhooks
      description: >-
        Returns a paginated list of webhooks registered under the current
        Project.
      parameters:
        - name: status
          in: query
          schema:
            $ref: '#/components/schemas/WebhookStatus'
          description: Filter by webhook status.
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: cursor
          in: query
          schema:
            type: string
      responses:
        '200':
          description: List of webhooks
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhooksList'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    post:
      tags:
        - Webhooks
      operationId: createWebhook
      summary: Create a webhook
      description: >-
        Registers an HTTPS endpoint with event subscriptions. The HMAC signing
        key is returned in cleartext once and never again.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookRequest'
      responses:
        '201':
          description: Webhook created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateWebhookResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/webhooks/{webhookId}':
    get:
      tags:
        - Webhooks
      operationId: getWebhook
      summary: Get webhook by ID
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Webhook details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    patch:
      tags:
        - Webhooks
      operationId: updateWebhook
      summary: Update a webhook
      description: >-
        Partial update of URL, subscriptions, timeout, and notify threshold.
        Lifecycle is managed via enable/disable.
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WebhookUpdate'
      responses:
        '200':
          description: Webhook updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
    delete:
      tags:
        - Webhooks
      operationId: deleteWebhook
      summary: Delete a webhook
      description: >-
        Soft delete. The webhook is hidden from List/Get but delivery history is
        retained for the configured retention window.
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Webhook soft-deleted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/webhooks/{webhookId}/rotate-key':
    post:
      tags:
        - Webhooks
      operationId: rotateWebhookKey
      summary: Rotate the signing key
      description: >-
        Issues a new HMAC signing key for the webhook. The cleartext key is
        returned once.
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: New signing key
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RotateWebhookKeyResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/webhooks/{webhookId}/enable':
    post:
      tags:
        - Webhooks
      operationId: enableWebhook
      summary: Enable a webhook
      description: >-
        Reactivates a webhook from any non-enabled state, including suspended.
        Resets the failure/down episode.
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Webhook enabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/webhooks/{webhookId}/disable':
    post:
      tags:
        - Webhooks
      operationId: disableWebhook
      summary: Disable a webhook
      description: Stops dispatch and skips the webhook's queued deliveries. Idempotent.
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Webhook disabled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Webhook'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/webhooks/{webhookId}/test':
    post:
      tags:
        - Webhooks
      operationId: testWebhook
      summary: Send a test delivery
      description: >-
        Synthesizes a test delivery to the registered endpoint so partners can
        verify signature and reachability.
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKey'
      responses:
        '200':
          description: Test delivery created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WebhookDelivery'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/webhooks/{webhookId}/deliveries':
    get:
      tags:
        - Webhooks
      operationId: listWebhookDeliveries
      summary: List deliveries for a webhook
      description: >-
        Returns a paginated list of deliveries for the webhook. Attempts are not
        included; use get-webhook-delivery to expand a delivery with its
        attempts.
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
        - name: status
          in: query
          schema:
            $ref: '#/components/schemas/DeliveryStatus'
        - name: eventId
          in: query
          description: Only deliveries whose `event.id` equals this value.
          schema:
            type: string
        - name: test
          in: query
          schema:
            type: boolean
        - name: createdAfter
          in: query
          schema:
            type: string
            format: date-time
        - name: createdBefore
          in: query
          schema:
            type: string
            format: date-time
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
            maximum: 100
        - name: cursor
          in: query
          schema:
            type: string
      responses:
        '200':
          description: List of deliveries
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeliveriesList'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/webhooks/{webhookId}/deliveries/{deliveryId}':
    get:
      tags:
        - Webhooks
      operationId: getWebhookDelivery
      summary: Get a delivery with its attempts
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
        - name: deliveryId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Delivery with attempts
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetDeliveryResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/webhooks/{webhookId}/deliveries/retry':
    post:
      tags:
        - Webhooks
      operationId: retryWebhookDeliveries
      summary: Retry deliveries
      description: >-
        Re-queues deliveries, resetting failedAttempts to zero. Provide explicit
        deliveryIds, or a status plus a createdAt range to retry all matching
        deliveries. Every retry is audited.
      parameters:
        - name: webhookId
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RetryDeliveriesRequest'
      responses:
        '200':
          description: Retry result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RetryDeliveriesResponse'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/customers/{customerId}/wallets/associate':
    post:
      tags:
        - Wallets
      operationId: associateWallet
      summary: Associate an embedded wallet with a customer
      description: >-
        Links an embedded (WaaS) wallet to the customer. The wallet is
        identified by the supplied WaaS idToken — its subject is the wallet id,
        so the wallet id is never passed directly — and the token's audience
        must be the authenticated project.
      parameters:
        - name: customerId
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKey'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssociateWalletRequest'
      responses:
        '200':
          description: Wallet associated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Wallet'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Not Found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: >-
            Conflict — the wallet is already associated with a different
            customer
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/customers/{customerId}/risk-session':
    post:
      x-internal: true
      tags:
        - Customers
      operationId: createCustomerRiskSession
      summary: Create a customer risk session
      description: >-
        Creates a risk session for the browser SDK. Requires a publishable
        Api-Key together with a customer-bound bearer token from
        /customers/{customerId}/token. Browser requests require a nonempty
        merchant Origin validated against the publishable key's origin policy.
        An empty origin allowlist permits any valid origin. The customer token
        must match the customer, project, and mode. Idempotency-Key presence is
        enforced; responses are not cached by this key.
      security:
        - CustomerTokenAuth: []
          PublishableKeyAuth: []
      parameters:
        - $ref: '#/components/parameters/IdempotencyKey'
        - name: customerId
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCustomerRiskSessionRequest'
      responses:
        '200':
          description: Risk session created
          headers:
            Cache-Control:
              schema:
                type: string
                enum:
                  - no-store
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerRiskSession'
        '400':
          description: 'Invalid fingerprint, customer ID, body, or missing Idempotency-Key'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Missing or invalid credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Customer token scope mismatch
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: 'Customer missing, deleted, or outside the authenticated project'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Too many requests
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: Risk session unavailable
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  '/customers/{customerId}/token':
    post:
      tags:
        - CustomerTokens
      operationId: createCustomerToken
      summary: Create a browser token for a customer
      description: >-
        Issues a short-lived token bound to this customer, the authenticated
        project, and its mode. The token expires after one minute. Fetch it
        immediately before a browser operation; never hand the project token to
        the browser.
      parameters:
        - name: customerId
          in: path
          required: true
          schema:
            type: string
      responses:
        '201':
          description: Customer token issued
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerToken'
        '400':
          description: Bad Request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Forbidden
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Customer not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /cash-ins:
    get:
      operationId: listCashIns
      summary: List cash-ins
      description: >-
        Returns a paginated list of cash-ins, optionally filtered by customer,
        status, type, date range, or free-text search. Results are ordered
        newest-first. Date filters `createdAfter` and `createdBefore` are
        inclusive, matching `GET /transactions`.
      parameters:
        - name: customerId
          in: query
          required: false
          description: Filter to a single customer (`cst_` prefix).
          schema:
            type: string
          explode: false
        - name: status
          in: query
          required: false
          description: Filter by status.
          schema:
            type: string
          explode: false
        - name: type
          in: query
          required: false
          description: Filter by type.
          schema:
            type: array
            items:
              $ref: '#/components/schemas/TransferType'
        - name: createdAfter
          in: query
          required: false
          description: Inclusive lower bound on `createdAt`.
          schema:
            type: string
            format: date-time
        - name: createdBefore
          in: query
          required: false
          description: Inclusive upper bound on `createdAt`.
          schema:
            type: string
            format: date-time
        - name: search
          in: query
          required: false
          description: >-
            Free-text search. Matches cash-in id, customer id, or customer
            email.
          schema:
            type: string
          explode: false
        - name: q
          in: query
          required: false
          description: Alias for `search`.
          schema:
            type: string
          explode: false
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashInList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidCustomerIDErrorResponse'
                  - $ref: '#/components/schemas/InvalidFilterErrorResponse'
                  - $ref: '#/components/schemas/InvalidStatusErrorResponse'
                  - $ref: '#/components/schemas/InvalidCursorErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - CashIns
    post:
      operationId: createCashIn
      summary: Create a cash-in deposit code
      description: >-
        Creates a cash-in: reserves a deposit code the customer presents at a
        physical cash location to deposit fiat, which is then converted to
        crypto and credited to the destination wallet. The 201 response includes
        the cash-in and its deposit instructions (the code and its expiry). Pass
        an Idempotency-Key header to safely retry without creating duplicates.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '201':
          description: >-
            The request has succeeded and a new resource has been created as a
            result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashIn'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidAmountFormatErrorResponse'
                  - $ref: '#/components/schemas/InvalidAssetErrorResponse'
                  - $ref: '#/components/schemas/InvalidLocationErrorResponse'
                  - $ref: '#/components/schemas/InvalidWalletAddressErrorResponse'
                  - $ref: '#/components/schemas/MetadataKeyTooLongErrorResponse'
                  - $ref: '#/components/schemas/MetadataTooManyKeysErrorResponse'
                  - $ref: '#/components/schemas/MetadataValueTooLongErrorResponse'
                  - $ref: '#/components/schemas/MissingCustomerErrorResponse'
                  - $ref: '#/components/schemas/MissingLocationErrorResponse'
                  - $ref: '#/components/schemas/MissingLocationReferenceErrorResponse'
                  - $ref: '#/components/schemas/MissingParameterErrorResponse'
                  - $ref: '#/components/schemas/MissingWalletErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedValueErrorResponse'
                  - $ref: '#/components/schemas/ZeroAddressNotAllowedErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/CustomerNotFoundErrorResponse'
                  - $ref: '#/components/schemas/KYCPendingErrorResponse'
                  - $ref: '#/components/schemas/KYCRequiredErrorResponse'
                  - $ref: '#/components/schemas/WalletNotOwnedErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConcurrentModificationErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AccountHolderUnsupportedErrorResponse'
                  - $ref: '#/components/schemas/BuyNotAllowedAtLocationErrorResponse'
                  - $ref: >-
                      #/components/schemas/CashNotAvailableInCountryErrorResponse
                  - $ref: '#/components/schemas/CashNotAvailableInStateErrorResponse'
                  - $ref: '#/components/schemas/DailyCountExceededErrorResponse'
                  - $ref: '#/components/schemas/DailyLimitExceededErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationInvalidReferenceErrorResponse
                  - $ref: '#/components/schemas/DestinationRequiredErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationWalletMismatchErrorResponse
                  - $ref: >-
                      #/components/schemas/ExternalAccountIDRequiredErrorResponse
                  - $ref: >-
                      #/components/schemas/ExternalAccountNotSupportedErrorResponse
                  - $ref: '#/components/schemas/MemoNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/MonthlyCountExceededErrorResponse'
                  - $ref: '#/components/schemas/MonthlyLimitExceededErrorResponse'
                  - $ref: '#/components/schemas/NoRouteAvailableErrorResponse'
                  - $ref: >-
                      #/components/schemas/ProviderUserAccountNotFoundErrorResponse
                  - $ref: '#/components/schemas/RouteDisabledErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedDestinationErrorResponse'
                  - $ref: '#/components/schemas/ValidationErrorResponse'
                  - $ref: >-
                      #/components/schemas/WalletBoundToCustodialFlowErrorResponse
                  - $ref: '#/components/schemas/WeeklyCountExceededErrorResponse'
                  - $ref: '#/components/schemas/WeeklyLimitExceededErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InternalErrorResponse'
                  - $ref: '#/components/schemas/LimitMisconfiguredErrorResponse'
      tags:
        - CashIns
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCashInRequest'
  '/cash-ins/{cashInId}':
    get:
      operationId: getCashIn
      summary: Get a cash-in by ID
      description: >-
        Retrieves a single cash-in by ID, including its current status and
        sub-status, source and destination amounts, fees, and deposit
        instructions.
      parameters:
        - name: cashInId
          in: path
          required: true
          description: Cash-in ID (`ci_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashIn'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashInNotFoundErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - CashIns
  '/cash-ins/{cashInId}/cancel':
    post:
      operationId: cancelCashIn
      summary: Cancel a cash-in
      description: >-
        Cancels a cash-in that is still `pending`: the deposit code stops
        working and the cash-in becomes `cancelled`, announced by
        `cashIn.statusChanged`. The cancel takes effect only when the provider
        confirms it deleted the code. When the customer scans the code while the
        cancel is in flight, the cash-in becomes `processing` and the request
        fails with 409 `CashInAlreadyScanned`; when the code had already expired
        the cash-in becomes `expired` and the request fails with 409
        `CashInExpired`. A cash-in that is `processing` or already final fails
        with 409 `CashInNotCancellable` and nothing changes. When the provider
        cannot be reached the cash-in stays `pending` and the request can be
        retried. Pass an Idempotency-Key header to safely retry.
      parameters:
        - name: cashInId
          in: path
          required: true
          description: Cash-in ID (`ci_` prefix).
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashIn'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashInNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/CashInAlreadyScannedErrorResponse'
                  - $ref: '#/components/schemas/CashInExpiredErrorResponse'
                  - $ref: '#/components/schemas/CashInNotCancellableErrorResponse'
                  - $ref: '#/components/schemas/ConcurrentModificationErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProjectMissingCoinmeIDErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '502':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProviderRequestFailedErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ProviderTimeoutErrorResponse'
                  - $ref: '#/components/schemas/ProviderUnavailableErrorResponse'
      tags:
        - CashIns
  '/cash-ins/{cashInId}/refresh':
    post:
      operationId: refreshCashIn
      summary: Refresh a cash-in deposit code
      description: >-
        Regenerates the deposit code for an existing cash-in that has not yet
        expired, returning a fresh `cashInCode`. The cash-in's `expiresAt` is
        unchanged, so a refresh does not buy the customer more time; once it has
        passed, the request fails with 422 `RefreshExpired`. Pass an
        Idempotency-Key header to safely retry.


        A per-cash-in refresh guard returns 429 when the total-refresh cap is
        hit (`RefreshLimitReached`) or when refreshed inside the minimum
        interval (`RefreshTooFrequent`, with a `Retry-After` header) —
        protecting the upstream provider and bounding stored refresh history.
      parameters:
        - name: cashInId
          in: path
          required: true
          description: Cash-in ID (`ci_` prefix).
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashIn'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidStatusErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashInNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConcurrentModificationErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RefreshExpiredErrorResponse'
        '429':
          description: >-
            The cash-in cannot be refreshed because it reached the refresh limit
            or was refreshed too recently.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/RefreshLimitReachedErrorResponse'
                  - $ref: '#/components/schemas/RefreshTooFrequentErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '502':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProviderRefreshFailedErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ProviderTimeoutErrorResponse'
                  - $ref: '#/components/schemas/ProviderUnavailableErrorResponse'
      tags:
        - CashIns
  '/cash-ins/{cashInId}/simulate/cancel':
    post:
      operationId: simulateCashInCancel
      summary: Simulate cash-in cancel
      description: >-
        Simulate the customer cancelling the authorization before handing over
        the cash (sandbox only). Once the cash was deposited the call is refused
        with 409 `CashInAlreadyDeposited`.
      parameters:
        - name: cashInId
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SimulateCashInCancelResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashInAlreadyDepositedErrorResponse'
      tags:
        - Sandbox
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimulateCashInCancelRequest'
      x-server-scope: non-prod-live
  '/cash-ins/{cashInId}/simulate/deposit-cash':
    post:
      operationId: simulateCashInDepositCash
      summary: Simulate cash-in deposit cash
      description: >-
        Simulate the customer handing over the cash, completing the authorized
        deposit (sandbox only).
      parameters:
        - name: cashInId
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SimulateCashInDepositCashResponse'
      tags:
        - Sandbox
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimulateCashInDepositCashRequest'
      x-server-scope: non-prod-live
  '/cash-ins/{cashInId}/simulate/present-code':
    post:
      operationId: simulateCashInPresentCode
      summary: Simulate cash-in present code
      description: >-
        Simulate the customer presenting their cash-in code at the register
        (sandbox only). A code the provider deleted or replaced is refused with
        409 `CashInBarcodeInvalid`.
      parameters:
        - name: cashInId
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SimulateCashInPresentCodeResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashInBarcodeInvalidErrorResponse'
      tags:
        - Sandbox
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimulateCashInPresentCodeRequest'
      x-server-scope: non-prod-live
  /cash-locations:
    get:
      operationId: listCashLocations
      summary: List cash locations
      description: >-
        Returns cash pickup and deposit locations for the given provider within
        range of the supplied coordinates, each with its distance from that
        point. Use the flow parameter to select the cash-in or cash-out provider
        configuration. One provider query returns up to the configured maximum
        number of locations; the list pages over that answer, nearest first.
      parameters:
        - name: provider
          in: query
          required: true
          description: Cash provider configuration to query.
          schema:
            type: string
        - name: latitude
          in: query
          required: true
          description: Search-center latitude in decimal degrees.
          schema:
            type: number
            format: double
        - name: longitude
          in: query
          required: true
          description: Search-center longitude in decimal degrees.
          schema:
            type: number
            format: double
        - name: radius
          in: query
          required: false
          description: >-
            Search radius around the given coordinates in miles. Must be greater
            than 0 and at most 100.
          schema:
            type: number
            format: double
            minimum: 0
            exclusiveMinimum: true
            maximum: 100
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: flow
          in: query
          required: false
          description: 'Flow type: determines which provider config to use.'
          schema:
            $ref: '#/components/schemas/CashFlow'
        - name: customerId
          in: query
          required: false
          description: >-
            Optional customer id. When supplied, results are filtered to
            locations the customer is eligible to use (matching their KYC
            country and, for US customers, their registered state), so
            ineligible locations are never offered. Omit to return all locations
            in range unfiltered.
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CashLocationList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidParameterErrorResponse'
                  - $ref: '#/components/schemas/InvalidProviderErrorResponse'
                  - $ref: '#/components/schemas/InvalidCursorErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerNotFoundErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProviderUnavailableErrorResponse'
      tags:
        - CashLocation
  /counterparties:
    get:
      operationId: listCounterparties
      summary: List Counterparties
      description: >-
        List Counterparties. `customerId` is an optional filter — omit it to
        list all counterparties in the project (still tenant-scoped by project).
      parameters:
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: customerId
          in: query
          required: false
          description: Filter to a single customer (`cst_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CounterpartyList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidCursorErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - Counterparty
    post:
      operationId: createCounterparty
      summary: Create a Counterparty
      description: Create a Counterparty.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '201':
          description: >-
            The request has succeeded and a new resource has been created as a
            result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Counterparty'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidMetadataErrorResponse'
                  - $ref: '#/components/schemas/MetadataKeyTooLongErrorResponse'
                  - $ref: '#/components/schemas/MetadataTooManyKeysErrorResponse'
                  - $ref: '#/components/schemas/MetadataValueTooLongErrorResponse'
                  - $ref: '#/components/schemas/MissingParameterErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AccountHolderUnsupportedErrorResponse'
                  - $ref: '#/components/schemas/AccountNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/AccountTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/AddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/BICInvalidErrorResponse'
                  - $ref: '#/components/schemas/BlockchainAddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/CardMustUseCardEndpointErrorResponse'
                  - $ref: '#/components/schemas/CountryInvalidErrorResponse'
                  - $ref: '#/components/schemas/CustodianInvalidErrorResponse'
                  - $ref: '#/components/schemas/DateOfBirthInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationInvalidReferenceErrorResponse
                  - $ref: '#/components/schemas/DestinationRequiredErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/EmailInvalidErrorResponse'
                  - $ref: '#/components/schemas/EntityTypeInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExpectedSourceAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/ExpectedSourceNetworkUnsupportedErrorResponse
                  - $ref: '#/components/schemas/ExpectedSourceRequiredErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExternalAccountIDRequiredErrorResponse
                  - $ref: '#/components/schemas/IBANInvalidErrorResponse'
                  - $ref: '#/components/schemas/InstitutionNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/MemoNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/NameInvalidErrorResponse'
                  - $ref: '#/components/schemas/NationalityInvalidErrorResponse'
                  - $ref: '#/components/schemas/NetworkFamilyInvalidErrorResponse'
                  - $ref: '#/components/schemas/NoRouteAvailableErrorResponse'
                  - $ref: '#/components/schemas/OtherCustodianRequiredErrorResponse'
                  - $ref: '#/components/schemas/OtherCustodianTooLongErrorResponse'
                  - $ref: '#/components/schemas/OwnerInvalidErrorResponse'
                  - $ref: '#/components/schemas/PhoneInvalidErrorResponse'
                  - $ref: '#/components/schemas/RouteDisabledErrorResponse'
                  - $ref: '#/components/schemas/RoutingNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/TaxIDInvalidErrorResponse'
                  - $ref: '#/components/schemas/TransitNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/TypeUnsupportedErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedDestinationErrorResponse'
                  - $ref: '#/components/schemas/ValidationErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
      tags:
        - Counterparty
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CounterpartyCreateRequest'
  '/counterparties/{counterpartyId}':
    delete:
      operationId: deleteCounterparty
      summary: Delete a Counterparty
      description: >-
        Delete a Counterparty (soft delete). Returns 409 when the counterparty
        still owns active or pending External Accounts.
      parameters:
        - name: counterpartyId
          in: path
          required: true
          description: Counterparty ID (`ctp_` prefix).
          schema:
            type: string
      responses:
        '204':
          description: >-
            There is no content to send for this request, but the headers may be
            useful.
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CounterpartyNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/CounterpartyHasActiveExternalAccountsErrorResponse
                  - $ref: '#/components/schemas/VersionConflictErrorResponse'
      tags:
        - Counterparty
    get:
      operationId: getCounterparty
      summary: Get a Counterparty
      description: Get a Counterparty by id.
      parameters:
        - name: counterpartyId
          in: path
          required: true
          description: Counterparty ID (`ctp_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Counterparty'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CounterpartyNotFoundErrorResponse'
      tags:
        - Counterparty
    patch:
      operationId: updateCounterparty
      summary: Update a Counterparty
      description: Update a Counterparty (partial; unknown keys 400).
      parameters:
        - name: counterpartyId
          in: path
          required: true
          description: Counterparty ID (`ctp_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Counterparty'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidMetadataErrorResponse'
                  - $ref: '#/components/schemas/MetadataKeyTooLongErrorResponse'
                  - $ref: '#/components/schemas/MetadataTooManyKeysErrorResponse'
                  - $ref: '#/components/schemas/MetadataValueTooLongErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CounterpartyNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VersionConflictErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/CountryInvalidErrorResponse'
                  - $ref: '#/components/schemas/DateOfBirthInvalidErrorResponse'
                  - $ref: '#/components/schemas/EmailInvalidErrorResponse'
                  - $ref: '#/components/schemas/EmptyUpdateErrorResponse'
                  - $ref: '#/components/schemas/EntityTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/NameInvalidErrorResponse'
                  - $ref: '#/components/schemas/NationalityInvalidErrorResponse'
                  - $ref: '#/components/schemas/PhoneInvalidErrorResponse'
                  - $ref: '#/components/schemas/TaxIDInvalidErrorResponse'
      tags:
        - Counterparty
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CounterpartyUpdateRequest'
  '/customers/{id}/balance':
    get:
      operationId: getCustomerBalance
      summary: Get customer balance
      description: >-
        Get the aggregated estimated balance across all customer wallets/assets.
        The project's enabled providers decide which balances are read:
        custodial crypto balances only when the project has the custodial
        provider, and fiat wallet balances only when it has the fiat bank. A
        project configured with no provider is refused with
        `vendorConfigMissing`.
      parameters:
        - name: id
          in: path
          required: true
          description: Customer ID (`cst_` prefix).
          schema:
            type: string
        - name: estimatedBalanceCurrencyCode
          in: query
          required: false
          description: ISO 4217 currency for the estimated value. Defaults to USD.
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerBalanceAggregate'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidParamsErrorResponse'
                  - $ref: '#/components/schemas/CustomerRejectedErrorResponse'
                  - $ref: '#/components/schemas/InvalidCustomerIDErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/VendorConfigMissingErrorResponse'
                  - $ref: '#/components/schemas/KYCRequiredErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AccountNotFoundErrorResponse'
                  - $ref: '#/components/schemas/PaymentMethodNotFoundErrorResponse'
                  - $ref: '#/components/schemas/WalletCustomerNotFoundErrorResponse'
        '409':
          description: The provider quote expired before the wallet request completed.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/WalletQuoteExpiredErrorResponse'
                  - $ref: '#/components/schemas/WalletProviderConflictErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/ProviderUserAccountNotFoundErrorResponse
                  - $ref: '#/components/schemas/InsufficientFundsErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedCorridorErrorResponse'
                  - $ref: '#/components/schemas/WalletProviderRejectedErrorResponse'
        '429':
          description: The provider's wallet request limit was exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletProviderRateLimitErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '502':
          description: Server error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ProviderErrorResponse'
                  - $ref: '#/components/schemas/ProviderRequestFailedErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
                  - $ref: '#/components/schemas/ProviderTimeoutErrorResponse'
                  - $ref: '#/components/schemas/ProviderUnreachableErrorResponse'
      tags:
        - Customer
  '/customers/{id}/wallets':
    get:
      operationId: listCustomerWallets
      summary: 'List customer wallets (deprecated, use GET /wallets?customerId=)'
      description: >-
        Lists the crypto wallets provisioned for a customer (one per
        asset/chain). Returns an empty list if none have been provisioned yet.


        Deprecated — use `GET /wallets?customerId=` instead. Every response,
        success and error alike, carries `Deprecation` and `Sunset` headers as
        HTTP-dates; `Sunset` is the date this route is removed. Migrating is not
        a byte-for-byte swap. This route and `GET /wallets?customerId=` make the
        same per-request provider calls for the customer, as long as the flat
        one is called without a `type` filter, so what differs is the outcome
        when the wallet-list refresh fails: here everything except a provider
        outage surfaces as a 4xx or 5xx, while the flat route answers 200 with
        the records OMS holds however that refresh fails. Without balance
        ordering, a failed stored-balance read returns the balances available to
        the service. With `orderBy=balance`, failure to load stored balances or
        token decimal metadata returns 500 on either route. `orderBy=balance`
        sorts available balances by their estimated USD value, with balances
        lacking an estimate last; `order` selects `asc` or `desc` and defaults
        to `desc`. Rows here also leave `customerId` unset, since the customer
        is already the path segment.
      parameters:
        - name: id
          in: path
          required: true
          description: Customer ID (`cst_` prefix).
          schema:
            type: string
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: search
          in: query
          required: false
          description: Free-text search. Matches wallet id or on-chain address.
          schema:
            type: string
        - name: q
          in: query
          required: false
          description: Alias for `search`.
          schema:
            type: string
        - name: orderBy
          in: query
          required: false
          description: Order by available balance's estimated USD value.
          schema:
            $ref: '#/components/schemas/WalletListOrderBy'
        - name: order
          in: query
          required: false
          description: >-
            Balance sort direction. Defaults to `desc`; requires
            `orderBy=balance`.
          schema:
            $ref: '#/components/schemas/WalletListOrderDirection'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerWalletList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidCursorErrorResponse'
                  - $ref: '#/components/schemas/InvalidCustomerIDErrorResponse'
                  - $ref: '#/components/schemas/InvalidParamsErrorResponse'
                  - $ref: '#/components/schemas/CustomerRejectedErrorResponse'
                  - $ref: '#/components/schemas/InvalidParameterErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KYCRequiredErrorResponse'
        '404':
          description: A customer could not be found within the wallet's project.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/WalletCustomerNotFoundErrorResponse'
                  - $ref: '#/components/schemas/AccountNotFoundErrorResponse'
                  - $ref: '#/components/schemas/PaymentMethodNotFoundErrorResponse'
        '409':
          description: The provider quote expired before the wallet request completed.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/WalletQuoteExpiredErrorResponse'
                  - $ref: '#/components/schemas/WalletProviderConflictErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/ProviderUserAccountNotFoundErrorResponse
                  - $ref: '#/components/schemas/InsufficientFundsErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedCorridorErrorResponse'
                  - $ref: '#/components/schemas/WalletProviderRejectedErrorResponse'
                  - $ref: '#/components/schemas/ProjectMissingCoinmeIDErrorResponse'
        '429':
          description: The provider's wallet request limit was exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletProviderRateLimitErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '502':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProviderRequestFailedErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
                  - $ref: '#/components/schemas/ProviderTimeoutErrorResponse'
                  - $ref: '#/components/schemas/ProviderUnreachableErrorResponse'
      tags:
        - Wallet
      deprecated: true
      x-deprecated-reason: Use GET /wallets?customerId= instead
    post:
      operationId: createCustomerWallet
      summary: 'Create a new wallet asset for a customer (deprecated, use POST /wallets)'
      description: >-
        Provisions a crypto wallet for a customer for the requested asset and
        chain, returning the created wallet. Pass an `Idempotency-Key` header to
        safely retry without provisioning duplicates.


        Deprecated — use `POST /wallets` with `type: custodial` instead. Every
        response, success and error alike, carries `Deprecation` and `Sunset`
        headers as HTTP-dates; `Sunset` is the date this route is removed.
      parameters:
        - name: id
          in: path
          required: true
          description: Customer ID (`cst_` prefix).
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '201':
          description: >-
            The request has succeeded and a new resource has been created as a
            result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BpnWallet'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/CryptoCustodyInactiveErrorResponse'
                  - $ref: '#/components/schemas/WalletInvalidRequestBodyErrorResponse'
                  - $ref: '#/components/schemas/InvalidCustomerIDErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/KYCRequiredErrorResponse'
        '404':
          description: A customer could not be found within the wallet's project.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/WalletCustomerNotFoundErrorResponse'
                  - $ref: '#/components/schemas/WalletResourceNotFoundErrorResponse'
        '413':
          description: Client error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestTooLargeErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ProjectMissingCoinmeIDErrorResponse'
                  - $ref: >-
                      #/components/schemas/ProviderUserAccountNotFoundErrorResponse
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - Wallet
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WalletCreateRequest'
      deprecated: true
      x-deprecated-reason: Use POST /wallets instead
  /deposit-addresses:
    get:
      operationId: listDepositAddresses
      summary: List all Deposit Addresses
      description: >-
        List all Deposit Addresses across the organization. Spans every customer
        in the caller's organization; optionally filter by status and/or
        customer. `closed` Deposit Addresses are omitted unless you ask for them
        explicitly with `status=closed`.
      parameters:
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: status
          in: query
          required: false
          description: >-
            Filter by status. Omitting this parameter returns every status
            **except** `closed`, which is terminal and permanent; pass
            `status=closed` to list closed Deposit Addresses. A closed Deposit
            Address is not deleted — it stays retrievable by id.
          schema:
            $ref: '#/components/schemas/DepositAddressStatus'
        - name: customerId
          in: query
          required: false
          description: Filter to a single customer (`cst_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DepositAddressList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidCursorErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - DepositAddress
    post:
      operationId: createDepositAddress
      summary: Create a Deposit Address
      description: >-
        Create a Deposit Address. Requires deposit addresses to be enabled for
        your project and the customer to be provisioned with the banking
        provider. The address starts `pending` and becomes `active` once the
        inbound on-chain address is assigned.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '201':
          description: >-
            The request has succeeded and a new resource has been created as a
            result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DepositAddress'
              example:
                id: da_jts3wrvsp6dz04fntj1v4g3hyy
                customer:
                  id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                status: pending
                depositInstructions:
                  asset: usdc
                  network: ethereum
                destination:
                  type: bankUs
                  id: ext_cc35pa5vgrq1tpsqm4bxy2dkrg
                  asset: usd
                  details:
                    bankName: 'Example Bank, N.A.'
                    accountNumberLast4: '1234'
                    routingNumber: '123456789'
                    accountType: checking
                payout:
                  rail: ach
                  secCode: ppd
                returnDestinationTypes:
                  - walletCrypto
                  - walletExternal
                sponsorGas: true
                provider: 'Example Bank, N.A.'
                requiresCounterpartyWalletRegistration: true
                label: Alice deposit address
                createdAt: '2026-05-14T10:00:00Z'
                updatedAt: '2026-05-14T10:00:00Z'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidMetadataErrorResponse'
                  - $ref: '#/components/schemas/MetadataKeyTooLongErrorResponse'
                  - $ref: '#/components/schemas/MetadataTooManyKeysErrorResponse'
                  - $ref: '#/components/schemas/MetadataValueTooLongErrorResponse'
                  - $ref: '#/components/schemas/MissingParameterErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/DestinationRailNotAllowedErrorResponse
                  - $ref: '#/components/schemas/VendorAmbiguousErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DestinationNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConflictErrorResponse'
        '422':
          description: >-
            The Deposit Address could not be created because the request failed
            validation or the requested configuration is not supported.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/EreborValidationFailedErrorResponse'
                  - $ref: '#/components/schemas/AccountHolderUnsupportedErrorResponse'
                  - $ref: '#/components/schemas/AccountNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/AccountTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/AddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/BICInvalidErrorResponse'
                  - $ref: '#/components/schemas/BlockchainAddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/CardMustUseCardEndpointErrorResponse'
                  - $ref: '#/components/schemas/CountryInvalidErrorResponse'
                  - $ref: '#/components/schemas/CustodianInvalidErrorResponse'
                  - $ref: '#/components/schemas/DateOfBirthInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationInvalidReferenceErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationNetworkUnsupportedErrorResponse
                  - $ref: '#/components/schemas/DestinationNotActiveErrorResponse'
                  - $ref: '#/components/schemas/DestinationRequiredErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeMismatchErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationWalletCryptoNotSupportedErrorResponse
                  - $ref: '#/components/schemas/DestinationWrongTypeErrorResponse'
                  - $ref: '#/components/schemas/EmailInvalidErrorResponse'
                  - $ref: '#/components/schemas/EntityTypeInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExpectedSourceAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/ExpectedSourceNetworkUnsupportedErrorResponse
                  - $ref: '#/components/schemas/ExpectedSourceRequiredErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExternalAccountIDRequiredErrorResponse
                  - $ref: '#/components/schemas/IBANInvalidErrorResponse'
                  - $ref: '#/components/schemas/InstitutionNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/IntraBankNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/MemoNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/NameInvalidErrorResponse'
                  - $ref: '#/components/schemas/NationalityInvalidErrorResponse'
                  - $ref: '#/components/schemas/NetworkFamilyInvalidErrorResponse'
                  - $ref: '#/components/schemas/NoRouteAvailableErrorResponse'
                  - $ref: '#/components/schemas/OtherCustodianRequiredErrorResponse'
                  - $ref: '#/components/schemas/OtherCustodianTooLongErrorResponse'
                  - $ref: '#/components/schemas/OwnerInvalidErrorResponse'
                  - $ref: '#/components/schemas/PhoneInvalidErrorResponse'
                  - $ref: '#/components/schemas/RailNotSupportedErrorResponse'
                  - $ref: >-
                      #/components/schemas/ReturnDestinationMustBeMultiAssetErrorResponse
                  - $ref: '#/components/schemas/ReturnWalletInvalidErrorResponse'
                  - $ref: '#/components/schemas/RouteDisabledErrorResponse'
                  - $ref: '#/components/schemas/RoutingNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/TaxIDInvalidErrorResponse'
                  - $ref: '#/components/schemas/TransitNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/TypeUnsupportedErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedDestinationErrorResponse'
                  - $ref: '#/components/schemas/ValidationErrorResponse'
                  - $ref: '#/components/schemas/WalletCustomerMismatchErrorResponse'
                  - $ref: '#/components/schemas/WalletNotActiveErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/EreborResponseInvalidErrorResponse'
                  - $ref: '#/components/schemas/InternalErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
      tags:
        - DepositAddress
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DepositAddressCreateRequest'
  '/deposit-addresses/{depositAddressId}':
    get:
      operationId: getDepositAddress
      summary: Get a Deposit Address
      description: Fetch a Deposit Address by ID.
      parameters:
        - name: depositAddressId
          in: path
          required: true
          description: Deposit Address ID (`da_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DepositAddress'
              examples:
                Active deposit address delivering to a US bank account:
                  summary: Active deposit address delivering to a US bank account
                  value:
                    id: da_n1m2ff68sd8ykvt4xswtq7e015
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    status: active
                    depositInstructions:
                      asset: usdc
                      network: ethereum
                      address: '0x7B3A9F2C4D1eA8bf6390cE5D2b7fA104c8e3D9B1'
                    destination:
                      type: bankUs
                      id: ext_cc35pa5vgrq1tpsqm4bxy2dkrg
                      asset: usd
                      details:
                        bankName: 'Example Bank, N.A.'
                        accountNumberLast4: '1234'
                        routingNumber: '123456789'
                        accountType: checking
                    payout:
                      rail: ach
                      secCode: ppd
                    returnDestinationTypes:
                      - walletCrypto
                      - walletExternal
                    sponsorGas: true
                    provider: 'Example Bank, N.A.'
                    requiresCounterpartyWalletRegistration: true
                    label: Alice USD payouts
                    createdAt: '2026-03-14T19:00:00Z'
                    updatedAt: '2026-03-14T19:00:00Z'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DepositAddressNotFoundErrorResponse'
      tags:
        - DepositAddress
    patch:
      operationId: updateDepositAddress
      summary: Update a Deposit Address
      description: >-
        Update a Deposit Address. The patchable fields are `destination`
        (re-point to a different bank-type External Account),
        `returnDestination`, `label`, and `metadata`; any other JSON key in the
        body is rejected with 400. Re-pointing `destination` to a healthy bank
        External Account recovers a DA from `inactiveActionRequired` back to
        `active`.
      parameters:
        - name: depositAddressId
          in: path
          required: true
          description: Deposit Address ID (`da_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DepositAddress'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidRequestErrorResponse'
                  - $ref: '#/components/schemas/MissingParameterErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DestinationRailNotAllowedErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/DepositAddressNotFoundErrorResponse'
                  - $ref: '#/components/schemas/DestinationNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ConflictErrorResponse'
                  - $ref: '#/components/schemas/DANotRecoverableErrorResponse'
                  - $ref: '#/components/schemas/VANotRecoverableErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AccountHolderUnsupportedErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationInvalidReferenceErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationNetworkUnsupportedErrorResponse
                  - $ref: '#/components/schemas/DestinationNotActiveErrorResponse'
                  - $ref: '#/components/schemas/DestinationRequiredErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeMismatchErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationTypeSwitchNotSupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationWalletCryptoNotSupportedErrorResponse
                  - $ref: '#/components/schemas/DestinationWrongTypeErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExternalAccountIDRequiredErrorResponse
                  - $ref: '#/components/schemas/IntraBankNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/MemoNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/NoRouteAvailableErrorResponse'
                  - $ref: '#/components/schemas/RailNotSupportedErrorResponse'
                  - $ref: >-
                      #/components/schemas/ReturnDestinationMustBeMultiAssetErrorResponse
                  - $ref: '#/components/schemas/ReturnWalletInvalidErrorResponse'
                  - $ref: '#/components/schemas/RouteDisabledErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedDestinationErrorResponse'
                  - $ref: '#/components/schemas/ValidationErrorResponse'
                  - $ref: '#/components/schemas/WalletCustomerMismatchErrorResponse'
                  - $ref: '#/components/schemas/WalletNotActiveErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - DepositAddress
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DepositAddressUpdateRequest'
  '/deposit-addresses/{depositAddressId}/transactions':
    get:
      operationId: listDepositAddressTransactions
      summary: List Deposit Address transactions
      description: >-
        Returns the payment transactions that originated from this Deposit
        Address, most recent first, with cursor-based pagination. Uses the same
        grouped payment read model as `GET /transactions`, pinned to this
        deposit address (equivalent to `GET /transactions?depositAddressId=`).


        This is a collection filter: it always returns `200` with the matching
        transactions. An unknown, deleted, or other-tenant `depositAddressId`
        simply matches no rows and yields an empty list — it is not a `404`. Use
        `GET /deposit-addresses/{depositAddressId}` to assert
        existence/ownership.
      parameters:
        - name: depositAddressId
          in: path
          required: true
          description: Deposit Address ID (`da_` prefix).
          schema:
            type: string
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: status
          in: query
          required: false
          description: Filter by status.
          schema:
            type: array
            items:
              $ref: '#/components/schemas/TransactionStatus'
        - name: sourceToDestination
          in: query
          required: false
          description: Filter by corridor (source/destination category composite).
          schema:
            type: array
            items:
              $ref: '#/components/schemas/SourceToDestination'
        - name: customerId
          in: query
          required: false
          description: Scope to a customer (sender or recipient). `cst_` prefix.
          schema:
            type: string
        - name: createdAfter
          in: query
          required: false
          description: Inclusive lower bound on `createdAt`.
          schema:
            type: string
            format: date-time
        - name: createdBefore
          in: query
          required: false
          description: Inclusive upper bound on `createdAt`.
          schema:
            type: string
            format: date-time
        - name: search
          in: query
          required: false
          description: >-
            Free-text search. Matches transaction id, customer id, or customer
            email.
          schema:
            type: string
        - name: q
          in: query
          required: false
          description: Alias for `search`.
          schema:
            type: string
        - name: legStatus
          in: query
          required: false
          description: >-
            Filters to payments where ANY leg's underlying status is in the
            given set.
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidFilterErrorResponse'
                  - $ref: '#/components/schemas/InvalidCursorErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - DepositAddress
  /external-accounts:
    get:
      operationId: listExternalAccounts
      summary: List External Accounts
      description: >-
        List External Accounts. `customerId`, `counterpartyId`, and `status` are
        all optional filters — omit all to list all non-deleted external
        accounts in the project (still tenant-scoped by project). Omitting
        `status` excludes soft-deleted rows, matching prior behavior; pass
        `status=deleted` to see them.
      parameters:
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: customerId
          in: query
          required: false
          description: Filter to a single customer (`cst_` prefix).
          schema:
            type: string
        - name: counterpartyId
          in: query
          required: false
          description: Counterparty ID (`ctp_` prefix).
          schema:
            type: string
        - name: status
          in: query
          required: false
          description: >-
            Filter to a single status. Omitted by default, which excludes
            soft-deleted rows; pass `deleted` explicitly to list them.
          schema:
            $ref: '#/components/schemas/ExternalAccountStatus'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAccountList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidCounterpartyIDErrorResponse'
                  - $ref: '#/components/schemas/InvalidFilterErrorResponse'
                  - $ref: '#/components/schemas/InvalidCursorErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - ExternalAccount
    post:
      operationId: createExternalAccount
      summary: Create an External Account
      description: >-
        Create an External Account (saved payment destination). Provisions
        synchronously against the configured payment provider; the account
        starts `pending` and flips to `active` or `failed`. Exactly one per-type
        detail object must match `type`. The owner discriminator determines
        whether this account belongs to a customer directly or to one of the
        customer's counterparties.


        **Uniqueness (`walletExternal`).** A wallet is registered at most once
        per **owner**: the key is (owner, normalized blockchain address, network
        family). Consequences:


        - Re-registering an address the same owner already holds `active`,
        `pending` or `invalid` returns `409 externalAccountAlreadyRegistered`,
        with `details.existingAccountId` naming that account and
        `details.existingAccountStatus` telling you what to do next: -
        `"pending"` means a registration is still in flight and this is
        TRANSIENT — the account resolves to `active` or `failed` on its own
        (typically within ~30 minutes; see the stale-pending sweep), after which
        re-registering a `failed` account re-drives it. Retrying the create
        immediately will not help; poll `GET` on `existingAccountId`, or simply
        wait and re-submit later. - `"active"` (or `"invalid"`) is TERMINAL: use
        the account named by `existingAccountId` instead of retrying the create.
        - Two **different owners** under the same customer (the customer itself
        and one of its counterparties, or two counterparties) may each register
        the same address — each gets its own account, `201`. - The same address
        under two different **customers** is likewise allowed. - An account in
        `failed` or `rejected` state does **not** block re-registration:
        submitting it again re-drives provisioning on that same account (same
        `id`) and adopts the newly submitted `label` and `metadata`, returning
        `201`. Deleted accounts free their key entirely.


        **Uniqueness (`bankUs` with a custodial provider).** When the project's
        bank accounts are registered with a custodial provider, the provider
        holds a routing and account number once per **customer**, across the
        customer and all of its counterparties:


        - Re-registering one the provider already holds for the customer, under
        any owner, returns `409 externalAccountAlreadyRegistered` with
        `details.existingAccountId` naming that account and `details.matchedOn`
        = `routingNumberAccountNumberCustomer`. That is an account registered
        with the provider that is `active`, `invalid`, or `pending` once the
        provider has accepted it. Use that account, or delete it before
        registering the number again. - When the provider itself reports the
        duplicate, for example when two registrations of the same number are
        sent at the same time, the `409` has no `details` and the account the
        request tried to create is recorded as `rejected`. - A `rejected` or
        `failed` account does not block, nor does a `pending` one whose
        registration never reached the provider, or one registered with a
        different provider: the create registers a new account. - Deleting a
        `pending` account whose registration the provider never confirmed may
        not free the number at the provider. Registering it again can then
        return `409` without `details`; contact support to release it.


        Send an `Idempotency-Key` and retry with the SAME key after a network
        failure: the original response is replayed, so a `409` always means a
        genuinely different request collided with an existing account.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '201':
          description: >-
            The request has succeeded and a new resource has been created as a
            result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAccount'
              examples:
                'External wallet owned by a counterparty, active':
                  summary: 'External wallet owned by a counterparty, active'
                  value:
                    id: ext_95863ktcdhw27ze8hxgybb24n9
                    type: walletExternal
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    owner:
                      kind: counterparty
                      id: ctp_yp5z8m7n22svc0vh6edqgcfdat
                      name: Acme Corp
                    supportedDestinations:
                      - asset: usdc
                        network: ethereum
                      - asset: usdt
                        network: ethereum
                    details:
                      address: '0xeB3eCfb244E94a407bfb1EEcFEDe27D920cc00F5'
                      custodian: coinbaseUs
                      networkFamily: evm
                    status: active
                    label: Acme deposits inbound
                    createdAt: '2026-05-15T18:01:12Z'
                    updatedAt: '2026-05-15T18:01:12Z'
                'Canadian bank account, customer-owned':
                  summary: 'Canadian bank account, customer-owned'
                  value:
                    id: ext_p4m9c2v7k1n5q8r3s6t0w2x4yz
                    type: bankCanada
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    asset: usd
                    details:
                      bankName: Royal Bank of Canada
                      accountNumberLast4: '4567'
                      institutionNumber: '003'
                      transitNumber: '12345'
                      holderName: Bob Jones
                    status: pending
                    label: Bob CAD payouts
                    createdAt: '2026-05-14T10:05:00Z'
                    updatedAt: '2026-05-14T10:05:00Z'
                'US bank account, customer-owned':
                  summary: 'US bank account, customer-owned'
                  value:
                    id: ext_cc35pa5vgrq1tpsqm4bxy2dkrg
                    type: bankUs
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    asset: usd
                    supportedDestinations:
                      - asset: usd
                        rail: ach
                      - asset: usd
                        rail: achSameDay
                      - asset: usd
                        rail: wire
                    details:
                      bankName: Chase
                      accountNumberLast4: '3210'
                      routingNumber: '021000021'
                      accountType: checking
                      holderName: Alice Smith
                    status: pending
                    createdAt: '2026-05-14T10:00:00Z'
                    updatedAt: '2026-05-14T10:00:00Z'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidMetadataErrorResponse'
                  - $ref: '#/components/schemas/MetadataKeyTooLongErrorResponse'
                  - $ref: '#/components/schemas/MetadataTooManyKeysErrorResponse'
                  - $ref: '#/components/schemas/MetadataValueTooLongErrorResponse'
                  - $ref: '#/components/schemas/MissingParameterErrorResponse'
                  - $ref: '#/components/schemas/ZeroAddressNotAllowedErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAccountNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ConflictErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExternalAccountAlreadyRegisteredErrorResponse
        '422':
          description: >-
            The External Account could not be created because the request failed
            validation or the account is not supported.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ExternalAccountRejectedErrorResponse'
                  - $ref: '#/components/schemas/AccountHolderUnsupportedErrorResponse'
                  - $ref: '#/components/schemas/AccountNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/AccountTypeInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/AccountTypeRequirementsNotMetErrorResponse
                  - $ref: '#/components/schemas/AddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/BICInvalidErrorResponse'
                  - $ref: '#/components/schemas/BlockchainAddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/CardMustUseCardEndpointErrorResponse'
                  - $ref: '#/components/schemas/CountryInvalidErrorResponse'
                  - $ref: '#/components/schemas/CustodianInvalidErrorResponse'
                  - $ref: '#/components/schemas/CustodianRequiredErrorResponse'
                  - $ref: '#/components/schemas/DateOfBirthInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationInvalidReferenceErrorResponse
                  - $ref: '#/components/schemas/DestinationRequiredErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/EmailInvalidErrorResponse'
                  - $ref: '#/components/schemas/EntityTypeInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExpectedSourceAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/ExpectedSourceNetworkUnsupportedErrorResponse
                  - $ref: '#/components/schemas/ExpectedSourceRequiredErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExternalAccountIDRequiredErrorResponse
                  - $ref: '#/components/schemas/IBANInvalidErrorResponse'
                  - $ref: '#/components/schemas/InstitutionNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/MemoNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/NameInvalidErrorResponse'
                  - $ref: '#/components/schemas/NationalityInvalidErrorResponse'
                  - $ref: '#/components/schemas/NetworkFamilyInvalidErrorResponse'
                  - $ref: '#/components/schemas/NetworkFamilyNotServedErrorResponse'
                  - $ref: '#/components/schemas/NoRouteAvailableErrorResponse'
                  - $ref: '#/components/schemas/OtherCustodianRequiredErrorResponse'
                  - $ref: '#/components/schemas/OtherCustodianTooLongErrorResponse'
                  - $ref: '#/components/schemas/OwnerInvalidErrorResponse'
                  - $ref: '#/components/schemas/OwnerNotActiveErrorResponse'
                  - $ref: '#/components/schemas/PhoneInvalidErrorResponse'
                  - $ref: '#/components/schemas/RouteDisabledErrorResponse'
                  - $ref: '#/components/schemas/RoutingNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/TaxIDInvalidErrorResponse'
                  - $ref: '#/components/schemas/TransitNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/TypeUnsupportedErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedDestinationErrorResponse'
                  - $ref: '#/components/schemas/ValidationErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
      tags:
        - ExternalAccount
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExternalAccountCreateRequest'
            examples:
              External wallet owned by a counterparty:
                summary: External wallet owned by a counterparty
                value:
                  label: Acme deposits
                  owner:
                    kind: counterparty
                    counterpartyId: ctp_1x0yvbj459mtzq609n8p33twd1
                  type: walletExternal
                  walletExternal:
                    blockchainAddress: '0xbEeF4A2C891d56e72B67a3f21d0cF94f1D7c5911'
                    networkFamily: evm
                    custodian: COINBASE_US
              'Canadian bank account, customer-owned':
                summary: 'Canadian bank account, customer-owned'
                value:
                  label: Bob CAD payouts
                  owner:
                    kind: customer
                    customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
                  type: bankCanada
                  bankCanada:
                    institutionNumber: '003'
                    transitNumber: '12345'
                    accountNumber: '1234567'
                    bankName: Royal Bank of Canada
              'US bank account, customer-owned':
                summary: 'US bank account, customer-owned'
                value:
                  label: Alice payouts to Chase
                  owner:
                    kind: customer
                    customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
                  type: bankUs
                  bankUs:
                    accountNumber: '9876543210'
                    routingNumber: '021000021'
                    accountType: checking
                    bankName: Chase
  /external-accounts/cards:
    post:
      operationId: createCardExternalAccount
      summary: Register a card
      description: >-
        Register a debit card as a customer-owned External Account. Card numbers
        are accepted only on this dedicated endpoint; reads, lists and deletes
        stay unified on the other External Account routes. `details.brand` is
        derived server-side from the card number. Only `debit` cards are
        supported; other card types are rejected at provisioning.
        `billingAddress` is optional and falls back to the customer's address. A
        per-customer velocity guard returns 429 `TooManyCardAttempts` (with a
        `Retry-After` header) against card-testing abuse.


        **Card input depends on the environment.** Production live requires
        VGS-enabled card registration: `details.cardNumber` and `details.cvv`
        must be VGS aliases, and raw values are rejected with
        `CardNumberInvalid` or `CVVInvalid`. Collect real card data with the
        Polygon SDK's hosted card form. The server-to-server VGS path for this
        endpoint is not available yet; do not send real card data directly to
        the API.


        In sandbox environments with VGS disabled, send only test card data:
        `details.cardNumber` must contain 12–19 digits and `details.cvv` must
        contain 3–4 digits. Those environments reject VGS aliases. A VGS-enabled
        sandbox instead requires aliases, as in the example below. Confirm the
        sandbox's input mode before integrating.


        **Uniqueness.** A card already registered with the card provider returns
        `409 externalAccountAlreadyRegistered`, WITHOUT `details`: the
        provider's dedupe is global (it spans customers and partners), so the
        blocking registration is frequently not an account in this project and
        cannot be named.


        **Country screening.** A billing country, or the owner's KYC country, on
        the compliance prohibited-jurisdictions list is not a 4xx: the create
        returns `201` with `status=rejected` and
        `failure.code=countryProhibited`, and the card is never sent to the
        provider. If the owning customer's address country is not a recognised
        country (so it cannot be screened), the create returns `422
        billingAddressInvalid`; correct the customer's address.


        **Billing address lines.** `line1` and `line2` must each be at most 35
        UTF-16 code units (a supplementary character counts as two), must not be
        digits only or a PO Box, and must not contain any of
        `!@#$%^&*()+=<>.,;:?"/\|}{[]~_`. A supplied address that breaks a line
        rule returns `422 billingAddressInvalid` naming `billingAddress.line1`
        or `line2`. When `billingAddress` is omitted and the customer's own
        address breaks one, the create returns `422 billingAddressInvalid`
        naming the customer's address (not `missingBillingAddress`); supply
        `billingAddress` or correct the customer's address. Supplied nonblank
        lines are sent as given, including leading and trailing whitespace,
        which counts toward the limit. A `line2` of only whitespace is treated
        as absent and not sent. The line rules apply only to an address that
        passes country screening: a prohibited country is still `201` with
        `status=rejected`.


        **Cardholder name.** The card is registered under the owning customer's
        `firstName` and `lastName`; any name in `billingAddress` is ignored.
        Latin letters are folded to ASCII (José and Yıldız become Jose and
        Yildiz), hyphens become spaces and apostrophes are dropped; a name that
        still cannot be used returns `422 cardholderNameInvalid` (correct the
        customer's name). An owning customer that is not an individual returns
        `422 accountTypeRequirementsNotMet`.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '201':
          description: >-
            The request has succeeded and a new resource has been created as a
            result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAccount'
              examples:
                'Debit card, VGS-aliased':
                  summary: 'Debit card, VGS-aliased'
                  value:
                    id: ext_7n2k4m8p1q3r5s9t0v6w2x4yzb
                    type: card
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    asset: usd
                    details:
                      brand: visa
                      last4: '4242'
                      cardType: debit
                      expiryMonth: 12
                      expiryYear: 2029
                      billingAddressSource: provided
                    status: pending
                    label: Alice debit card
                    createdAt: '2026-05-14T10:00:00Z'
                    updatedAt: '2026-05-14T10:00:00Z'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidRequestBodyErrorResponse'
                  - $ref: '#/components/schemas/CardLegacyBadRequestErrorResponse'
                  - $ref: '#/components/schemas/InvalidMetadataErrorResponse'
                  - $ref: '#/components/schemas/MetadataKeyTooLongErrorResponse'
                  - $ref: '#/components/schemas/MetadataTooManyKeysErrorResponse'
                  - $ref: '#/components/schemas/MetadataValueTooLongErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/UnauthorizedErrorResponse'
                  - $ref: '#/components/schemas/CardLegacyProjectMissingErrorResponse'
        '404':
          description: The customer does not exist on this project.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardCustomerNotFoundErrorResponse'
        '409':
          description: >-
            This owner, or for a `bankUs` account with a custodial provider this
            customer, has already registered this external account. Returned as
            409 `externalAccountAlreadyRegistered`, and on this error `code`
            carries that same string rather than the numeric `code` of the
            standard error envelope; branch on it as a string here.


            `details` names the account that already holds the registration and
            is returned on the `walletExternal` and `bankUs` create paths. It is
            absent when the provider reports the duplicate itself: always on
            `POST /external-accounts/cards`, where card de-duplication spans the
            card provider's whole platform, so the blocking registration is not
            necessarily one of yours and cannot be named; and on `bankUs` when
            two registrations of the same number race.
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/ExternalAccountAlreadyRegisteredErrorResponse
        '413':
          description: The request body exceeds the size limit.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardLegacyBodyTooLargeErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/SSNNotVerifiedErrorResponse'
                  - $ref: '#/components/schemas/RiskRejectedErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedCardTypeErrorResponse'
                  - $ref: '#/components/schemas/CardProviderErrorResponse'
                  - $ref: >-
                      #/components/schemas/AccountTypeRequirementsNotMetErrorResponse
                  - $ref: '#/components/schemas/BillingAddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/CardholderNameInvalidErrorResponse'
                  - $ref: '#/components/schemas/CVVInvalidErrorResponse'
                  - $ref: '#/components/schemas/CardExpiredErrorResponse'
                  - $ref: '#/components/schemas/CardExpiryInvalidErrorResponse'
                  - $ref: '#/components/schemas/CardNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/CardLimitReachedErrorResponse'
                  - $ref: '#/components/schemas/CardNotEnabledForProjectErrorResponse'
                  - $ref: '#/components/schemas/TypeUnsupportedErrorResponse'
                  - $ref: '#/components/schemas/MissingBillingAddressErrorResponse'
                  - $ref: '#/components/schemas/OwnerNotActiveErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedCardBrandErrorResponse'
        '429':
          description: Client error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TooManyCardAttemptsErrorResponse'
        '500':
          description: An internal error prevented registration.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/CardLegacyInternalErrorResponse'
                  - $ref: '#/components/schemas/InternalErrorResponse'
        '502':
          description: The card provider could not authenticate the request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CardLegacyProviderErrorResponse'
        '503':
          description: Country screening is temporarily unavailable.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/CardLegacyScreenUnavailableErrorResponse
                  - $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
      tags:
        - ExternalAccount
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CardRequest'
            examples:
              'Debit card, VGS-aliased':
                summary: 'Debit card, VGS-aliased'
                value:
                  customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
                  details:
                    cardNumber: 424242Xk9bT24242
                    cvv: tok_live_7d2Hq9xVb3
                    expiryMonth: 12
                    expiryYear: 2029
                  billingAddress:
                    firstName: Alice
                    lastName: Smith
                    line1: 100 Main St
                    city: Seattle
                    state: WA
                    country: US
                    zipCode: '98101'
                  webSessionId: ws_7f3c9a1e2b4d
                  deviceFingerprint: fp_5e8a2c7d9b1f
                  label: Alice debit card
  '/external-accounts/{externalAccountId}':
    delete:
      operationId: deleteExternalAccount
      summary: Delete an External Account
      description: >-
        Delete an External Account (soft delete). Returns 204.


        Returns 409 `ConvertingSendInFlight` while a converting send (a crypto
        send that swaps to another asset, then sends to this account) still owes
        a send to the account: its swap is still settling, the send has not been
        issued yet, or the send failed and is still being retried automatically
        (a withdrawal reads `processing.payoutRetrying`, a deposit address
        payout reads `processing.awaitingCryptoOut`). The error's `cause` names
        the oldest such transaction by its `txn_` id. Nothing is deleted. A
        failed send that is still being retried keeps blocking the delete, so
        retrying the delete succeeds only once that transaction has completed,
        or the retries have finished with it (for example because the provider
        failed the swap), or operations have closed it. To cut the account off
        now, use the emergency revoke below.


        **Emergency revoke.** If the account must be cut off now (for example
        because it is compromised), send `emergencyRevoke=true` with a `reason`.
        The account is deleted even while a converting send is in flight. What
        follows covers crypto to crypto sends by Coinme (withdrawals and deposit
        address crypto payouts, converting or same-asset, and their retries);
        the last point covers every other send:


        - every converting send to it whose send has not been issued yet is
        stopped by the revoke: nothing is sent to the account, the funds stay
        with the provider and are held for operations review (nothing is
        returned automatically), and the transaction never completes (it reads
        `failed`, with the funds held for review). These are listed in
        `revokedTransactionIds`. - every other such send (a same-asset
        withdrawal or deposit address payout, or a retry) re-checks the account
        right before it is issued, so one not issued yet fails once the account
        is deleted. That is the delete itself, not the revoke. A same-asset send
        whose check passed in the instant before the delete committed, and whose
        transaction did not exist yet when the lists were read, can still be
        issued and is not listed. - such a send that may already have been
        issued cannot be recalled and may still complete: one pending or
        processing, or recorded as failed after an unclear provider answer.
        These are listed in `sendsNotRecalledTransactionIds`, together with any
        other crypto to crypto send by that provider to the account (such as a
        virtual account's crypto forward). A pending one is listed even if its
        call had not gone out yet. - every other send to the account is in
        neither list, notably any deposit address or virtual account crypto
        payout by Erebor, and any crypto buy delivered to the account. The
        delete does not stop one already issued, so an empty
        `sendsNotRecalledTransactionIds` does not mean nothing can still reach
        the account. To find those, list the customer's `pending` and
        `processing` transactions and check those whose `destination` is
        `walletExternal` with this account's `id`.


        The response is 200 with both lists. The `reason` is recorded on every
        stopped transaction for operations review. Sending the same request
        again for an account this project already deleted with an emergency
        revoke that stopped at least one transaction answers 200 again with the
        lists rebuilt from what that revoke recorded, without changing anything;
        the not-recalled list is read again, so a send that settled since drops
        out. Any other deleted account answers 404, including one deleted by an
        emergency revoke that stopped nothing: then nothing records the revoke,
        so its `sendsNotRecalledTransactionIds` cannot be read again. Keep that
        list from the first response; if it was lost, find the sends still owed
        to the account through the customer's transactions, as above. Without
        `emergencyRevoke`, or with `emergencyRevoke=false`, the delete behaves
        as described above and `reason` is ignored.
      parameters:
        - name: externalAccountId
          in: path
          required: true
          description: External Account ID (`ext_` prefix).
          schema:
            type: string
        - name: emergencyRevoke
          in: query
          required: false
          description: >-
            Delete even while a converting send to this account is in flight,
            and stop every such send not yet issued. Requires `reason`. See the
            operation description.
          schema:
            type: boolean
          explode: false
        - name: reason
          in: query
          required: false
          description: >-
            Why the account is being cut off. Required with
            `emergencyRevoke=true`: 3 to 500 characters once leading and
            trailing whitespace is trimmed, otherwise 400 `InvalidParameter`.
            The limits apply to the trimmed value only, so this schema sets no
            length on the raw string: a value padded with whitespace is accepted
            when what is left fits. The trimmed value is recorded on every
            transaction the revoke stops and in operations logs, for operations
            review. It must not carry personal data (names, emails, phone
            numbers, addresses or account numbers): say what happened, for
            example "wallet reported compromised", and keep any reference to
            your own case id.
          schema:
            type: string
          explode: false
      responses:
        '200':
          description: >-
            The outcome of `DELETE
            /external-accounts/{externalAccountId}?emergencyRevoke=true`. The
            account is deleted in every case. Both lists name transactions by
            their `txn_` id and are empty when nothing matched.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAccountEmergencyRevoke'
        '204':
          description: >-
            There is no content to send for this request, but the headers may be
            useful.
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidParameterErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAccountNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/VersionConflictErrorResponse'
                  - $ref: '#/components/schemas/ConvertingSendInFlightErrorResponse'
      tags:
        - ExternalAccount
    get:
      operationId: getExternalAccount
      summary: Get an External Account
      description: Get an External Account by id.
      parameters:
        - name: externalAccountId
          in: path
          required: true
          description: External Account ID (`ext_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAccount'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidExternalAccountIDErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAccountNotFoundErrorResponse'
      tags:
        - ExternalAccount
    patch:
      operationId: updateExternalAccount
      summary: Update an External Account
      description: >-
        Update an External Account. Only `label` and `metadata` are mutable; any
        other JSON key in the body is rejected with 400.
      parameters:
        - name: externalAccountId
          in: path
          required: true
          description: External Account ID (`ext_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAccount'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidMetadataErrorResponse'
                  - $ref: '#/components/schemas/MetadataKeyTooLongErrorResponse'
                  - $ref: '#/components/schemas/MetadataTooManyKeysErrorResponse'
                  - $ref: '#/components/schemas/MetadataValueTooLongErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalAccountNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VersionConflictErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/CountryInvalidErrorResponse'
                  - $ref: '#/components/schemas/DateOfBirthInvalidErrorResponse'
                  - $ref: '#/components/schemas/EmailInvalidErrorResponse'
                  - $ref: '#/components/schemas/EmptyUpdateErrorResponse'
                  - $ref: '#/components/schemas/EntityTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/NameInvalidErrorResponse'
                  - $ref: '#/components/schemas/NationalityInvalidErrorResponse'
                  - $ref: '#/components/schemas/PhoneInvalidErrorResponse'
                  - $ref: '#/components/schemas/TaxIDInvalidErrorResponse'
      tags:
        - ExternalAccount
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExternalAccountUpdateRequest'
  /networks:
    get:
      operationId: listNetworks
      summary: List supported networks
      description: >-
        Lists every network OMS supports, with its identifiers, available
        assets, and which OMS resources can use it in which direction.
        Availability is derived from live route configuration, so a network
        absent from this list is not routable; the fiat-rail availability and
        the crypto deposit-address signal both reflect your own project's
        provider configuration. When your project holds more than one payment
        provider, the response covers the networks of every provider it holds.


        "Network" here means any rail, not only a blockchain: `category`
        (`crypto` | `fiatAccount` | `cash`) and `type` (`blockchain` |
        `bankRail` | `card` | `physical`) are what distinguish them, and
        `chainId` / `networkFamily` are absent on everything that is not a
        blockchain.
      parameters:
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NetworkList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidParameterErrorResponse'
                  - $ref: '#/components/schemas/InvalidCursorErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - Reference
  /quotes:
    post:
      operationId: createQuote
      summary: Create a payment quote
      description: >-
        Creates a payment quote with a locked exchange rate and fee breakdown
        for a prospective transfer. Quotes expire after a short window;
        reference the returned quote ID when executing the transaction. Pass an
        Idempotency-Key header to safely retry.


        A disallowed source→destination instrument pair is rejected with `422
        unsupportedInstrumentCombination` before any quote is created; the error
        body carries a `details` object of `{ source, destination,
        supportedDestinations }`. (Not modeled as a typed error arm here so the
        other 422 codes on this operation keep their shape.)
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '201':
          description: >-
            The request has succeeded and a new resource has been created as a
            result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Quote'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/CustomerRequiredErrorResponse'
                  - $ref: '#/components/schemas/DestinationAssetRequiredErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationNetworkRequiredErrorResponse
                  - $ref: '#/components/schemas/InvalidAmountFormatErrorResponse'
                  - $ref: '#/components/schemas/InvalidDestinationTypeErrorResponse'
                  - $ref: '#/components/schemas/InvalidExternalAccountIDErrorResponse'
                  - $ref: '#/components/schemas/InvalidMetadataErrorResponse'
                  - $ref: '#/components/schemas/InvalidRequestErrorResponse'
                  - $ref: '#/components/schemas/InvalidSourceTypeErrorResponse'
                  - $ref: '#/components/schemas/InvalidWalletAddressErrorResponse'
                  - $ref: '#/components/schemas/InvalidWalletIDErrorResponse'
                  - $ref: '#/components/schemas/InvalidWalletTargetErrorResponse'
                  - $ref: '#/components/schemas/MetadataKeyTooLongErrorResponse'
                  - $ref: '#/components/schemas/MetadataTooManyKeysErrorResponse'
                  - $ref: '#/components/schemas/MetadataValueTooLongErrorResponse'
                  - $ref: '#/components/schemas/MissingCashLocationErrorResponse'
                  - $ref: '#/components/schemas/MissingRequiredFieldErrorResponse'
                  - $ref: '#/components/schemas/SourceAssetRequiredErrorResponse'
                  - $ref: '#/components/schemas/SourceNetworkRequiredErrorResponse'
                  - $ref: '#/components/schemas/SourceWalletRequiredErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedValueErrorResponse'
                  - $ref: '#/components/schemas/ZeroAddressNotAllowedErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/FeatureNotEnabledErrorResponse'
                  - $ref: '#/components/schemas/KYCPendingErrorResponse'
                  - $ref: '#/components/schemas/KYCRequiredErrorResponse'
                  - $ref: '#/components/schemas/TransferPairNotPermittedErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ExternalAccountNotFoundErrorResponse'
                  - $ref: '#/components/schemas/QuoteNotFoundErrorResponse'
                  - $ref: '#/components/schemas/WalletNotFoundErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AboveMaximumAmountErrorResponse'
                  - $ref: '#/components/schemas/AmbiguousAmountErrorResponse'
                  - $ref: '#/components/schemas/AmountAboveMaximumErrorResponse'
                  - $ref: '#/components/schemas/AmountBelowMinimumErrorResponse'
                  - $ref: '#/components/schemas/AmountNotMultipleErrorResponse'
                  - $ref: >-
                      #/components/schemas/AmountNotMultipleOfTwentyErrorResponse
                  - $ref: '#/components/schemas/AmountRequiredErrorResponse'
                  - $ref: >-
                      #/components/schemas/BankBeneficiaryNotVerifiedErrorResponse
                  - $ref: '#/components/schemas/BankRailNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/CardNotEnabledForProjectErrorResponse'
                  - $ref: '#/components/schemas/CashPayoutExceedsMaximumErrorResponse'
                  - $ref: >-
                      #/components/schemas/CashPickupNotAllowedInCountryErrorResponse
                  - $ref: >-
                      #/components/schemas/CashPickupNotAllowedInStateErrorResponse
                  - $ref: >-
                      #/components/schemas/CryptoToCryptoExternalAddressUnsupportedErrorResponse
                  - $ref: '#/components/schemas/DailyCountExceededErrorResponse'
                  - $ref: '#/components/schemas/DailyLimitExceededErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationExternalAccountAddressMissingErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationExternalAccountNetworkMismatchErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationExternalAccountNotActiveErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationExternalAccountNotWalletExternalErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationExternalAccountVendorMismatchErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationInvalidReferenceErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationNetworkNotSupportedByProviderErrorResponse
                  - $ref: '#/components/schemas/DestinationRequiredErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/InsufficientBalanceErrorResponse'
                  - $ref: '#/components/schemas/IntraBankNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/MemoNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/MonthlyCountExceededErrorResponse'
                  - $ref: '#/components/schemas/MonthlyLimitExceededErrorResponse'
                  - $ref: '#/components/schemas/NoRouteAvailableErrorResponse'
                  - $ref: '#/components/schemas/ProductDailyLimitReachedErrorResponse'
                  - $ref: '#/components/schemas/RouteDisabledErrorResponse'
                  - $ref: '#/components/schemas/SelfTransferNotAllowedErrorResponse'
                  - $ref: '#/components/schemas/SellNotAllowedAtLocationErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedDestinationErrorResponse'
                  - $ref: >-
                      #/components/schemas/UnsupportedInstrumentCombinationErrorResponse
                  - $ref: '#/components/schemas/ValidationErrorResponse'
                  - $ref: '#/components/schemas/WalletAssetMismatchErrorResponse'
                  - $ref: >-
                      #/components/schemas/WalletBoundToCustodialFlowErrorResponse
                  - $ref: '#/components/schemas/WalletClaimedErrorResponse'
                  - $ref: >-
                      #/components/schemas/WalletExternalIDUnsupportedErrorResponse
                  - $ref: '#/components/schemas/WeeklyCountExceededErrorResponse'
                  - $ref: '#/components/schemas/WeeklyLimitExceededErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InternalErrorResponse'
                  - $ref: '#/components/schemas/LimitMisconfiguredErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/BankRailUnavailableErrorResponse'
                  - $ref: '#/components/schemas/CardRailUnavailableErrorResponse'
      tags:
        - Quote
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/QuoteCreateRequest'
  '/quotes/{quoteId}':
    get:
      operationId: getQuote
      summary: Get quote by ID
      description: >-
        Retrieves a previously created quote by ID, including its locked rate,
        fee breakdown, and expiry.
      parameters:
        - name: quoteId
          in: path
          required: true
          description: Quote ID (`qt_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Quote'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/QuoteNotFoundErrorResponse'
      tags:
        - Quote
  /reference/account-type-requirements:
    get:
      operationId: getAccountTypeRequirements
      summary: Get account-type requirements
      description: >-
        The owner and detail fields required to create each External Account
        type through `POST /external-accounts` on this project — one ruleset per
        type. A type absent from `requirements` cannot be created through `POST
        /external-accounts` on this project. Cards are never listed here;
        register them with `POST /external-accounts/cards`.


        `walletExternal` is resolved from the project's wallet-provisioning
        vendor. `bankUs` is resolved per customer on a project holding both
        vendors: pass `customerId` to run the same resolution create runs for
        that customer — including its refusal when that customer cannot create
        `bankUs` at all — or omit it to receive the conservative default flagged
        with `routingDependsOnCustomer`.
      parameters:
        - name: customerId
          in: query
          required: false
          description: >-
            Resolve `bankUs` for this customer (canonical `cst_` TypeID).
            Ignored by every other type.
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountTypeRequirements'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidParameterErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorConfigMissingErrorResponse'
        '404':
          description: >-
            The `customerId` query parameter did not resolve to a customer on
            this project.
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/AccountTypeRequirementsCustomerNotFoundErrorResponse
        '422':
          description: Client error
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/AccountTypeRequirementsNotMetErrorResponse
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
      tags:
        - Reference
  /transactions:
    get:
      operationId: listTransactions
      summary: List transactions with filters
      description: >-
        List transactions with filters.


        Results are ordered newest-first (by createdAt desc, id desc). `limit`
        defaults to 50 and is capped at 100.


        Date filters `createdAfter` and `createdBefore` are **inclusive**
        (treated as `>=` and `<=` against `createdAt`).


        Pagination returns opaque `nextCursor` / `previousCursor` tokens in the
        response whenever the page is non-empty: use `startingAfter=nextCursor`
        to fetch the next page, or `endingBefore=previousCursor` to page
        backward. `hasMore` tells the client whether more rows exist in the
        current direction of travel; an empty response in the other direction
        signals the start of the list.
      parameters:
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: status
          in: query
          required: false
          description: Filter by status.
          schema:
            type: array
            items:
              $ref: '#/components/schemas/TransactionStatus'
        - name: sourceToDestination
          in: query
          required: false
          description: Filter by corridor (source/destination category composite).
          schema:
            type: array
            items:
              $ref: '#/components/schemas/SourceToDestination'
        - name: customerId
          in: query
          required: false
          description: >-
            Scope to a customer. Matches rows where the customer is on either
            side: the sender (quote owner) or the recipient. `cst_` prefix.
          schema:
            type: string
        - name: walletId
          in: query
          required: false
          description: >-
            Transactions where this wallet is the source or destination
            instrument, crypto or fiat alike. Accepts the canonical `wlt_`
            prefix plus the older `acc_` and `wlt_fiat_` forms.
          schema:
            type: string
        - name: virtualAccountId
          in: query
          required: false
          description: >-
            Filter to the transaction's originating virtual account. `va_`
            prefix.
          schema:
            type: string
        - name: depositAddressId
          in: query
          required: false
          description: >-
            Filter to the transaction's originating deposit address. `da_`
            prefix.
          schema:
            type: string
        - name: cashInId
          in: query
          required: false
          description: Filter to the transaction's originating cash-in. `ci_` prefix.
          schema:
            type: string
        - name: precursorType
          in: query
          required: false
          description: >-
            Filter by the kind of precursor that originated the transaction.
            Matches transactions where ANY leg carries a precursor of this type
            (consistent with the id filters above). This may differ from the
            single `precursor` object rendered on the transaction: when a leg
            has several precursor sources, the rendered `precursor` reports one
            winner by fixed precedence (depositAddress > virtualAccount > cashIn
            > quote), so a transaction can match e.g. `precursorType=quote`
            while its rendered `precursor.type` is `depositAddress`. `manual`
            matches a transaction with no known origin resource and no
            recognized out-of-band arrival — this includes a future
            operator-initiated transaction (rendered `{type: manual}`). A
            recognized custodial-wallet deposit, the one out-of-band arrival
            current data produces, renders `{type: walletDeposit}` instead;
            filter on `precursorType=walletDeposit` to match those rows.
            `reversal` is deferred until reversal automation lands.
          schema:
            $ref: '#/components/schemas/TransactionPrecursorType'
        - name: createdAfter
          in: query
          required: false
          description: Inclusive lower bound on `createdAt`.
          schema:
            type: string
            format: date-time
        - name: createdBefore
          in: query
          required: false
          description: Inclusive upper bound on `createdAt`.
          schema:
            type: string
            format: date-time
        - name: search
          in: query
          required: false
          description: >-
            Free-text search. Matches transaction id, customer id, or customer
            email.
          schema:
            type: string
        - name: q
          in: query
          required: false
          description: Alias for `search`.
          schema:
            type: string
        - name: legStatus
          in: query
          required: false
          description: >-
            Filters to payments where ANY leg's underlying status is in the
            given set (e.g. `failed` surfaces outbound-failed-funds-held
            payments whose derived overall `status` is still `processing`).
            Values are leg-level statuses, a superset of `TransactionStatus`.
            Only applied under the grouped read model; ignored otherwise.
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidFilterErrorResponse'
                  - $ref: '#/components/schemas/InvalidCursorErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - Transaction
    post:
      operationId: createTransaction
      summary: Execute a transaction (send)
      description: >-
        Executes a transfer by accepting an open quote. Reference the quote by
        its ID; OMS pulls funds from the quote's source and delivers them to its
        destination. Pass an Idempotency-Key header to safely retry without
        sending twice.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '201':
          description: >-
            The request has succeeded and a new resource has been created as a
            result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
              examples:
                'Just created from a quote, funds pulled, settling':
                  summary: 'Just created from a quote, funds pulled, settling'
                  value:
                    id: txn_hdgebv2mns4af7pgs5r6kkacxh
                    status: processing
                    subStatus: processing.fundsPulled
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    precursor:
                      type: quote
                      id: qt_0gq9aesz4wb5etdv88z1j61qcm
                    source:
                      type: walletCrypto
                      id: wlt_5h4jzzpr9xre3bamd9ca7qyghn
                      asset: usdc
                      network: polygon
                      details:
                        address: '0x7B3A9F2C4D1eA8bf6390cE5D2b7fA104c8e3D9B1'
                    destination:
                      owner:
                        kind: counterparty
                        id: ctp_yp5z8m7n22svc0vh6edqgcfdat
                        name: Alice Smith
                      type: bankUs
                      id: ext_fky491gakzj0dd46qb6whsr2vq
                      asset: usd
                      details:
                        bankName: 'Example Bank, N.A.'
                        accountNumberLast4: '1234'
                        routingNumber: '123456789'
                        accountType: checking
                        holderName: Alice Smith
                    pricing:
                      source:
                        asset: usdc
                        amount: '100.000000'
                      destination:
                        asset: usd
                        amount: '100.00'
                      fees: []
                      exchangeRate: '1.0000'
                      fixedAmountSide: source
                      sponsorGas: true
                    metadata:
                      orderId: order_12345
                    createdAt: '2026-03-14T19:00:00Z'
                    updatedAt: '2026-03-14T19:00:20Z'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/CounterpartyUnresolvedErrorResponse'
                  - $ref: '#/components/schemas/InvalidQuoteErrorResponse'
                  - $ref: '#/components/schemas/InvalidWalletIDErrorResponse'
                  - $ref: '#/components/schemas/MetadataKeyTooLongErrorResponse'
                  - $ref: '#/components/schemas/MetadataTooManyKeysErrorResponse'
                  - $ref: '#/components/schemas/MetadataValueTooLongErrorResponse'
                  - $ref: '#/components/schemas/QuoteRequiredErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/DestinationRailNotAllowedErrorResponse
                  - $ref: '#/components/schemas/EreborConfigMissingErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/QuoteNotFoundErrorResponse'
                  - $ref: '#/components/schemas/TransactionNotFoundErrorResponse'
                  - $ref: '#/components/schemas/WalletNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ConcurrentModificationErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AboveMaximumAmountErrorResponse'
                  - $ref: '#/components/schemas/AmountAboveMaximumErrorResponse'
                  - $ref: '#/components/schemas/AmountBelowMinimumErrorResponse'
                  - $ref: '#/components/schemas/AmountNotMultipleErrorResponse'
                  - $ref: >-
                      #/components/schemas/AmountNotMultipleOfTwentyErrorResponse
                  - $ref: >-
                      #/components/schemas/BankBeneficiaryNotVerifiedErrorResponse
                  - $ref: '#/components/schemas/BankRailNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/CardNotEligibleErrorResponse'
                  - $ref: '#/components/schemas/CardNotEnabledForProjectErrorResponse'
                  - $ref: '#/components/schemas/CashPayoutExceedsMaximumErrorResponse'
                  - $ref: '#/components/schemas/CurrencyNotEnforceableErrorResponse'
                  - $ref: '#/components/schemas/DailyCountExceededErrorResponse'
                  - $ref: '#/components/schemas/DailyLimitExceededErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExternalDeliveryWalletRequiredErrorResponse
                  - $ref: '#/components/schemas/InsufficientBalanceErrorResponse'
                  - $ref: '#/components/schemas/IntraBankNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/MemoNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/MonthlyCountExceededErrorResponse'
                  - $ref: '#/components/schemas/MonthlyLimitExceededErrorResponse'
                  - $ref: '#/components/schemas/ProductDailyLimitReachedErrorResponse'
                  - $ref: '#/components/schemas/QuoteConsumedErrorResponse'
                  - $ref: '#/components/schemas/QuoteExpiredErrorResponse'
                  - $ref: '#/components/schemas/QuoteMissingCustomerErrorResponse'
                  - $ref: '#/components/schemas/QuoteTypeMismatchErrorResponse'
                  - $ref: '#/components/schemas/RiskSessionRequiredErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedDestinationErrorResponse'
                  - $ref: '#/components/schemas/ValidationErrorResponse'
                  - $ref: >-
                      #/components/schemas/WalletBoundToCustodialFlowErrorResponse
                  - $ref: '#/components/schemas/WalletClaimedErrorResponse'
                  - $ref: '#/components/schemas/WeeklyCountExceededErrorResponse'
                  - $ref: '#/components/schemas/WeeklyLimitExceededErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InternalErrorResponse'
                  - $ref: '#/components/schemas/LimitMisconfiguredErrorResponse'
        '501':
          description: Server error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/AwaitingDepositUnsupportedErrorResponse
                  - $ref: '#/components/schemas/CryptoOutNotSupportedErrorResponse'
        '502':
          description: Server error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/Transaction'
                  - $ref: '#/components/schemas/BalanceRefreshFailedErrorResponse'
      tags:
        - Transaction
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransactionCreateRequest'
  '/transactions/{transactionId}':
    get:
      operationId: getTransaction
      summary: Get transaction by ID
      description: Retrieves a single transaction by ID.
      parameters:
        - name: transactionId
          in: path
          required: true
          description: Transaction ID (`txn_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
              examples:
                'Failed transfer, inbound returned to the registered wallet':
                  summary: 'Failed transfer, inbound returned to the registered wallet'
                  value:
                    id: txn_mmbdyjd3r0z92y1zwck56anv0r
                    status: failed
                    subStatus: failed.returnedToSender
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    precursor:
                      type: quote
                      id: qt_6yd7gwfxaa13m83sepnzrmqnj2
                    source:
                      type: walletCrypto
                      id: wlt_5h4jzzpr9xre3bamd9ca7qyghn
                      asset: usdc
                      network: polygon
                      details:
                        address: '0x7B3A9F2C4D1eA8bf6390cE5D2b7fA104c8e3D9B1'
                    destination:
                      owner:
                        kind: counterparty
                        id: ctp_yp5z8m7n22svc0vh6edqgcfdat
                        name: Alice Smith
                      type: walletExternal
                      id: ext_95863ktcdhw27ze8hxgybb24n9
                      asset: usdc
                      network: base
                      details:
                        address: '0xbEeF4A2C891d56e72B67a3f21d0cF94f1D7c5911'
                    pricing:
                      source:
                        asset: usdc
                        amount: '100.000000'
                      destination:
                        asset: usdc
                        amount: '100.000000'
                      fees: []
                      exchangeRate: '1.0000'
                      fixedAmountSide: source
                      sponsorGas: true
                    failure:
                      code: returnedToSender
                      message: The funds were returned to the sender.
                      retryable: false
                    createdAt: '2026-03-14T19:00:00Z'
                    updatedAt: '2026-03-14T19:35:00Z'
                'Deposit-address inbound from an unrecognized sender, awaiting attribution':
                  summary: >-
                    Deposit-address inbound from an unrecognized sender,
                    awaiting attribution
                  value:
                    id: txn_x9waqqeg1ng6v32c5142zfp89d
                    status: awaitingAction
                    subStatus: awaitingAction.awaitingSenderAttribution
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    precursor:
                      type: depositAddress
                      id: da_r8f126hqwm3x6j5k00qsaysf4c
                    source:
                      type: walletExternal
                      asset: usdc
                      network: polygon
                      details:
                        address: '0xeB3eCfb244E94a407bfb1EEcFEDe27D920cc00F5'
                    destination:
                      type: bankUs
                      id: ext_cc35pa5vgrq1tpsqm4bxy2dkrg
                      asset: usd
                      details:
                        bankName: 'Example Bank, N.A.'
                        accountNumberLast4: '1234'
                        routingNumber: '123456789'
                        accountType: checking
                    pricing:
                      source:
                        asset: usdc
                        amount: '250.000000'
                      destination:
                        asset: usd
                        amount: '250.00'
                      fees: []
                      exchangeRate: '1.0000'
                      fixedAmountSide: source
                      sponsorGas: true
                    hold:
                      code: senderAttribution
                      message: >-
                        The sender of this deposit is not identified. Register
                        its wallet as an external account to release the
                        deposit.
                      deadline: '2026-06-14T17:32:48Z'
                      match:
                        address: '0xeB3eCfb244E94a407bfb1EEcFEDe27D920cc00F5'
                        network: evm
                    createdAt: '2026-05-15T17:32:48Z'
                    updatedAt: '2026-05-15T17:32:48Z'
                Cash payout with a pickup code ready at a retail location:
                  summary: Cash payout with a pickup code ready at a retail location
                  value:
                    id: txn_t21b4031yen78cqx2t93crbs66
                    status: processing
                    subStatus: processing.cashPickupReady
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    precursor:
                      type: quote
                      id: qt_3qj8x54e73641hrabft05xc6fv
                    source:
                      type: walletCrypto
                      id: wlt_5h4jzzpr9xre3bamd9ca7qyghn
                      asset: usdc
                      network: polygon
                      details:
                        address: '0x7B3A9F2C4D1eA8bf6390cE5D2b7fA104c8e3D9B1'
                    destination:
                      type: cash
                      asset: usd
                      details:
                        locationId: loc_01H9Xd
                        locationName: 'Walmart #2517'
                        locationAddress:
                          line1: 123 Main St
                          city: San Francisco
                          state: CA
                          zipCode: '94105'
                          country: US
                      pickupCode: '8847162'
                    pricing:
                      source:
                        asset: usdc
                        amount: '100.000000'
                      destination:
                        asset: usd
                        amount: '100.00'
                      fees: []
                      exchangeRate: '1.0000'
                      fixedAmountSide: destination
                      sponsorGas: true
                    createdAt: '2026-03-14T20:00:00Z'
                    updatedAt: '2026-03-14T20:00:30Z'
                Completed payout from an OMS wallet to a US bank account:
                  summary: Completed payout from an OMS wallet to a US bank account
                  value:
                    id: txn_qv6ch9rjv7t8nncezke4s10a3z
                    status: completed
                    subStatus: completed.settled
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    precursor:
                      type: quote
                      id: qt_0gq9aesz4wb5etdv88z1j61qcm
                    source:
                      type: walletCrypto
                      id: wlt_5h4jzzpr9xre3bamd9ca7qyghn
                      asset: usdc
                      network: polygon
                      details:
                        address: '0x7B3A9F2C4D1eA8bf6390cE5D2b7fA104c8e3D9B1'
                    destination:
                      owner:
                        kind: counterparty
                        id: ctp_yp5z8m7n22svc0vh6edqgcfdat
                        name: Alice Smith
                      type: bankUs
                      id: ext_fky491gakzj0dd46qb6whsr2vq
                      asset: usd
                      details:
                        bankName: 'Example Bank, N.A.'
                        accountNumberLast4: '1234'
                        routingNumber: '123456789'
                        accountType: checking
                        holderName: Alice Smith
                    pricing:
                      source:
                        asset: usdc
                        amount: '100.000000'
                      destination:
                        asset: usd
                        amount: '100.00'
                      fees: []
                      exchangeRate: '1.0000'
                      fixedAmountSide: source
                      sponsorGas: true
                    transfers:
                      - id: trf_qv6ch9rjv7t8nncezke4s10a3z
                        role: payout
                        rail: ach
                        attempt: 1
                    metadata:
                      orderId: order_12345
                    createdAt: '2026-03-14T19:00:00Z'
                    updatedAt: '2026-03-14T19:05:00Z'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionNotFoundErrorResponse'
      tags:
        - Transaction
  '/transfers/{transferId}':
    get:
      operationId: getTransfer
      summary: Get transfer by ID
      description: Retrieves one transfer of a transaction by ID.
      parameters:
        - name: transferId
          in: path
          required: true
          description: Transfer ID (`trf_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transfer'
              examples:
                A settled wire payout from a deposit address:
                  summary: A settled wire payout from a deposit address
                  value:
                    id: trf_01k7n3h6x2v9c8b4m5q0w1e2r3
                    transactionId: txn_qv6ch9rjv7t8nncezke4s10a3z
                    role: payout
                    rail: wire
                    attempt: 1
                    status: settled
                    amount:
                      amount: '100.00'
                      asset: usd
                    from:
                      type: depositAddress
                      id: da_r8f126hqwm3x6j5k00qsaysf4c
                      asset: usdc
                      network: polygon
                    to:
                      owner:
                        kind: counterparty
                        id: ctp_yp5z8m7n22svc0vh6edqgcfdat
                        name: Alice Smith
                      type: bankUs
                      id: ext_fky491gakzj0dd46qb6whsr2vq
                      asset: usd
                      details:
                        accountNumberLast4: '1234'
                        holderName: Alice Smith
                    tracking:
                      imad: 20261016MMQFMP2K000001
                      uetr: 8a562c67-ca16-48ba-b074-65581be6f001
                    createdAt: '2026-03-14T19:00:00Z'
                    updatedAt: '2026-03-14T19:05:00Z'
                    settledAt: '2026-03-14T19:05:00Z'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransferNotFoundErrorResponse'
      tags:
        - Transfer
  /virtual-accounts:
    get:
      operationId: listVirtualAccounts
      summary: List all Virtual Accounts
      description: >-
        List all Virtual Accounts across the organization. Spans every customer
        in the caller's organization; optionally filter by status and/or
        customer.
      parameters:
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: status
          in: query
          required: false
          description: >-
            Filter by status. `deleted` returns Virtual Accounts whose close
            flow has finalized; they are excluded from every other filter and
            from the unfiltered list.
          schema:
            $ref: '#/components/schemas/VirtualAccountStatus'
        - name: customerId
          in: query
          required: false
          description: Filter to a single customer (`cst_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VirtualAccountList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InvalidCursorErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - VirtualAccount
    post:
      operationId: createVirtualAccount
      summary: Create a Virtual Account
      description: >-
        Create a Virtual Account for a customer. Partner must have
        virtual_account_provider configured.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '201':
          description: >-
            The request has succeeded and a new resource has been created as a
            result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VirtualAccount'
              example:
                id: va_8rzhjp17c4kdp2n3gg79te9zmw
                customer:
                  id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                status: pending
                provider: 'Example Bank, N.A.'
                destination:
                  type: walletExternal
                  id: ext_fky491gakzj0dd46qb6whsr2vq
                  asset: usdc
                  network: ethereum
                  details:
                    address: '0x7B3A9F2C4D1eA8bf6390cE5D2b7fA104c8e3D9B1'
                sponsorGas: true
                label: Alice USD deposit account
                createdAt: '2026-05-14T10:00:00Z'
                updatedAt: '2026-05-14T10:00:00Z'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidMetadataErrorResponse'
                  - $ref: '#/components/schemas/MetadataKeyTooLongErrorResponse'
                  - $ref: '#/components/schemas/MetadataTooManyKeysErrorResponse'
                  - $ref: '#/components/schemas/MetadataValueTooLongErrorResponse'
                  - $ref: '#/components/schemas/MissingParameterErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/CoinmeVirtualAccountsNotEnabledErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationRailNotAllowedErrorResponse
                  - $ref: '#/components/schemas/EreborConfigMissingErrorResponse'
                  - $ref: '#/components/schemas/TransferPairNotPermittedErrorResponse'
                  - $ref: '#/components/schemas/VendorAmbiguousErrorResponse'
                  - $ref: '#/components/schemas/VendorConfigMissingErrorResponse'
                  - $ref: >-
                      #/components/schemas/VendorVirtualAccountUnavailableErrorResponse
                  - $ref: >-
                      #/components/schemas/VirtualAccountProviderSetupIncompleteErrorResponse
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/CustodialWalletUnavailableErrorResponse
                  - $ref: '#/components/schemas/DestinationNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/CoinmeAddressClaimedByOtherFlowErrorResponse
                  - $ref: '#/components/schemas/ConflictErrorResponse'
                  - $ref: >-
                      #/components/schemas/VirtualAccountWalletInUseErrorResponse
                  - $ref: >-
                      #/components/schemas/WalletIsVirtualAccountDestinationErrorResponse
        '422':
          description: >-
            The Virtual Account could not be created because the request failed
            validation or the requested configuration is not supported.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/EreborValidationFailedErrorResponse'
                  - $ref: '#/components/schemas/AccountHolderUnsupportedErrorResponse'
                  - $ref: '#/components/schemas/AccountNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/AccountTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/AddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/BICInvalidErrorResponse'
                  - $ref: '#/components/schemas/BlockchainAddressInvalidErrorResponse'
                  - $ref: '#/components/schemas/CardMustUseCardEndpointErrorResponse'
                  - $ref: '#/components/schemas/CountryInvalidErrorResponse'
                  - $ref: '#/components/schemas/CustodianInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/CustomerNotEnrolledWithVendorErrorResponse
                  - $ref: '#/components/schemas/DateOfBirthInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationInvalidReferenceErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationNetworkUnsupportedErrorResponse
                  - $ref: '#/components/schemas/DestinationNotActiveErrorResponse'
                  - $ref: '#/components/schemas/DestinationRequiredErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeMismatchErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationWalletCryptoNotSupportedErrorResponse
                  - $ref: '#/components/schemas/DestinationWrongTypeErrorResponse'
                  - $ref: '#/components/schemas/EmailInvalidErrorResponse'
                  - $ref: '#/components/schemas/EntityTypeInvalidErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExpectedSourceAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/ExpectedSourceNetworkUnsupportedErrorResponse
                  - $ref: '#/components/schemas/ExpectedSourceRequiredErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExternalAccountIDRequiredErrorResponse
                  - $ref: '#/components/schemas/IBANInvalidErrorResponse'
                  - $ref: '#/components/schemas/InstitutionNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/LimitExceededErrorResponse'
                  - $ref: '#/components/schemas/MemoNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/NameInvalidErrorResponse'
                  - $ref: '#/components/schemas/NationalityInvalidErrorResponse'
                  - $ref: '#/components/schemas/NetworkFamilyInvalidErrorResponse'
                  - $ref: '#/components/schemas/NoRouteAvailableErrorResponse'
                  - $ref: '#/components/schemas/OtherCustodianRequiredErrorResponse'
                  - $ref: '#/components/schemas/OtherCustodianTooLongErrorResponse'
                  - $ref: '#/components/schemas/OwnerInvalidErrorResponse'
                  - $ref: '#/components/schemas/PhoneInvalidErrorResponse'
                  - $ref: '#/components/schemas/ProjectMissingCoinmeIDErrorResponse'
                  - $ref: '#/components/schemas/RailNotSupportedErrorResponse'
                  - $ref: >-
                      #/components/schemas/ReturnDestinationMustBeMultiAssetErrorResponse
                  - $ref: '#/components/schemas/ReturnWalletInvalidErrorResponse'
                  - $ref: '#/components/schemas/RouteDisabledErrorResponse'
                  - $ref: '#/components/schemas/RoutingNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/TaxIDInvalidErrorResponse'
                  - $ref: '#/components/schemas/TransitNumberInvalidErrorResponse'
                  - $ref: '#/components/schemas/TypeUnsupportedErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedDestinationErrorResponse'
                  - $ref: >-
                      #/components/schemas/UnsupportedWithdrawalConstraintErrorResponse
                  - $ref: '#/components/schemas/ValidationErrorResponse'
                  - $ref: '#/components/schemas/WalletCustomerMismatchErrorResponse'
                  - $ref: >-
                      #/components/schemas/WalletExternalBusinessOnlyErrorResponse
                  - $ref: '#/components/schemas/WalletNotActiveErrorResponse'
                  - $ref: >-
                      #/components/schemas/WalletProvisioningRejectedErrorResponse
        '500':
          description: Server error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/EreborResponseInvalidErrorResponse'
                  - $ref: '#/components/schemas/InternalErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
      tags:
        - VirtualAccount
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VirtualAccountCreateRequest'
  '/virtual-accounts/{virtualAccountId}':
    delete:
      operationId: deleteVirtualAccount
      summary: Delete a Virtual Account
      description: >-
        Delete a customer's Virtual Account. The close is executed with the
        institution that backs it: the VA enters a delete-pending window (status
        unchanged, `deletionRequestedAt` set) and finalizes to `deleted` once
        the provider confirms the close, answering 204 on a completed delete.


        A VA that cannot be deleted in its current state is rejected with 409 —
        `CannotDeletePendingVirtualAccount` while it is still provisioning,
        `NonZeroBalance` while it holds funds, `PendingTransactionsExist` while
        a deposit is still in flight, and `DeleteInProgress` when a concurrent
        DELETE has already stamped the marker. A later DELETE on a VA whose
        close is still pending resumes that same close rather than being
        refused. 409 `VirtualAccountNotFoundAtProvider` means the provider
        cannot find the account being closed; nothing is deleted or failed
        locally and retrying will not clear it. 422
        `VirtualAccountCloseRejected` means the provider terminally rejected the
        close and the VA moves to `failed`. 501 `DeleteNotSupported` means the
        provider has no delete for this account type.


        On 503 `VirtualAccountCloseUnavailable` the provider does not yet offer
        a close for this account: the call goes out and comes back refused, and
        `deletionRequestedAt` is cleared, whether this request set it or an
        earlier one did. The Virtual Account's status is not changed and it can
        be deleted again, so retry after the interval given in `Retry-After`. A
        concurrent write on the same Virtual Account can block that clear and
        leave `deletionRequestedAt` set; a later DELETE resolves it.


        502 `VirtualAccountProviderUnavailable` means the close did not
        complete. It covers a failure at the provider, a failed live balance
        read behind the `NonZeroBalance` check, and a Virtual Account whose
        institution offers no close through this API, so it does not by itself
        mean that anything was sent. Read `deletionRequestedAt` afterwards to
        tell whether the Virtual Account is untouched or left in the
        delete-pending window; one already in that window stays in it. Retrying
        is safe either way: a DELETE on a delete-pending Virtual Account resumes
        the same close. On 502 `VirtualAccountUnexpectedCloseStatus` (the
        provider returned an account status the close flow does not recognise)
        the provider did receive and attempt the close, so the VA stays in the
        delete-pending window with `deletionRequestedAt` set: retryable, but not
        untouched.
      parameters:
        - name: virtualAccountId
          in: path
          required: true
          description: Virtual Account ID (`va_` prefix).
          schema:
            type: string
      responses:
        '204':
          description: >-
            There is no content to send for this request, but the headers may be
            useful.
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EreborConfigMissingErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VirtualAccountNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/CannotDeletePendingVirtualAccountErrorResponse
                  - $ref: '#/components/schemas/DeleteInProgressErrorResponse'
                  - $ref: '#/components/schemas/NonZeroBalanceErrorResponse'
                  - $ref: '#/components/schemas/PendingTransactionsExistErrorResponse'
                  - $ref: >-
                      #/components/schemas/VirtualAccountNotFoundAtProviderErrorResponse
        '422':
          description: Client error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VirtualAccountCloseRejectedErrorResponse'
        '501':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DeleteNotSupportedErrorResponse'
        '502':
          description: Server error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/VirtualAccountProviderUnavailableErrorResponse
                  - $ref: >-
                      #/components/schemas/VirtualAccountUnexpectedCloseStatusErrorResponse
        '503':
          description: >-
            The Virtual Account cannot be closed because its provider does not
            offer account closure through this API.
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/VirtualAccountCloseUnavailableErrorResponse
      tags:
        - VirtualAccount
    get:
      operationId: getVirtualAccount
      summary: Get a Virtual Account
      description: >-
        Fetch a Virtual Account by ID. A `deleted` Virtual Account stays
        readable and keeps its final `status`; its `depositInstructions` are
        omitted.
      parameters:
        - name: virtualAccountId
          in: path
          required: true
          description: Virtual Account ID (`va_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VirtualAccount'
              examples:
                Active virtual account with US bank routing details:
                  summary: Active virtual account with US bank routing details
                  value:
                    id: va_bztg5dcpfbec9s0jkq28d5meq3
                    customer:
                      id: cst_vfa0nxw6zvyws9g237jrxn4y7k
                    status: active
                    depositInstructions:
                      bankUs:
                        - supportedSources:
                            - asset: usd
                              rail: ach
                            - asset: usd
                              rail: achSameDay
                            - asset: usd
                              rail: rtp
                            - asset: usd
                              rail: wire
                          bankName: 'Example Bank, N.A.'
                          bankAddress: '100 Example Plaza, Seattle, WA 98101 US'
                          accountNumber: '9876543210'
                          routingNumber: '123456789'
                          accountType: checking
                    provider: 'Example Bank, N.A.'
                    destination:
                      type: walletExternal
                      id: ext_fky491gakzj0dd46qb6whsr2vq
                      asset: usdc
                      network: ethereum
                      details:
                        address: '0x7B3A9F2C4D1eA8bf6390cE5D2b7fA104c8e3D9B1'
                    sponsorGas: true
                    label: Alice USD deposit account
                    createdAt: '2026-03-14T19:00:00Z'
                    updatedAt: '2026-03-14T19:01:26Z'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VirtualAccountNotFoundErrorResponse'
      tags:
        - VirtualAccount
    patch:
      operationId: updateVirtualAccount
      summary: Update a Virtual Account
      description: >-
        Update a Virtual Account. Patchable fields: `destination` (re-point),
        `sponsorGas`, `label`, `metadata`; any other JSON key is rejected with
        400. For an Erebor-vendored VA, re-pointing `destination` to a healthy
        External Account recovers it from `inactiveActionRequired` back to
        `active`. A Coinme-vendored VA has no PATCH-time recovery story: it only
        accepts a re-point while already `active`, and rejects anything else.


        `CustodialWalletUnavailableErrorResponse` (10304) is declared here, not
        just on `createVirtualAccount`, because a `walletCrypto` re-point
        resolves the destination through the SAME resolver the create path uses.
        That resolver writes 10304 directly, so a walletCrypto PATCH re-point
        can surface it too.
      parameters:
        - name: virtualAccountId
          in: path
          required: true
          description: Virtual Account ID (`va_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VirtualAccount'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidRequestErrorResponse'
                  - $ref: '#/components/schemas/MissingParameterErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/DestinationRailNotAllowedErrorResponse
                  - $ref: >-
                      #/components/schemas/VirtualAccountProviderSetupIncompleteErrorResponse
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/CustodialWalletUnavailableErrorResponse
                  - $ref: '#/components/schemas/DestinationNotFoundErrorResponse'
                  - $ref: '#/components/schemas/VirtualAccountNotFoundErrorResponse'
                  - $ref: >-
                      #/components/schemas/VirtualAccountUpdateCustodialWalletUnavailableErrorResponse
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ConflictErrorResponse'
                  - $ref: '#/components/schemas/DANotRecoverableErrorResponse'
                  - $ref: '#/components/schemas/VANotRecoverableErrorResponse'
                  - $ref: >-
                      #/components/schemas/VirtualAccountUpdateNotSupportedForVendorErrorResponse
                  - $ref: >-
                      #/components/schemas/VirtualAccountWalletInUseErrorResponse
                  - $ref: >-
                      #/components/schemas/WalletIsVirtualAccountDestinationErrorResponse
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AccountHolderUnsupportedErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationAssetUnsupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationInvalidReferenceErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationNetworkUnsupportedErrorResponse
                  - $ref: '#/components/schemas/DestinationNotActiveErrorResponse'
                  - $ref: '#/components/schemas/DestinationRequiredErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeInvalidErrorResponse'
                  - $ref: '#/components/schemas/DestinationTypeMismatchErrorResponse'
                  - $ref: >-
                      #/components/schemas/DestinationTypeSwitchNotSupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/DestinationWalletCryptoNotSupportedErrorResponse
                  - $ref: '#/components/schemas/DestinationWrongTypeErrorResponse'
                  - $ref: >-
                      #/components/schemas/ExternalAccountIDRequiredErrorResponse
                  - $ref: '#/components/schemas/MemoNotSupportedErrorResponse'
                  - $ref: '#/components/schemas/NoRouteAvailableErrorResponse'
                  - $ref: '#/components/schemas/RailNotSupportedErrorResponse'
                  - $ref: >-
                      #/components/schemas/ReturnDestinationMustBeMultiAssetErrorResponse
                  - $ref: '#/components/schemas/ReturnWalletInvalidErrorResponse'
                  - $ref: '#/components/schemas/RouteDisabledErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedDestinationErrorResponse'
                  - $ref: '#/components/schemas/ValidationErrorResponse'
                  - $ref: >-
                      #/components/schemas/VirtualAccountCustodialWalletChangeNotSupportedErrorResponse
                  - $ref: >-
                      #/components/schemas/VirtualAccountUpdateProvisioningRejectedErrorResponse
                  - $ref: '#/components/schemas/WalletCustomerMismatchErrorResponse'
                  - $ref: '#/components/schemas/WalletNotActiveErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
      tags:
        - VirtualAccount
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VirtualAccountUpdateRequest'
  '/virtual-accounts/{virtualAccountId}/simulate/inbound-transfer':
    post:
      operationId: simulateVirtualAccountInboundTransfer
      summary: Simulate inbound transfer on a Virtual Account
      description: >-
        Simulate an inbound fiat transfer against a Virtual Account, for testing
        webhook and reconciliation flows. Sandbox / non-production only; returns
        404 in production-live. Set the `type` field in the request body to
        choose the transfer rail: `bankUs` (network `ach`, `wire` or `rtp`) or
        `bankIban` (network `swift`). Not every rail is available on every
        Virtual Account; one whose provider does not offer the requested rail
        refuses the request. The `Idempotency-Key` header is required and is
        deduplicated before the provider is called: a retry carrying the same
        key replays the recorded response and never reaches the provider again.
        A retry with a new key is a new request, and on a Virtual Account whose
        provider models no idempotency key of its own it books a second credit.
      parameters:
        - name: virtualAccountId
          in: path
          required: true
          schema:
            type: string
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SimulateVaInboundTransferResponse'
              examples:
                International SWIFT inbound (settles asynchronously):
                  summary: International SWIFT inbound (settles asynchronously)
                  value:
                    virtualAccountId: va_bztg5dcpfbec9s0jkq28d5meq3
                    type: bankIban
                    network: swift
                    asset: usd
                    amount: '10.00'
                    status: pending
                    submittedAt: '2026-07-13T19:05:00Z'
                    referenceId: intl_wire_in_9f3c2a7b8d1e4056
                US domestic ACH inbound:
                  summary: US domestic ACH inbound
                  value:
                    virtualAccountId: va_bztg5dcpfbec9s0jkq28d5meq3
                    type: bankUs
                    network: ach
                    asset: usd
                    amount: '5.00'
                    status: submitted
                    submittedAt: '2026-07-13T19:00:00Z'
                    referenceId: null
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AmountExceedsCapErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/NotFoundErrorResponse'
      tags:
        - Sandbox
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SimulateVaInboundTransferRequest'
            examples:
              International SWIFT inbound (settles asynchronously):
                summary: International SWIFT inbound (settles asynchronously)
                value:
                  type: bankIban
                  network: swift
                  asset: usd
                  amount: '10.00'
              US domestic ACH inbound:
                summary: US domestic ACH inbound
                value:
                  type: bankUs
                  network: ach
                  asset: usd
                  amount: '5.00'
      x-server-scope: non-prod-live
  '/virtual-accounts/{virtualAccountId}/transactions':
    get:
      operationId: listVirtualAccountTransactions
      summary: List Virtual Account transactions
      description: >-
        Returns the payment transactions that originated from this Virtual
        Account, most recent first, with cursor-based pagination. Uses the same
        grouped payment read model as `GET /transactions`, pinned to this
        virtual account (equivalent to `GET /transactions?virtualAccountId=`).


        This is a collection filter: it always returns `200` with the matching
        transactions. An unknown, deleted, or other-tenant `virtualAccountId`
        simply matches no rows and yields an empty list — it is not a `404`. Use
        `GET /virtual-accounts/{virtualAccountId}` to assert
        existence/ownership.
      parameters:
        - name: virtualAccountId
          in: path
          required: true
          description: Virtual Account ID (`va_` prefix).
          schema:
            type: string
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: status
          in: query
          required: false
          description: Filter by status.
          schema:
            type: array
            items:
              $ref: '#/components/schemas/TransactionStatus'
        - name: sourceToDestination
          in: query
          required: false
          description: Filter by corridor (source/destination category composite).
          schema:
            type: array
            items:
              $ref: '#/components/schemas/SourceToDestination'
        - name: customerId
          in: query
          required: false
          description: Scope to a customer (sender or recipient). `cst_` prefix.
          schema:
            type: string
        - name: createdAfter
          in: query
          required: false
          description: Inclusive lower bound on `createdAt`.
          schema:
            type: string
            format: date-time
        - name: createdBefore
          in: query
          required: false
          description: Inclusive upper bound on `createdAt`.
          schema:
            type: string
            format: date-time
        - name: search
          in: query
          required: false
          description: >-
            Free-text search. Matches transaction id, customer id, or customer
            email.
          schema:
            type: string
        - name: q
          in: query
          required: false
          description: Alias for `search`.
          schema:
            type: string
        - name: legStatus
          in: query
          required: false
          description: >-
            Filters to payments where ANY leg's underlying status is in the
            given set.
          schema:
            type: array
            items:
              type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransactionList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidFilterErrorResponse'
                  - $ref: '#/components/schemas/InvalidCursorErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - VirtualAccount
  /wallets:
    get:
      operationId: listWallets
      summary: List wallets
      description: >-
        Lists the balance-holding wallets provisioned in the project, most
        recent first — `fiat` and `custodial` — unless `orderBy=balance` is set.
        Balance ordering uses available balance valued in USD; balances without
        a USD estimate are placed last. The default direction is descending.
        Balance ordering uses live values, not a point-in-time snapshot. Balance
        or token decimal metadata changes between pages can cause wallets to be
        skipped or repeated during traversal. Internal deposit-routing addresses
        and native gas-token wallets (e.g. `pol`, `eth`, `sol`) are not
        returned. Omitting `customerId` returns every wallet in the project;
        providing it scopes the list to that customer. A well-formed
        `customerId` that matches no customer returns an empty list; a
        present-but-blank `customerId` is a 400. Each item carries `customer`,
        an object holding the owning customer's `id`. When `customerId` names a
        customer enrolled with the custody provider and `type` is either omitted
        or `custodial`, the listing refreshes that customer's custodial wallets
        from the custody provider before rendering; every other request, the
        project-wide listing included, is served from OMS's own records with no
        per-request provider call. Balances are re-read on that same refresh
        only once the stored values have aged past a freshness window. The
        refresh is best-effort and no failure of it is ever surfaced, whatever
        its cause: the response carries the records OMS holds. Balance ordering
        requires stored balances and token decimal metadata; failure to load
        either returns 500.
      parameters:
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: customerId
          in: query
          required: false
          description: Scope to a customer. `cst_` prefix.
          schema:
            type: string
        - name: type
          in: query
          required: false
          description: >-
            Filter by wallet type: `custodial` and `fiat` return rows whose
            `type` is `walletCrypto` and `walletFiat`. An empty value is treated
            as omitted. `noncustodial` currently returns an empty list.
          schema:
            $ref: '#/components/schemas/WalletVariant'
        - name: search
          in: query
          required: false
          description: Free-text search. Matches wallet id or on-chain address.
          schema:
            type: string
        - name: q
          in: query
          required: false
          description: Alias for `search`.
          schema:
            type: string
        - name: orderBy
          in: query
          required: false
          description: Order by available balance's estimated USD value.
          schema:
            $ref: '#/components/schemas/WalletListOrderBy'
        - name: order
          in: query
          required: false
          description: >-
            Balance sort direction. Defaults to `desc`; requires
            `orderBy=balance`.
          schema:
            $ref: '#/components/schemas/WalletListOrderDirection'
        - name: includeHidden
          in: query
          required: false
          description: >-
            `claimed` adds wallets that a live deposit address or virtual
            account currently claims, which the default page leaves out. It also
            includes custodial wallets the default page leaves out for address
            reuse. Omitting this param leaves default behavior unchanged.
          schema:
            type: array
            items:
              $ref: '#/components/schemas/WalletListHidden'
          explode: false
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidCustomerIDErrorResponse'
                  - $ref: '#/components/schemas/InvalidCursorErrorResponse'
                  - $ref: '#/components/schemas/InvalidParameterErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - Wallet
    post:
      operationId: createWallet
      summary: Create a wallet
      description: >-
        Creates a wallet for a customer. Polymorphic on `type`: `fiat` and
        `custodial` are implemented — `noncustodial` is accepted by the request
        discriminator but rejected with 501 `WalletTypeNotSupported`. Pass an
        `Idempotency-Key` header to safely retry without provisioning
        duplicates; a replay returns the same response, including the same
        operation `Location`.


        A `fiat` create requires the project to be configured for fiat wallets
        at "Erebor Bank, N.A." (403 `EreborConfigMissing`), the fiat-wallet
        book-transfer rail enabled for the project (403
        `DestinationRailNotAllowed`), and the customer registered with that bank
        (400 `EreborCustomerNotMapped`); the wallet starts `pending` and becomes
        `active` once the bank opens the backing account. The
        `customerWallet.created` webhook fires when the wallet is first recorded
        and carries `pending`; `customerWallet.statusChanged` to `active`
        follows when the bank opens the account. A `custodial` create requires
        the project and the customer to be enrolled with the custody provider
        (422 `ProjectMissingCoinmeID`, 422 `ProviderUserAccountNotFound`), an
        active `cryptoCustody` endorsement when the project requires one (400
        `CryptoCustodyInactive`), and an asset/network pair that provider
        supports (422 `UnsupportedAsset`); it returns `201` with the wallet when
        the wallet already exists or the provider confirms it synchronously, and
        `202` with a `Location` header pointing at the wallet-provisioning
        operation — poll `GET /wallets/operations/{operationId}` — when
        confirmation arrives asynchronously. A durable provider rejection is 422
        `WalletProvisioningRejected`.
      parameters:
        - $ref: '#/components/parameters/IdempotencyKeyHeader'
      responses:
        '201':
          description: >-
            The request has succeeded and a new resource has been created as a
            result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletResource'
        '202':
          description: >-
            The request has been accepted for processing, but processing has not
            yet completed.
          headers:
            Location:
              required: true
              description: URL of the wallet-provisioning operation to poll for completion.
              schema:
                type: string
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletOperation'
        '400':
          description: The wallet request body could not be decoded.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/WalletInvalidRequestBodyErrorResponse'
                  - $ref: '#/components/schemas/InvalidCustomerIDErrorResponse'
                  - $ref: '#/components/schemas/CryptoCustodyInactiveErrorResponse'
                  - $ref: '#/components/schemas/EreborCustomerNotMappedErrorResponse'
                  - $ref: '#/components/schemas/InvalidWalletTypeErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/DestinationRailNotAllowedErrorResponse
                  - $ref: '#/components/schemas/EreborConfigMissingErrorResponse'
                  - $ref: '#/components/schemas/KYCRequiredErrorResponse'
        '404':
          description: A customer could not be found within the wallet's project.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletCustomerNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ConflictErrorResponse'
                  - $ref: '#/components/schemas/FiatWalletLimitReachedErrorResponse'
        '413':
          description: Client error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestTooLargeErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/EreborValidationFailedErrorResponse'
                  - $ref: '#/components/schemas/IdempotencyKeyReuseErrorResponse'
                  - $ref: '#/components/schemas/ProjectMissingCoinmeIDErrorResponse'
                  - $ref: >-
                      #/components/schemas/ProviderUserAccountNotFoundErrorResponse
                  - $ref: '#/components/schemas/UnsupportedAssetErrorResponse'
                  - $ref: >-
                      #/components/schemas/WalletProvisioningRejectedErrorResponse
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '501':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletTypeNotSupportedErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
      tags:
        - Wallet
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WalletRequest'
  '/wallets/operations/{operationId}':
    get:
      operationId: getWalletOperation
      summary: Get a wallet-provisioning operation
      description: >-
        Fetch a wallet-provisioning operation — the status resource a `202` from
        POST /wallets points at. Project-scoped to the caller.
      parameters:
        - name: operationId
          in: path
          required: true
          description: Operation ID (`op_` prefix).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletOperation'
      tags:
        - Wallet
  '/wallets/{id}':
    get:
      operationId: getWallet
      summary: Get a wallet
      description: >-
        Fetch a wallet by ID. Serves both fiat and custodial wallets by their
        shared `wlt_` id; the response variant is discriminated by the `type`
        field. A `wlt_fiat_` id is also accepted.
      parameters:
        - name: id
          in: path
          required: true
          description: Wallet ID (`wlt_` prefix; a `wlt_fiat_` id is also accepted).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletResource'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidCustomerIDErrorResponse'
                  - $ref: '#/components/schemas/InvalidParameterErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '404':
          description: A customer could not be found within the wallet's project.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/WalletCustomerNotFoundErrorResponse'
                  - $ref: '#/components/schemas/WalletResourceNotFoundErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - Wallet
    patch:
      operationId: updateWallet
      summary: Update a wallet
      description: >-
        Update a wallet's mutable presentation fields. Only `label` is mutable;
        send an empty string to clear it. Serves both fiat and custodial wallets
        by their shared `wlt_` id, matching `getWallet`.
      parameters:
        - name: id
          in: path
          required: true
          description: Wallet ID (`wlt_` prefix; a `wlt_fiat_` id is also accepted).
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletResource'
        '400':
          description: The wallet request body could not be decoded.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/WalletInvalidRequestBodyErrorResponse'
                  - $ref: '#/components/schemas/WalletUnknownFieldErrorResponse'
                  - $ref: '#/components/schemas/InvalidCustomerIDErrorResponse'
                  - $ref: '#/components/schemas/InvalidParameterErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '404':
          description: A customer could not be found within the wallet's project.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/WalletCustomerNotFoundErrorResponse'
                  - $ref: '#/components/schemas/WalletResourceNotFoundErrorResponse'
        '409':
          description: The request conflicts with the current state of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VersionConflictErrorResponse'
        '413':
          description: Client error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestTooLargeErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EmptyUpdateErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - Wallet
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/WalletUpdateRequest'
  '/wallets/{id}/balance':
    get:
      operationId: getWalletBalance
      summary: >-
        Get current balance of a specific wallet (deprecated, use GET
        /wallets/{id})
      description: >-
        Returns the current balance of a specific wallet, including the display
        balance and its estimated value in the currency requested via
        `estimatedBalanceCurrencyCode` (defaults to USD).


        Deprecated — the same balances are carried by `balances[]` on `GET
        /wallets/{id}`, whose estimate is USD-only: there is no
        `estimatedBalanceCurrencyCode` equivalent there, so a caller requesting
        a non-USD estimate loses it on migration. Every response, success and
        error alike, carries `Deprecation` and `Sunset` headers as HTTP-dates;
        `Sunset` is the date this route is removed.
      parameters:
        - name: id
          in: path
          required: true
          description: Wallet ID.
          schema:
            type: string
        - name: estimatedBalanceCurrencyCode
          in: query
          required: false
          description: ISO 4217 currency for the estimated value. Defaults to USD.
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletBalance'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidParamsErrorResponse'
                  - $ref: '#/components/schemas/CustomerRejectedErrorResponse'
                  - $ref: '#/components/schemas/InvalidCustomerIDErrorResponse'
                  - $ref: '#/components/schemas/InvalidParameterErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/KYCRequiredErrorResponse'
                  - $ref: '#/components/schemas/VendorConfigMissingErrorResponse'
        '404':
          description: The server cannot find the requested resource.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/AccountNotFoundErrorResponse'
                  - $ref: '#/components/schemas/PaymentMethodNotFoundErrorResponse'
                  - $ref: '#/components/schemas/WalletCustomerNotFoundErrorResponse'
                  - $ref: '#/components/schemas/WalletResourceNotFoundErrorResponse'
        '409':
          description: The provider quote expired before the wallet request completed.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/WalletQuoteExpiredErrorResponse'
                  - $ref: '#/components/schemas/WalletProviderConflictErrorResponse'
        '422':
          description: Client error
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: >-
                      #/components/schemas/ProviderUserAccountNotFoundErrorResponse
                  - $ref: '#/components/schemas/InsufficientFundsErrorResponse'
                  - $ref: '#/components/schemas/UnsupportedCorridorErrorResponse'
                  - $ref: '#/components/schemas/WalletProviderRejectedErrorResponse'
                  - $ref: '#/components/schemas/ProjectMissingCoinmeIDErrorResponse'
        '429':
          description: The provider's wallet request limit was exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/WalletProviderRateLimitErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
        '502':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProviderRequestFailedErrorResponse'
        '503':
          description: Service unavailable.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/ServiceUnavailableErrorResponse'
                  - $ref: '#/components/schemas/ProviderTimeoutErrorResponse'
                  - $ref: '#/components/schemas/ProviderUnreachableErrorResponse'
      tags:
        - Wallet
      deprecated: true
      x-deprecated-reason: 'Use balances[] on GET /wallets/{id} instead'
  '/wallets/{id}/transactions':
    get:
      operationId: listWalletTransactions
      summary: 'List wallet transactions (deprecated, use GET /transactions?walletId=)'
      description: >-
        Returns the transaction history for the specified wallet, most recent
        first, with cursor-based pagination and optional type/date filters. Each
        entry is a single ledger movement on the wallet — credit, debit, hold,
        or release — covering both inbound and outbound activity. `balanceAfter`
        is a snapshot taken when the entry was written, not a guaranteed running
        total.


        Deprecated — use `GET /transactions?walletId=` instead, which accepts
        the canonical `wlt_` id plus the older `acc_` and `wlt_fiat_` forms.
        Every response, success and error alike, carries `Deprecation` and
        `Sunset` headers as HTTP-dates; `Sunset` is the date this route is
        removed.
      parameters:
        - name: id
          in: path
          required: true
          description: Wallet ID (`wlt_` prefix).
          schema:
            type: string
        - $ref: '#/components/parameters/PaginationParams.limit'
        - $ref: '#/components/parameters/PaginationParams.startingAfter'
        - $ref: '#/components/parameters/PaginationParams.endingBefore'
        - name: transactionType
          in: query
          required: false
          description: Filter by ledger entry type.
          schema:
            $ref: '#/components/schemas/TransactionType'
        - name: since
          in: query
          required: false
          description: Inclusive start of the date range.
          schema:
            type: string
        - name: until
          in: query
          required: false
          description: Inclusive end of the date range.
          schema:
            type: string
      responses:
        '200':
          description: The request has succeeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AccountTransactionList'
        '400':
          description: The server could not understand the request due to invalid syntax.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/InvalidCursorErrorResponse'
                  - $ref: '#/components/schemas/InvalidParameterErrorResponse'
                  - $ref: '#/components/schemas/InvalidCustomerIDErrorResponse'
        '401':
          description: Access is unauthorized.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UnauthorizedErrorResponse'
        '403':
          description: Access is forbidden.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/VendorConfigMissingErrorResponse'
        '404':
          description: A customer could not be found within the wallet's project.
          content:
            application/json:
              schema:
                anyOf:
                  - $ref: '#/components/schemas/WalletCustomerNotFoundErrorResponse'
                  - $ref: '#/components/schemas/WalletResourceNotFoundErrorResponse'
        '500':
          description: Server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InternalErrorResponse'
      tags:
        - Wallet
      deprecated: true
      x-deprecated-reason: Use GET /transactions?walletId= instead
  /v1/IndexerGateway/GetBalanceUpdates:
    post:
      operationId: IndexerGateway-GetBalanceUpdates
      summary: Get balance updates
      description: >-
        Returns token balances for a contract that changed after a given block,
        paginated. Pass `lastBlockNumber` and `lastBlockHash` to resume from the
        last block you processed.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IndexerGateway_GetBalanceUpdates_Request'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IndexerGateway_GetBalanceUpdates_Response'
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
                  - $ref: '#/components/schemas/ErrorAborted'
                  - $ref: '#/components/schemas/ErrorAccessKeyMismatch'
                  - $ref: '#/components/schemas/ErrorAccessKeyNotFound'
                  - $ref: '#/components/schemas/ErrorAtLeastOneKey'
                  - $ref: '#/components/schemas/ErrorGeoblocked'
                  - $ref: '#/components/schemas/ErrorInvalidArgument'
                  - $ref: '#/components/schemas/ErrorInvalidOrigin'
                  - $ref: '#/components/schemas/ErrorInvalidService'
                  - $ref: '#/components/schemas/ErrorMaxAccessKeys'
                  - $ref: '#/components/schemas/ErrorMetadataCallFailed'
                  - $ref: '#/components/schemas/ErrorMethodNotFound'
                  - $ref: '#/components/schemas/ErrorNoDefaultKey'
                  - $ref: '#/components/schemas/ErrorNotFound'
                  - $ref: '#/components/schemas/ErrorPermissionDenied'
                  - $ref: '#/components/schemas/ErrorProjectNotFound'
                  - $ref: '#/components/schemas/ErrorQueryFailed'
                  - $ref: '#/components/schemas/ErrorQuotaExceeded'
                  - $ref: '#/components/schemas/ErrorRateLimit'
                  - $ref: '#/components/schemas/ErrorRateLimited'
                  - $ref: '#/components/schemas/ErrorRequestConflict'
                  - $ref: '#/components/schemas/ErrorResourceExhausted'
                  - $ref: '#/components/schemas/ErrorSessionExpired'
                  - $ref: '#/components/schemas/ErrorTimeout'
                  - $ref: '#/components/schemas/ErrorUnauthorized'
                  - $ref: '#/components/schemas/ErrorUnauthorizedUser'
                  - $ref: '#/components/schemas/ErrorUnavailable'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/IndexerGateway/GetChains:
    post:
      operationId: IndexerGateway-GetChains
      summary: List chains
      description: 'Returns the chains the indexer covers, with their ID and name.'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IndexerGateway_GetChains_Request'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IndexerGateway_GetChains_Response'
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
                  - $ref: '#/components/schemas/ErrorAborted'
                  - $ref: '#/components/schemas/ErrorAccessKeyMismatch'
                  - $ref: '#/components/schemas/ErrorAccessKeyNotFound'
                  - $ref: '#/components/schemas/ErrorAtLeastOneKey'
                  - $ref: '#/components/schemas/ErrorGeoblocked'
                  - $ref: '#/components/schemas/ErrorInvalidArgument'
                  - $ref: '#/components/schemas/ErrorInvalidOrigin'
                  - $ref: '#/components/schemas/ErrorInvalidService'
                  - $ref: '#/components/schemas/ErrorMaxAccessKeys'
                  - $ref: '#/components/schemas/ErrorMetadataCallFailed'
                  - $ref: '#/components/schemas/ErrorMethodNotFound'
                  - $ref: '#/components/schemas/ErrorNoDefaultKey'
                  - $ref: '#/components/schemas/ErrorNotFound'
                  - $ref: '#/components/schemas/ErrorPermissionDenied'
                  - $ref: '#/components/schemas/ErrorProjectNotFound'
                  - $ref: '#/components/schemas/ErrorQueryFailed'
                  - $ref: '#/components/schemas/ErrorQuotaExceeded'
                  - $ref: '#/components/schemas/ErrorRateLimit'
                  - $ref: '#/components/schemas/ErrorRateLimited'
                  - $ref: '#/components/schemas/ErrorRequestConflict'
                  - $ref: '#/components/schemas/ErrorResourceExhausted'
                  - $ref: '#/components/schemas/ErrorSessionExpired'
                  - $ref: '#/components/schemas/ErrorTimeout'
                  - $ref: '#/components/schemas/ErrorUnauthorized'
                  - $ref: '#/components/schemas/ErrorUnauthorizedUser'
                  - $ref: '#/components/schemas/ErrorUnavailable'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/IndexerGateway/GetNativeTokenBalance:
    post:
      operationId: IndexerGateway-GetNativeTokenBalance
      summary: Get native token balance
      description: >-
        Returns the latest native token balance of an account on each selected
        chain.
      requestBody:
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/IndexerGateway_GetNativeTokenBalance_Request
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/IndexerGateway_GetNativeTokenBalance_Response
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
                  - $ref: '#/components/schemas/ErrorAborted'
                  - $ref: '#/components/schemas/ErrorAccessKeyMismatch'
                  - $ref: '#/components/schemas/ErrorAccessKeyNotFound'
                  - $ref: '#/components/schemas/ErrorAtLeastOneKey'
                  - $ref: '#/components/schemas/ErrorGeoblocked'
                  - $ref: '#/components/schemas/ErrorInvalidArgument'
                  - $ref: '#/components/schemas/ErrorInvalidOrigin'
                  - $ref: '#/components/schemas/ErrorInvalidService'
                  - $ref: '#/components/schemas/ErrorMaxAccessKeys'
                  - $ref: '#/components/schemas/ErrorMetadataCallFailed'
                  - $ref: '#/components/schemas/ErrorMethodNotFound'
                  - $ref: '#/components/schemas/ErrorNoDefaultKey'
                  - $ref: '#/components/schemas/ErrorNotFound'
                  - $ref: '#/components/schemas/ErrorPermissionDenied'
                  - $ref: '#/components/schemas/ErrorProjectNotFound'
                  - $ref: '#/components/schemas/ErrorQueryFailed'
                  - $ref: '#/components/schemas/ErrorQuotaExceeded'
                  - $ref: '#/components/schemas/ErrorRateLimit'
                  - $ref: '#/components/schemas/ErrorRateLimited'
                  - $ref: '#/components/schemas/ErrorRequestConflict'
                  - $ref: '#/components/schemas/ErrorResourceExhausted'
                  - $ref: '#/components/schemas/ErrorSessionExpired'
                  - $ref: '#/components/schemas/ErrorTimeout'
                  - $ref: '#/components/schemas/ErrorUnauthorized'
                  - $ref: '#/components/schemas/ErrorUnauthorizedUser'
                  - $ref: '#/components/schemas/ErrorUnavailable'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/IndexerGateway/GetTokenBalances:
    post:
      operationId: IndexerGateway-GetTokenBalances
      summary: Get token balances
      description: >-
        Deprecated. Use `GetTokenBalancesSummary` or `GetTokenBalancesDetails`
        instead.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IndexerGateway_GetTokenBalances_Request'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IndexerGateway_GetTokenBalances_Response'
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
                  - $ref: '#/components/schemas/ErrorAborted'
                  - $ref: '#/components/schemas/ErrorAccessKeyMismatch'
                  - $ref: '#/components/schemas/ErrorAccessKeyNotFound'
                  - $ref: '#/components/schemas/ErrorAtLeastOneKey'
                  - $ref: '#/components/schemas/ErrorGeoblocked'
                  - $ref: '#/components/schemas/ErrorInvalidArgument'
                  - $ref: '#/components/schemas/ErrorInvalidOrigin'
                  - $ref: '#/components/schemas/ErrorInvalidService'
                  - $ref: '#/components/schemas/ErrorMaxAccessKeys'
                  - $ref: '#/components/schemas/ErrorMetadataCallFailed'
                  - $ref: '#/components/schemas/ErrorMethodNotFound'
                  - $ref: '#/components/schemas/ErrorNoDefaultKey'
                  - $ref: '#/components/schemas/ErrorNotFound'
                  - $ref: '#/components/schemas/ErrorPermissionDenied'
                  - $ref: '#/components/schemas/ErrorProjectNotFound'
                  - $ref: '#/components/schemas/ErrorQueryFailed'
                  - $ref: '#/components/schemas/ErrorQuotaExceeded'
                  - $ref: '#/components/schemas/ErrorRateLimit'
                  - $ref: '#/components/schemas/ErrorRateLimited'
                  - $ref: '#/components/schemas/ErrorRequestConflict'
                  - $ref: '#/components/schemas/ErrorResourceExhausted'
                  - $ref: '#/components/schemas/ErrorSessionExpired'
                  - $ref: '#/components/schemas/ErrorTimeout'
                  - $ref: '#/components/schemas/ErrorUnauthorized'
                  - $ref: '#/components/schemas/ErrorUnauthorizedUser'
                  - $ref: '#/components/schemas/ErrorUnavailable'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      deprecated: true
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/IndexerGateway/GetTokenBalancesByContract:
    post:
      operationId: IndexerGateway-GetTokenBalancesByContract
      summary: Get token balances by contract
      description: >-
        Returns balances for specific accounts and contracts across all indexed
        chains. ERC-721 and ERC-1155 tokens are returned as individual balances.
      requestBody:
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/IndexerGateway_GetTokenBalancesByContract_Request
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/IndexerGateway_GetTokenBalancesByContract_Response
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
                  - $ref: '#/components/schemas/ErrorAborted'
                  - $ref: '#/components/schemas/ErrorAccessKeyMismatch'
                  - $ref: '#/components/schemas/ErrorAccessKeyNotFound'
                  - $ref: '#/components/schemas/ErrorAtLeastOneKey'
                  - $ref: '#/components/schemas/ErrorGeoblocked'
                  - $ref: '#/components/schemas/ErrorInvalidArgument'
                  - $ref: '#/components/schemas/ErrorInvalidOrigin'
                  - $ref: '#/components/schemas/ErrorInvalidService'
                  - $ref: '#/components/schemas/ErrorMaxAccessKeys'
                  - $ref: '#/components/schemas/ErrorMetadataCallFailed'
                  - $ref: '#/components/schemas/ErrorMethodNotFound'
                  - $ref: '#/components/schemas/ErrorNoDefaultKey'
                  - $ref: '#/components/schemas/ErrorNotFound'
                  - $ref: '#/components/schemas/ErrorPermissionDenied'
                  - $ref: '#/components/schemas/ErrorProjectNotFound'
                  - $ref: '#/components/schemas/ErrorQueryFailed'
                  - $ref: '#/components/schemas/ErrorQuotaExceeded'
                  - $ref: '#/components/schemas/ErrorRateLimit'
                  - $ref: '#/components/schemas/ErrorRateLimited'
                  - $ref: '#/components/schemas/ErrorRequestConflict'
                  - $ref: '#/components/schemas/ErrorResourceExhausted'
                  - $ref: '#/components/schemas/ErrorSessionExpired'
                  - $ref: '#/components/schemas/ErrorTimeout'
                  - $ref: '#/components/schemas/ErrorUnauthorized'
                  - $ref: '#/components/schemas/ErrorUnauthorizedUser'
                  - $ref: '#/components/schemas/ErrorUnavailable'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/IndexerGateway/GetTokenBalancesDetails:
    post:
      operationId: IndexerGateway-GetTokenBalancesDetails
      summary: Get token balance details
      description: >-
        Returns detailed balances for the given accounts across all indexed
        chains. ERC-721 and ERC-1155 tokens are returned as individual balances.
      requestBody:
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/IndexerGateway_GetTokenBalancesDetails_Request
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/IndexerGateway_GetTokenBalancesDetails_Response
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
                  - $ref: '#/components/schemas/ErrorAborted'
                  - $ref: '#/components/schemas/ErrorAccessKeyMismatch'
                  - $ref: '#/components/schemas/ErrorAccessKeyNotFound'
                  - $ref: '#/components/schemas/ErrorAtLeastOneKey'
                  - $ref: '#/components/schemas/ErrorGeoblocked'
                  - $ref: '#/components/schemas/ErrorInvalidArgument'
                  - $ref: '#/components/schemas/ErrorInvalidOrigin'
                  - $ref: '#/components/schemas/ErrorInvalidService'
                  - $ref: '#/components/schemas/ErrorMaxAccessKeys'
                  - $ref: '#/components/schemas/ErrorMetadataCallFailed'
                  - $ref: '#/components/schemas/ErrorMethodNotFound'
                  - $ref: '#/components/schemas/ErrorNoDefaultKey'
                  - $ref: '#/components/schemas/ErrorNotFound'
                  - $ref: '#/components/schemas/ErrorPermissionDenied'
                  - $ref: '#/components/schemas/ErrorProjectNotFound'
                  - $ref: '#/components/schemas/ErrorQueryFailed'
                  - $ref: '#/components/schemas/ErrorQuotaExceeded'
                  - $ref: '#/components/schemas/ErrorRateLimit'
                  - $ref: '#/components/schemas/ErrorRateLimited'
                  - $ref: '#/components/schemas/ErrorRequestConflict'
                  - $ref: '#/components/schemas/ErrorResourceExhausted'
                  - $ref: '#/components/schemas/ErrorSessionExpired'
                  - $ref: '#/components/schemas/ErrorTimeout'
                  - $ref: '#/components/schemas/ErrorUnauthorized'
                  - $ref: '#/components/schemas/ErrorUnauthorizedUser'
                  - $ref: '#/components/schemas/ErrorUnavailable'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/IndexerGateway/GetTokenBalancesSummary:
    post:
      operationId: IndexerGateway-GetTokenBalancesSummary
      summary: Get token balance summary
      description: >-
        Returns a balance summary for the given accounts across all indexed
        chains. Each ERC-721 and ERC-1155 collection is returned as a single
        aggregated balance.
      requestBody:
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/IndexerGateway_GetTokenBalancesSummary_Request
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/IndexerGateway_GetTokenBalancesSummary_Response
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
                  - $ref: '#/components/schemas/ErrorAborted'
                  - $ref: '#/components/schemas/ErrorAccessKeyMismatch'
                  - $ref: '#/components/schemas/ErrorAccessKeyNotFound'
                  - $ref: '#/components/schemas/ErrorAtLeastOneKey'
                  - $ref: '#/components/schemas/ErrorGeoblocked'
                  - $ref: '#/components/schemas/ErrorInvalidArgument'
                  - $ref: '#/components/schemas/ErrorInvalidOrigin'
                  - $ref: '#/components/schemas/ErrorInvalidService'
                  - $ref: '#/components/schemas/ErrorMaxAccessKeys'
                  - $ref: '#/components/schemas/ErrorMetadataCallFailed'
                  - $ref: '#/components/schemas/ErrorMethodNotFound'
                  - $ref: '#/components/schemas/ErrorNoDefaultKey'
                  - $ref: '#/components/schemas/ErrorNotFound'
                  - $ref: '#/components/schemas/ErrorPermissionDenied'
                  - $ref: '#/components/schemas/ErrorProjectNotFound'
                  - $ref: '#/components/schemas/ErrorQueryFailed'
                  - $ref: '#/components/schemas/ErrorQuotaExceeded'
                  - $ref: '#/components/schemas/ErrorRateLimit'
                  - $ref: '#/components/schemas/ErrorRateLimited'
                  - $ref: '#/components/schemas/ErrorRequestConflict'
                  - $ref: '#/components/schemas/ErrorResourceExhausted'
                  - $ref: '#/components/schemas/ErrorSessionExpired'
                  - $ref: '#/components/schemas/ErrorTimeout'
                  - $ref: '#/components/schemas/ErrorUnauthorized'
                  - $ref: '#/components/schemas/ErrorUnauthorizedUser'
                  - $ref: '#/components/schemas/ErrorUnavailable'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/IndexerGateway/GetTokenPrice:
    post:
      operationId: IndexerGateway-GetTokenPrice
      summary: Get token price
      description: Returns the current price of one token.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IndexerGateway_GetTokenPrice_Request'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IndexerGateway_GetTokenPrice_Response'
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
                  - $ref: '#/components/schemas/ErrorAborted'
                  - $ref: '#/components/schemas/ErrorAccessKeyMismatch'
                  - $ref: '#/components/schemas/ErrorAccessKeyNotFound'
                  - $ref: '#/components/schemas/ErrorAtLeastOneKey'
                  - $ref: '#/components/schemas/ErrorGeoblocked'
                  - $ref: '#/components/schemas/ErrorInvalidArgument'
                  - $ref: '#/components/schemas/ErrorInvalidOrigin'
                  - $ref: '#/components/schemas/ErrorInvalidService'
                  - $ref: '#/components/schemas/ErrorMaxAccessKeys'
                  - $ref: '#/components/schemas/ErrorMetadataCallFailed'
                  - $ref: '#/components/schemas/ErrorMethodNotFound'
                  - $ref: '#/components/schemas/ErrorNoDefaultKey'
                  - $ref: '#/components/schemas/ErrorNotFound'
                  - $ref: '#/components/schemas/ErrorPermissionDenied'
                  - $ref: '#/components/schemas/ErrorProjectNotFound'
                  - $ref: '#/components/schemas/ErrorQueryFailed'
                  - $ref: '#/components/schemas/ErrorQuotaExceeded'
                  - $ref: '#/components/schemas/ErrorRateLimit'
                  - $ref: '#/components/schemas/ErrorRateLimited'
                  - $ref: '#/components/schemas/ErrorRequestConflict'
                  - $ref: '#/components/schemas/ErrorResourceExhausted'
                  - $ref: '#/components/schemas/ErrorSessionExpired'
                  - $ref: '#/components/schemas/ErrorTimeout'
                  - $ref: '#/components/schemas/ErrorUnauthorized'
                  - $ref: '#/components/schemas/ErrorUnauthorizedUser'
                  - $ref: '#/components/schemas/ErrorUnavailable'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/IndexerGateway/GetTokenPrices:
    post:
      operationId: IndexerGateway-GetTokenPrices
      summary: Get token prices
      description: Returns current prices for a batch of tokens.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/IndexerGateway_GetTokenPrices_Request'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IndexerGateway_GetTokenPrices_Response'
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
                  - $ref: '#/components/schemas/ErrorAborted'
                  - $ref: '#/components/schemas/ErrorAccessKeyMismatch'
                  - $ref: '#/components/schemas/ErrorAccessKeyNotFound'
                  - $ref: '#/components/schemas/ErrorAtLeastOneKey'
                  - $ref: '#/components/schemas/ErrorGeoblocked'
                  - $ref: '#/components/schemas/ErrorInvalidArgument'
                  - $ref: '#/components/schemas/ErrorInvalidOrigin'
                  - $ref: '#/components/schemas/ErrorInvalidService'
                  - $ref: '#/components/schemas/ErrorMaxAccessKeys'
                  - $ref: '#/components/schemas/ErrorMetadataCallFailed'
                  - $ref: '#/components/schemas/ErrorMethodNotFound'
                  - $ref: '#/components/schemas/ErrorNoDefaultKey'
                  - $ref: '#/components/schemas/ErrorNotFound'
                  - $ref: '#/components/schemas/ErrorPermissionDenied'
                  - $ref: '#/components/schemas/ErrorProjectNotFound'
                  - $ref: '#/components/schemas/ErrorQueryFailed'
                  - $ref: '#/components/schemas/ErrorQuotaExceeded'
                  - $ref: '#/components/schemas/ErrorRateLimit'
                  - $ref: '#/components/schemas/ErrorRateLimited'
                  - $ref: '#/components/schemas/ErrorRequestConflict'
                  - $ref: '#/components/schemas/ErrorResourceExhausted'
                  - $ref: '#/components/schemas/ErrorSessionExpired'
                  - $ref: '#/components/schemas/ErrorTimeout'
                  - $ref: '#/components/schemas/ErrorUnauthorized'
                  - $ref: '#/components/schemas/ErrorUnauthorizedUser'
                  - $ref: '#/components/schemas/ErrorUnavailable'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/IndexerGateway/GetTransactionHistory:
    post:
      operationId: IndexerGateway-GetTransactionHistory
      summary: Get transaction history
      description: >-
        Returns mined transactions for an account across all indexed chains,
        including token transfers sent and received and transactions sent from
        the wallet.
      requestBody:
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/IndexerGateway_GetTransactionHistory_Request
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/IndexerGateway_GetTransactionHistory_Response
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
                  - $ref: '#/components/schemas/ErrorAborted'
                  - $ref: '#/components/schemas/ErrorAccessKeyMismatch'
                  - $ref: '#/components/schemas/ErrorAccessKeyNotFound'
                  - $ref: '#/components/schemas/ErrorAtLeastOneKey'
                  - $ref: '#/components/schemas/ErrorGeoblocked'
                  - $ref: '#/components/schemas/ErrorInvalidArgument'
                  - $ref: '#/components/schemas/ErrorInvalidOrigin'
                  - $ref: '#/components/schemas/ErrorInvalidService'
                  - $ref: '#/components/schemas/ErrorMaxAccessKeys'
                  - $ref: '#/components/schemas/ErrorMetadataCallFailed'
                  - $ref: '#/components/schemas/ErrorMethodNotFound'
                  - $ref: '#/components/schemas/ErrorNoDefaultKey'
                  - $ref: '#/components/schemas/ErrorNotFound'
                  - $ref: '#/components/schemas/ErrorPermissionDenied'
                  - $ref: '#/components/schemas/ErrorProjectNotFound'
                  - $ref: '#/components/schemas/ErrorQueryFailed'
                  - $ref: '#/components/schemas/ErrorQuotaExceeded'
                  - $ref: '#/components/schemas/ErrorRateLimit'
                  - $ref: '#/components/schemas/ErrorRateLimited'
                  - $ref: '#/components/schemas/ErrorRequestConflict'
                  - $ref: '#/components/schemas/ErrorResourceExhausted'
                  - $ref: '#/components/schemas/ErrorSessionExpired'
                  - $ref: '#/components/schemas/ErrorTimeout'
                  - $ref: '#/components/schemas/ErrorUnauthorized'
                  - $ref: '#/components/schemas/ErrorUnauthorizedUser'
                  - $ref: '#/components/schemas/ErrorUnavailable'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/SolanaIndexerGateway/GetTokenBalancesDetails:
    post:
      operationId: SolanaIndexerGateway-GetTokenBalancesDetails
      summary: Get Solana token balances
      description: >-
        Returns native SOL and fungible SPL token balances for the given
        accounts across the selected Solana networks (default: all). Failures
        for a single network or account are reported in `errors`; a 502 is
        returned only when every selected network fails.
      requestBody:
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/SolanaIndexerGateway_GetTokenBalancesDetails_Request
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/SolanaIndexerGateway_GetTokenBalancesDetails_Response
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
  /v1/TronIndexerGateway/GetTokenBalancesDetails:
    post:
      operationId: TronIndexerGateway-GetTokenBalancesDetails
      summary: Get Tron token balances
      description: >-
        Returns native TRX and token balances for the given accounts across the
        selected Tron networks. Failures for a single network or account are
        reported in `errors`.
      requestBody:
        content:
          application/json:
            schema:
              $ref: >-
                #/components/schemas/TronIndexerGateway_GetTokenBalancesDetails_Request
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: >-
                  #/components/schemas/TronIndexerGateway_GetTokenBalancesDetails_Response
        4XX:
          description: Client error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcEndpoint'
                  - $ref: '#/components/schemas/ErrorWebrpcRequestFailed'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRoute'
                  - $ref: '#/components/schemas/ErrorWebrpcBadMethod'
                  - $ref: '#/components/schemas/ErrorWebrpcBadRequest'
                  - $ref: '#/components/schemas/ErrorWebrpcClientAborted'
                  - $ref: '#/components/schemas/ErrorWebrpcStreamLost'
        5XX:
          description: Server error
          content:
            application/json:
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorWebrpcBadResponse'
                  - $ref: '#/components/schemas/ErrorWebrpcServerPanic'
                  - $ref: '#/components/schemas/ErrorWebrpcInternalError'
      security:
        - PublishableKey: []
        - BearerAuth: []
      tags:
        - Indexer
    servers:
      - url: 'https://sandbox-api.polygon.technology'
        description: Sandbox
      - url: 'https://api.polygon.technology'
        description: Production
components:
  schemas:
    AuthorizeRequest:
      type: object
      required:
        - apiKey
        - apiSecret
      properties:
        apiKey:
          type: string
          description: |
            Secret API key identifier. Prefix encodes (mode, env): `sk_live_…` /
            `sk_sdbx_…` on prod; non-prod envs add an env infix
            (`sk_dev_sdbx_…`, `sk_stg_live_…`, …). The matching apiSecret is
            shown once at key creation and stored only as an HMAC hash.
          example: sk_live_abc123...
        apiSecret:
          type: string
          description: Opaque secret revealed once at key creation; not a typeid.
          example: opaque-bearer-secret...
    AuthorizeResponse:
      type: object
      required:
        - accessToken
        - tokenType
        - expiresIn
        - expiresAt
        - projectId
        - projectMode
      properties:
        accessToken:
          type: string
          example: eyJhbGciOiJSUzI1NiIs...
        tokenType:
          type: string
          enum:
            - bearer
        expiresIn:
          type: integer
          example: 3600
        expiresAt:
          type: string
          format: date-time
        projectId:
          type: string
          description: Project authenticated by the secret credentials.
        projectMode:
          type: string
          enum:
            - sandbox
            - live
          x-enum-varnames:
            - ProjectModeSandbox
            - ProjectModeLive
    CreateCustomerRiskSessionRequest:
      type: object
      additionalProperties: false
      required:
        - deviceFingerprint
      properties:
        deviceFingerprint:
          type: string
          minLength: 1
          maxLength: 1024
          pattern: '^[!-~]+$'
    CustomerRiskSession:
      type: object
      required:
        - webSessionId
        - riskId
      properties:
        webSessionId:
          type: string
        riskId:
          type: string
    CustomerToken:
      type: object
      required:
        - token
        - expiresAt
      properties:
        token:
          type: string
          description: >-
            Customer-bound browser token with the `omsx-customer-token`
            audience.
          example: eyJhbGciOiJFZERTQSIs...
        expiresAt:
          type: string
          format: date-time
    AssociateWalletRequest:
      type: object
      required:
        - idToken
      properties:
        idToken:
          type: string
          description: >-
            WaaS-issued idToken (ES256 JWT). Its subject is the wallet id and
            its audience must be the authenticated project.
          example: eyJhbGciOiJFUzI1NiIs...
    Wallet:
      type: object
      description: Embedded wallet linked to a customer.
      properties:
        id:
          type: string
          x-go-type-skip-optional-pointer: true
          example: wlt_01H9Xa8F5dN6mP3q
        object:
          type: string
          x-go-type-skip-optional-pointer: true
          example: wallet
        customer:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          example: cst_01H9Xa8F5dN6mP3q
        custodyType:
          type: string
          x-go-type-skip-optional-pointer: true
          enum:
            - custodial
            - embedded
          example: embedded
        blockchainAddress:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          example: '0x1234567890abcdef1234567890abcdef12345678'
        networkFamily:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          example: evm
        status:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          enum:
            - preallocated
            - active
            - suspended
          example: active
        createdAt:
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
          nullable: true
        updatedAt:
          type: string
          format: date-time
          x-go-type-skip-optional-pointer: true
          nullable: true
    CustomerTotalBalance:
      type: object
      description: >-
        USD rollup of a customer's balances. Returned on GET /customers/{id}
        only — never on list, create, or update. Covers fiat wallets and
        custodial crypto wallets; `noncustodial` wallets are not yet valued, so
        a customer holding one reads an undercount here. Omitted entirely when
        the rollup cannot be read; a partial total is never returned, so treat
        an absent field as "unknown", not as zero.
      properties:
        totalUsd:
          type: string
          description: '`fiatUsd + cryptoUsd`, 2 decimal places, sign preserved.'
          example: '1250.00'
        fiatUsd:
          type: string
          description: >-
            Sum of the customer's USD fiat wallet balances as last reported by
            the holding bank. Can be negative — an ACH clawback can overdraw a
            deposit account — so render the sign verbatim and never clamp.
          example: '1000.00'
        cryptoUsd:
          type: string
          description: >-
            Sum of the customer's custodial crypto wallet balances at the
            custodian's own per-asset USD estimate. `"0.00"` for a customer with
            no custodial crypto account.
          example: '250.00'
        updatedAt:
          type: string
          format: date-time
          description: >-
            When the custodial wallet provider last updated the crypto balances
            in `cryptoUsd`: the newest per-asset timestamp the provider reports
            across those balances, read live with this request. Fiat balances do
            not affect it. Omitted when the provider reports no timestamp, for
            example when the customer holds no custodial crypto wallet.
          example: '2026-03-20T14:15:22Z'
    Customer:
      type: object
      description: >-
        Customer response object. PII fields (birthDate, residentialAddress,
        ipAddress, identifyingInformation) are write-only — accepted in
        POST/PATCH but never returned in responses.
      properties:
        id:
          type: string
          x-go-type-skip-optional-pointer: true
          example: cst_01H9Xa8F5dN6mP3q
        type:
          type: string
          x-go-type-skip-optional-pointer: true
          enum:
            - individual
            - business
          description: >-
            Customer type. Individuals are subject to the project's KYC policy,
            businesses to its KYB policy.
          example: individual
        name:
          type: string
          description: >-
            An individual's first, middle and last names joined by spaces, or a
            business's legal name. Left out when the customer has no name.
          example: Jane Smith
        firstName:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          example: Jane
        middleName:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          example: null
        lastName:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          example: Smith
        email:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          example: jane@example.com
        phone:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          description: Primary phone in E.164 format.
          example: '+12125551234'
        nationality:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          description: ISO 3166-1 alpha-2 country code.
          example: US
        externalId:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          description: Developer's own customer ID for cross-referencing.
          example: crm-12345
        status:
          type: string
          x-go-type-skip-optional-pointer: true
          enum:
            - pending
            - actionRequired
            - active
            - rejected
            - offboarded
          description: >-
            Where the customer is in onboarding. `actionRequired` carries a
            `hold` saying what to do, and `rejected` carries a `failure`.
            `offboarded` is a deleted or deactivated customer.
          example: active
        hold:
          $ref: '#/components/schemas/CustomerHold'
        failure:
          $ref: '#/components/schemas/CustomerFailure'
        signedAgreement:
          type: boolean
          x-go-type-skip-optional-pointer: true
          description: Whether the customer has accepted OMS terms of service.
          example: true
        signedAgreementAt:
          type: string
          format: date-time
          nullable: true
          description: >-
            Timestamp when signedAgreement was set to true. Null if not yet
            signed.
          example: '2026-03-20T14:15:22Z'
        totalBalance:
          $ref: '#/components/schemas/CustomerTotalBalance'
        endorsements:
          type: array
          description: >-
            What the customer is endorsed for. An endorsement never reads
            further along than its customer, and one that was not requested is
            left out.
          items:
            $ref: '#/components/schemas/CustomerEndorsement'
        metadata:
          type: object
          nullable: true
          additionalProperties:
            type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        companyLegalName:
          type: string
          maxLength: 255
        dbaName:
          type: string
        formationDate:
          type: string
        registrationCountry:
          type: string
        registrationNumber:
          type: string
        legalEntityType:
          type: string
          enum:
            - corporation
            - llc
            - nonProfit
            - partnership
            - soleProprietorship
            - trust
        ownershipType:
          type: string
          enum:
            - exempt
            - excluded
            - nonProfit
            - legalEntity
        taxIdType:
          $ref: '#/components/schemas/BusinessTaxIDType'
        incorporationAddress:
          $ref: '#/components/schemas/BusinessAddress'
        physicalAddress:
          $ref: '#/components/schemas/BusinessAddress'
        websiteUrl:
          type: string
        businessDescription:
          type: string
        industry:
          type: string
        industryFinancialServicesSubtype:
          type: string
        industryCryptoSubtype:
          type: string
        industryOtherDescription:
          type: string
        sourceOfFundsOtherDescription:
          type: string
        accountPurposesOtherDescription:
          type: string
        primaryTargetMarketOtherDescription:
          type: string
        sourceOfFunds:
          type: array
          items:
            type: string
        accountPurposes:
          type: array
          items:
            type: string
        primaryTargetMarket:
          type: string
        expectedFiatMonthlyVolume:
          type: string
        expectedCryptoMonthlyVolume:
          type: string
        isMsb:
          type: boolean
        disclosureAccepted:
          type: boolean
        disclosureAcceptedAt:
          type: string
          format: date-time
        disclosureVersion:
          type: string
        disclosureIpAddress:
          type: string
        hasBusinessTaxId:
          type: boolean
    CustomerEndorsement:
      type: object
      required:
        - type
        - status
      properties:
        type:
          type: string
          enum:
            - basic
            - cryptoCustody
            - usd
        status:
          type: string
          enum:
            - pending
            - actionRequired
            - active
            - rejected
            - offboarded
        requirements:
          $ref: '#/components/schemas/CustomerEndorsementRequirements'
        failure:
          $ref: '#/components/schemas/CustomerFailure'
    CustomerEndorsementRequirements:
      type: object
      description: >-
        Tracks what is complete, pending, missing, or has issues for this
        endorsement.
      properties:
        complete:
          type: array
          items:
            type: string
        pending:
          type: array
          items:
            type: string
        missing:
          type: array
          nullable: true
          items:
            type: string
        issues:
          type: array
          items:
            type: string
    CustomerHold:
      type: object
      description: What you must do for a customer in `actionRequired`.
      required:
        - code
        - message
      properties:
        code:
          type: string
          example: verificationRequired
        message:
          type: string
    CustomerFailure:
      type: object
      description: Why a customer or an endorsement was rejected.
      required:
        - code
        - message
        - retryable
      properties:
        code:
          type: string
          example: onboardingRejected
        message:
          type: string
        retryable:
          type: boolean
    CustomerCreateAccepted:
      type: object
      description: >-
        A customer creation that is still running. The customer reads as 404
        until it finishes.
      required:
        - id
        - object
        - status
      properties:
        id:
          type: string
          description: The id the customer will have once created.
          example: cst_01H9Xa8F5dN6mP3q
        object:
          type: string
          enum:
            - customer
        status:
          type: string
          enum:
            - processing
    BusinessTaxIDType:
      type: string
      enum:
        - ein
        - vat
        - foreign
        - ssn
        - itin
        - foreignTin
    BusinessAddress:
      type: object
      properties:
        line1:
          type: string
        line2:
          type: string
        city:
          type: string
        state:
          type: string
        postalCode:
          type: string
        country:
          type: string
    BusinessBeneficiaryInput:
      type: object
      description: >-
        Full replacement of non-sensitive beneficiary facts. Omitted
        non-sensitive values are cleared. Sensitive identifiers are write-only;
        omission preserves their values and an empty string clears them. Enum
        values use camelCase.
      required:
        - roles
      properties:
        firstName:
          type: string
        middleName:
          type: string
        lastName:
          type: string
        fullNameAsOnDocument:
          type: string
        nationality:
          type: string
        address:
          $ref: '#/components/schemas/BusinessAddress'
        email:
          type: string
        phone:
          type: string
        title:
          type: string
        roles:
          type: array
          items:
            type: string
            enum:
              - beneficialOwner
              - controller
              - director
              - signatory
              - representative
        ownershipPercentage:
          type: string
        hasControl:
          type: boolean
        politicallyExposedPerson:
          type: boolean
        taxIdType:
          $ref: '#/components/schemas/BusinessTaxIDType'
        identificationType:
          type: string
          enum:
            - driversLicense
            - passport
            - idCard
            - socialSecurityCard
            - other
        issuingAuthority:
          type: string
        issuingCountry:
          type: string
        issuingState:
          type: string
        issuedDate:
          type: string
        expirationDate:
          type: string
        verifiedDate:
          type: string
        birthDate:
          type: string
          writeOnly: true
        taxId:
          type: string
          writeOnly: true
        identificationNumber:
          type: string
          writeOnly: true
    BusinessBeneficiaryUpdate:
      type: object
      required:
        - version
        - input
      properties:
        version:
          type: integer
          minimum: 1
        input:
          $ref: '#/components/schemas/BusinessBeneficiaryInput'
    BusinessBeneficiary:
      type: object
      required:
        - id
        - object
        - customerId
        - roles
        - version
      properties:
        id:
          type: string
        object:
          type: string
          enum:
            - businessBeneficiary
        customerId:
          type: string
        firstName:
          type: string
        middleName:
          type: string
        lastName:
          type: string
        fullNameAsOnDocument:
          type: string
        nationality:
          type: string
        address:
          $ref: '#/components/schemas/BusinessAddress'
        email:
          type: string
        phone:
          type: string
        title:
          type: string
        roles:
          type: array
          items:
            type: string
            enum:
              - beneficialOwner
              - controller
              - director
              - signatory
              - representative
        ownershipPercentage:
          type: string
        hasControl:
          type: boolean
        politicallyExposedPerson:
          type: boolean
        taxIdType:
          $ref: '#/components/schemas/BusinessTaxIDType'
        identificationType:
          type: string
          enum:
            - driversLicense
            - passport
            - idCard
            - socialSecurityCard
            - other
        issuingAuthority:
          type: string
        issuingCountry:
          type: string
        issuingState:
          type: string
        issuedDate:
          type: string
        expirationDate:
          type: string
        verifiedDate:
          type: string
        hasBirthDate:
          type: boolean
        hasTaxId:
          type: boolean
        hasIdentificationNumber:
          type: boolean
        version:
          type: integer
          minimum: 1
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    BusinessBeneficiariesList:
      type: object
      required:
        - data
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/BusinessBeneficiary'
    CustomerOnboardingRequest:
      type: object
      required:
        - beneficiaryIds
        - partnerAttestation
      properties:
        beneficiaryIds:
          type: array
          minItems: 1
          maxItems: 5
          items:
            type: string
        partnerAttestation:
          type: object
          required:
            - id
            - provider
            - attestedAt
          properties:
            id:
              type: string
              minLength: 1
              maxLength: 256
            provider:
              type: string
              minLength: 1
              maxLength: 256
            attestedAt:
              type: string
              format: date-time
    CustomerOnboarding:
      type: object
      required:
        - id
        - object
        - customerId
        - provider
        - status
      properties:
        id:
          type: string
        object:
          type: string
          enum:
            - customerOnboarding
        customerId:
          type: string
        provider:
          type: string
          enum:
            - coinme
        status:
          type: string
          enum:
            - pending
            - active
            - rejected
        failureCode:
          type: string
          enum:
            - rejected
            - processingFailed
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    CustomerOnboardingsList:
      type: object
      required:
        - data
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/CustomerOnboarding'
    CustomerRequest:
      type: object
      required:
        - type
      description: >-
        Create a new customer. Individuals require firstName and lastName.
        Businesses require companyLegalName and email, and do not accept
        person-name fields. PII fields (birthDate, residentialAddress,
        ipAddress, identifyingInformation) are write-only and never returned in
        responses. Whether identity verification is required, and whether OMS
        relies on your attestation or a vendor verifies, is configured per
        project, not per request.
      properties:
        type:
          type: string
          enum:
            - individual
            - business
          description: >-
            Customer type. Individuals follow the project's KYC policy,
            businesses its KYB policy.
          example: individual
        companyLegalName:
          type: string
          maxLength: 255
          description: >-
            Legal business name. Required for business creation; supports
            Unicode and punctuation. Only valid for business customers.
        firstName:
          type: string
          description: >-
            Individual customer's legal first name. Not accepted for business
            customers.
          example: Jane
        middleName:
          type: string
          description: >-
            Individual customer's middle name. Not accepted for business
            customers.
        lastName:
          type: string
          description: >-
            Individual customer's legal last name. Not accepted for business
            customers.
          example: Smith
        email:
          type: string
          format: email
          example: jane@example.com
        phone:
          type: string
          description: Primary phone in E.164 format.
          example: '+12125551234'
        birthDate:
          type: string
          description: Date of birth in YYYY-MM-DD format. Write-only.
          example: '1990-05-15'
          writeOnly: true
        nationality:
          type: string
          description: ISO 3166-1 alpha-2 country code.
          example: US
        ipAddress:
          type: string
          description: >-
            Customer's IP address. Used for geo-based compliance checks on the
            basic endorsement. Write-only.
          writeOnly: true
        externalId:
          type: string
          description: Developer's own customer ID for cross-referencing.
          example: crm-12345
        signedAgreement:
          type: boolean
          description: >-
            Whether the customer has accepted OMS terms of service. Default
            false.
          default: false
        residentialAddress:
          description: Customer's residential address. Write-only.
          writeOnly: true
          allOf:
            - $ref: '#/components/schemas/ResidentialAddress'
        identifyingInformation:
          type: array
          description: >-
            Array of ID documents. Write-only. Supported types: ssn, itin,
            driversLicense, passport.
          writeOnly: true
          items:
            $ref: '#/components/schemas/IdentificationDocument'
        endorsements:
          type: array
          description: >-
            Endorsements to request: basic, cryptoCustody, usd. If omitted, OMS
            defaults to cryptoCustody and usd (which auto-includes basic).
          items:
            type: string
            enum:
              - basic
              - cryptoCustody
              - usd
        metadata:
          type: object
          nullable: true
          additionalProperties:
            type: string
          maxProperties: 20
        dbaName:
          type: string
        formationDate:
          type: string
        registrationCountry:
          type: string
        registrationNumber:
          type: string
        legalEntityType:
          type: string
          enum:
            - corporation
            - llc
            - nonProfit
            - partnership
            - soleProprietorship
            - trust
        ownershipType:
          type: string
          enum:
            - exempt
            - excluded
            - nonProfit
            - legalEntity
        taxIdType:
          $ref: '#/components/schemas/BusinessTaxIDType'
        incorporationAddress:
          $ref: '#/components/schemas/BusinessAddress'
        physicalAddress:
          $ref: '#/components/schemas/BusinessAddress'
        websiteUrl:
          type: string
        businessDescription:
          type: string
        industry:
          type: string
        industryFinancialServicesSubtype:
          type: string
        industryCryptoSubtype:
          type: string
        industryOtherDescription:
          type: string
        sourceOfFundsOtherDescription:
          type: string
        accountPurposesOtherDescription:
          type: string
        primaryTargetMarketOtherDescription:
          type: string
        sourceOfFunds:
          type: array
          items:
            type: string
        accountPurposes:
          type: array
          items:
            type: string
        primaryTargetMarket:
          type: string
        expectedFiatMonthlyVolume:
          type: string
        expectedCryptoMonthlyVolume:
          type: string
        isMsb:
          type: boolean
        disclosureAccepted:
          type: boolean
        disclosureAcceptedAt:
          type: string
          format: date-time
        disclosureVersion:
          type: string
        disclosureIpAddress:
          type: string
        businessTaxId:
          type: string
          writeOnly: true
    CustomerUpdate:
      type: object
      description: >-
        Partial update — only send the fields you want to change. All optional
        fields from CustomerRequest can be updated (including ipAddress). PII
        fields are write-only.
      properties:
        companyLegalName:
          type: string
          maxLength: 255
          description: >-
            Legal business name. Required for business creation; supports
            Unicode and punctuation. Only valid for business customers.
        firstName:
          type: string
        middleName:
          type: string
        lastName:
          type: string
        email:
          type: string
        phone:
          type: string
        birthDate:
          type: string
          writeOnly: true
        nationality:
          type: string
        ipAddress:
          type: string
          writeOnly: true
        externalId:
          type: string
        signedAgreement:
          type: boolean
          description: One-way operation — cannot be set back to false.
        residentialAddress:
          writeOnly: true
          allOf:
            - $ref: '#/components/schemas/ResidentialAddress'
        identifyingInformation:
          type: array
          writeOnly: true
          description: >-
            Appends to existing array. To replace an entry, submit the same type
            with updated fields.
          items:
            $ref: '#/components/schemas/IdentificationDocument'
        endorsements:
          type: array
          description: >-
            Request additional endorsements. New endorsements are added;
            existing ones are not removed. Including endorsement names triggers
            re-evaluation.
          items:
            type: string
            enum:
              - basic
              - cryptoCustody
              - usd
        metadata:
          type: object
          additionalProperties:
            type: string
        dbaName:
          type: string
        formationDate:
          type: string
        registrationCountry:
          type: string
        registrationNumber:
          type: string
        legalEntityType:
          type: string
          enum:
            - corporation
            - llc
            - nonProfit
            - partnership
            - soleProprietorship
            - trust
        ownershipType:
          type: string
          enum:
            - exempt
            - excluded
            - nonProfit
            - legalEntity
        taxIdType:
          $ref: '#/components/schemas/BusinessTaxIDType'
        incorporationAddress:
          $ref: '#/components/schemas/BusinessAddress'
        physicalAddress:
          $ref: '#/components/schemas/BusinessAddress'
        websiteUrl:
          type: string
        businessDescription:
          type: string
        industry:
          type: string
        industryFinancialServicesSubtype:
          type: string
        industryCryptoSubtype:
          type: string
        industryOtherDescription:
          type: string
        sourceOfFundsOtherDescription:
          type: string
        accountPurposesOtherDescription:
          type: string
        primaryTargetMarketOtherDescription:
          type: string
        sourceOfFunds:
          type: array
          items:
            type: string
        accountPurposes:
          type: array
          items:
            type: string
        primaryTargetMarket:
          type: string
        expectedFiatMonthlyVolume:
          type: string
        expectedCryptoMonthlyVolume:
          type: string
        isMsb:
          type: boolean
        disclosureAccepted:
          type: boolean
        disclosureAcceptedAt:
          type: string
          format: date-time
        disclosureVersion:
          type: string
        disclosureIpAddress:
          type: string
        businessTaxId:
          type: string
          writeOnly: true
    ResidentialAddress:
      type: object
      description: Customer's residential address.
      properties:
        line1:
          type: string
          example: 123 Main St
        line2:
          type: string
        city:
          type: string
          example: Seattle
        state:
          type: string
          example: WA
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code.
          example: US
        zipCode:
          type: string
          example: '98101'
    IdentificationDocument:
      type: object
      required:
        - type
        - issuingCountry
        - number
      properties:
        type:
          type: string
          enum:
            - ssn
            - itin
            - driversLicense
            - passport
          example: ssn
        issuingCountry:
          type: string
          description: ISO 3166-1 alpha-2 country code.
          example: US
        number:
          type: string
          description: The identification number.
          example: '123456789'
    CustomersList:
      type: object
      required:
        - data
        - hasMore
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Customer'
        hasMore:
          type: boolean
        cursor:
          type: string
          x-go-type-skip-optional-pointer: true
          description: >-
            Opaque pagination cursor — pass back as the `cursor` query param to
            fetch the next page. Absent on the last page.
    WebhookStatus:
      type: string
      enum:
        - enabled
        - disabled
        - suspended
      description: >-
        Webhook lifecycle state. `suspended` is set only by the service when the
        endpoint is unhealthy.
    DeliveryStatus:
      type: string
      enum:
        - queued
        - inProgress
        - delivered
        - failed
        - skipped
      description: >-
        Delivery lifecycle state. `skipped` is recorded but not dispatched
        (suspended/disabled webhook).
    WebhookMode:
      type: string
      enum:
        - live
        - sandbox
    Webhook:
      type: object
      description: >-
        A partner-configured webhook endpoint. The signing key is never
        serialized back; it is returned in cleartext only from
        create/rotate-key.
      properties:
        id:
          type: string
          x-go-type-skip-optional-pointer: true
          example: whk_01H9Xa8F5dN6mP3q
        object:
          type: string
          x-go-type-skip-optional-pointer: true
          example: webhook
        url:
          type: string
          x-go-type-skip-optional-pointer: true
          example: 'https://partner.example/webhooks'
        status:
          $ref: '#/components/schemas/WebhookStatus'
        statusReason:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          description: Set on transition to suspended; describes the down/suspend cause.
        subscriptions:
          type: array
          x-go-type-skip-optional-pointer: true
          x-omitempty: false
          x-omitzero: true
          items:
            type: string
          example:
            - transaction.settled
            - '*'
        timeoutMs:
          type: integer
          x-go-type-skip-optional-pointer: true
          description: 'Per-webhook HTTP timeout. Default 5000, hard cap 10000.'
          example: 5000
        notifyThresholdSecs:
          type: integer
          x-go-type-skip-optional-pointer: true
          nullable: true
          description: Down-notification threshold (10 min – 1 day; default 1 h).
        successCount:
          type: integer
          x-go-type-skip-optional-pointer: true
          format: int64
        failureCount:
          type: integer
          x-go-type-skip-optional-pointer: true
          format: int64
        mode:
          $ref: '#/components/schemas/WebhookMode'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    WebhookRequest:
      type: object
      required:
        - url
        - subscriptions
      properties:
        url:
          type: string
          example: 'https://partner.example/webhooks'
        subscriptions:
          type: array
          items:
            type: string
          example:
            - transaction.settled
            - '*'
        timeoutMs:
          type: integer
          description: >-
            Per-webhook HTTP timeout in milliseconds. Default 5000, hard cap
            10000.
        notifyThresholdSecs:
          type: integer
          description: Down-notification threshold in seconds (600 – 86400; default 3600).
    WebhookUpdate:
      type: object
      description: Partial update. Only include fields you want to change.
      properties:
        url:
          type: string
        subscriptions:
          type: array
          items:
            type: string
        timeoutMs:
          type: integer
        notifyThresholdSecs:
          type: integer
    CreateWebhookResponse:
      type: object
      required:
        - webhook
        - signingKey
      properties:
        webhook:
          $ref: '#/components/schemas/Webhook'
        signingKey:
          type: string
          description: >-
            Cleartext HMAC signing key. Shown once — store it immediately; it is
            never returned again.
    RotateWebhookKeyResponse:
      type: object
      required:
        - signingKey
      properties:
        signingKey:
          type: string
          description: New cleartext HMAC signing key. Shown once.
    DeliverySummary:
      type: object
      properties:
        eventType:
          type: string
        status:
          $ref: '#/components/schemas/DeliveryStatus'
        createdAt:
          type: string
          format: date-time
    WebhookListItem:
      type: object
      properties:
        webhook:
          $ref: '#/components/schemas/Webhook'
        deliveryCount:
          type: integer
          format: int64
        successCount:
          type: integer
          format: int64
        failureCount:
          type: integer
          format: int64
        failureRate:
          type: integer
          description: >-
            Failure rate in basis points (0..10000); 250 = 2.50%. 0 when
            deliveryCount is 0.
        lastDelivery:
          $ref: '#/components/schemas/DeliverySummary'
    WebhooksList:
      type: object
      required:
        - data
        - hasMore
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/WebhookListItem'
        hasMore:
          type: boolean
        cursor:
          type: string
          x-go-type-skip-optional-pointer: true
          description: >-
            Opaque pagination cursor — pass back as the `cursor` query param to
            fetch the next page. Absent on the last page.
    WebhookEvent:
      type: object
      x-go-type: json.RawMessage
      description: >-
        The webhook body for this delivery, rendered as the current webhook
        format. `attempts[].requestBody` holds the body each attempt sent, cut
        off at 64 KiB when `requestBodyTruncated` is set.
      required:
        - id
        - type
        - createdAt
        - schema
        - data
      properties:
        id:
          type: string
          description: 'The event''s dedup key, stable across retries.'
          example: evt_01m4wp8xtpfm9tp57mh59nbgrq
        idempotencyKey:
          type: string
          description: >-
            The same on every emission of one logical change, so a repeat that
            carries a new id can be skipped. Absent when the producer set none.
          example: 6f1c2d3e-0a4b-5c7d-8e9f-1a2b3c4d5e6f
        type:
          type: string
          example: transfer.statusChanged
        createdAt:
          type: string
          format: date-time
          description: >-
            When the producer created the event, falling back to when it
            happened, in UTC with three decimals.
          example: '2026-10-14T09:30:00.100Z'
        schema:
          type: string
          description: >-
            `v1` for events in the V1 catalog, or an empty string for events
            published before it.
          example: v1
        data:
          type: object
          description: >-
            The event's data. An empty object when the delivery's payload could
            not be converted.
    WebhookDelivery:
      type: object
      description: >-
        One delivery of one event to one webhook. The `whd_` id identifies the
        delivery. `event.id` is the envelope id and dedup key, stable across
        retries.
      required:
        - event
      properties:
        id:
          type: string
          x-go-type-skip-optional-pointer: true
          example: whd_01H9Xa8F5dN6mP3q
        object:
          type: string
          x-go-type-skip-optional-pointer: true
          example: webhookDelivery
        webhookId:
          type: string
          x-go-type-skip-optional-pointer: true
          example: whk_01H9Xa8F5dN6mP3q
        resourceType:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
        resourceId:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
        status:
          $ref: '#/components/schemas/DeliveryStatus'
        statusReason:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
        sendAt:
          type: string
          format: date-time
          x-go-type: string
          x-go-type-skip-optional-pointer: true
        deliveredAt:
          type: string
          format: date-time
          x-go-type: string
          x-go-type-skip-optional-pointer: true
        failedAttempts:
          type: integer
          x-go-type-skip-optional-pointer: true
        test:
          type: boolean
          x-go-type-skip-optional-pointer: true
          description: True for a synthesized test delivery.
        event:
          $ref: '#/components/schemas/WebhookEvent'
        createdAt:
          type: string
          format: date-time
          x-go-type: string
          x-go-type-skip-optional-pointer: true
          description: When OMS stored the delivery.
    DeliveryAttempt:
      type: object
      description: >-
        One HTTP attempt within a delivery. Sensitive header/body fields are
        redacted before storage.
      properties:
        attemptNumber:
          type: integer
          x-go-type-skip-optional-pointer: true
        statusCode:
          type: integer
          x-go-type-skip-optional-pointer: true
          nullable: true
        error:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
        durationMs:
          type: integer
          x-go-type-skip-optional-pointer: true
          nullable: true
        createdAt:
          type: string
          format: date-time
          x-go-type: string
          x-go-type-skip-optional-pointer: true
        targetUrl:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          description: >-
            Target URL with userinfo stripped and credential-bearing query
            params redacted.
        requestMethod:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
        requestHeaders:
          type: object
          x-go-type-skip-optional-pointer: true
          nullable: true
          additionalProperties:
            type: string
          description: Stored as a JSON map; sensitive header names redacted.
        requestBody:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          description: >-
            Snapshot of the body this attempt POSTed, cut off at 64 KiB;
            `requestBodyTruncated` is set when it is.
        requestBodyTruncated:
          type: boolean
          x-go-type-skip-optional-pointer: true
          nullable: true
        responseHeaders:
          type: object
          x-go-type-skip-optional-pointer: true
          nullable: true
          additionalProperties:
            type: string
        responseBody:
          type: string
          x-go-type-skip-optional-pointer: true
          nullable: true
          description: Up to 64 KiB stored; sensitive JSON field names redacted.
        responseBodyTruncated:
          type: boolean
          x-go-type-skip-optional-pointer: true
          nullable: true
    DeliveriesList:
      type: object
      required:
        - data
        - hasMore
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/WebhookDelivery'
        hasMore:
          type: boolean
        cursor:
          type: string
          x-go-type-skip-optional-pointer: true
          description: Opaque pagination cursor. Absent on the last page.
    GetDeliveryResponse:
      type: object
      required:
        - delivery
        - attempts
      properties:
        delivery:
          $ref: '#/components/schemas/WebhookDelivery'
        attempts:
          type: array
          items:
            $ref: '#/components/schemas/DeliveryAttempt'
    RetryDeliveriesRequest:
      type: object
      description: >-
        Provide explicit deliveryIds, or a status plus a createdAt range to
        retry all matching deliveries. At least one anchor is required.
      properties:
        deliveryIds:
          type: array
          items:
            type: string
        status:
          $ref: '#/components/schemas/DeliveryStatus'
        createdAfter:
          type: string
          format: date-time
        createdBefore:
          type: string
          format: date-time
    RetryDeliveriesResponse:
      type: object
      required:
        - retried
      properties:
        retried:
          type: integer
          description: Number of deliveries re-queued.
    ErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
        - status
      description: >-
        Standard OMS error response. Error names and numeric codes are stable
        identifiers.
      properties:
        error:
          type: string
          description: Stable OMS error name.
          example: Unauthorized
        code:
          type: integer
          description: Stable OMS error code.
          example: 1000
        msg:
          type: string
          description: Human-readable message (kept stable across releases)
          example: unauthorized access
        cause:
          type: string
          description: >-
            Optional internal cause for operator triage; filtered before
            reaching end customers
          example: signature
        status:
          type: integer
          description: HTTP status mirrored in the body for client convenience
          example: 401
    AboveMaximumAmountErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AboveMaximumAmount
        code:
          type: number
          enum:
            - 10110
        msg:
          type: string
          enum:
            - amount exceeds the maximum (cash_onramp legacy)
        cause:
          type: string
    AccountHolderUnsupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AccountHolderUnsupported
        code:
          type: number
          enum:
            - 10022
        msg:
          type: string
          enum:
            - destination.details.accountHolder must be customer
        cause:
          type: string
    AccountNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AccountNotFound
        code:
          type: number
          enum:
            - 10081
        msg:
          type: string
          enum:
            - account not found
        cause:
          type: string
    AccountNumberInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AccountNumberInvalid
        code:
          type: number
          enum:
            - 10040
        msg:
          type: string
          enum:
            - accountNumber is required
        cause:
          type: string
    AccountTransaction:
      type: object
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Unique identifier.
        object:
          type: string
          enum:
            - accountTransaction
          description: Resource type discriminator. Always "accountTransaction".
        accountId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Wallet/account ID.
        type:
          $ref: '#/components/schemas/TransactionType'
        status:
          type: string
          description: Current lifecycle status.
        amount:
          allOf:
            - $ref: '#/components/schemas/signedFixedDecimalString'
          description: >-
            Amount of this entry, as a fixed-point decimal string at the wallet
            asset's own scale — `"5.00"` for $5.00 of fiat (2dp), `"5.000000"`
            for 5 USDC (6dp). Signed: render the sign as returned rather than
            taking the absolute value.
        currency:
          type: string
          description: ISO 4217 currency code.
        creditCurrencyAmount:
          type: string
          description: 'Amount credited, in `creditCurrencyCode`.'
        creditCurrencyCode:
          type: string
          description: Currency credited.
        debitCurrencyAmount:
          type: string
          description: 'Amount debited, in `debitCurrencyCode`.'
        debitCurrencyCode:
          type: string
          description: Currency debited.
        exchangeRate:
          type: string
          description: Units of destination asset per 1 unit of source asset.
        totalFees:
          type: string
          description: Total fees for this entry.
        feeCurrencyCode:
          type: string
          description: Currency the fees are denominated in.
        orderType:
          type: string
          description: Order type of the underlying trade.
        providerTransactionRef:
          type: string
          description: Upstream provider's transaction reference.
        blockchainTransactionId:
          type: string
          description: On-chain transaction identifier.
        fromWalletAddress:
          type: string
          description: Sending wallet address.
        toWalletAddress:
          type: string
          description: Receiving wallet address.
        balanceAfter:
          allOf:
            - $ref: '#/components/schemas/signedFixedDecimalString'
          description: >-
            Account balance at the moment this entry was written, as a signed
            fixed-point decimal string at the wallet asset's own scale. A
            point-in-time snapshot, not a guaranteed running total: consecutive
            entries need not differ by their amounts, and an entry is immutable
            once written, so the value is never revised. On a fiat entry the
            figure is the balance the holding bank last reported, which may
            already include this movement. For the current balance read
            `balances[]` on `GET /wallets/{id}`.
        sourceType:
          type: string
          description: Type of the originating resource.
        sourceId:
          type: string
          description: >-
            Polymorphic source correlation key. Transaction sources are rendered
            as txn_ TypeIDs; non-resource reconciliation/request keys remain
            raw.
        description:
          type: string
          description: Human-readable description.
        createdAt:
          type: string
          format: date-time
          description: When the resource was created.
      description: >-
        A single ledger entry on an account: a credit, debit, hold, or release,
        along with the resulting balance.
    AccountTransactionList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/AccountTransaction'
          description: The page of results.
      description: A paginated list of account ledger entries.
    AccountTypeInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AccountTypeInvalid
        code:
          type: number
          enum:
            - 10042
        msg:
          type: string
          enum:
            - >-
              exactly the matching detail object must be present for the given
              type
        cause:
          type: string
    AccountTypeRequirement:
      type: object
      required:
        - type
        - ownerFields
        - detailFields
        - requiredCapabilities
      properties:
        type:
          $ref: '#/components/schemas/ExternalAccountType'
        ownerFields:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/FieldRequirement'
          description: >-
            Owner fields and their requirement level (e.g. `name: required`,
            `address: required`).
        detailFields:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/FieldRequirement'
          description: >-
            Fields on the type's own detail object — `walletExternal.custodian`
            today — and their requirement level.
        requiredCapabilities:
          type: array
          items:
            type: string
          description: >-
            Project capabilities required to create this type (e.g. an outgoing
            rail).
        routingDependsOnCustomer:
          type: boolean
          description: >-
            Only on `bankUs`, and only when `customerId` was omitted on a
            project that holds both vendors: which vendor validates the create
            depends on the owning customer, so this entry is the conservative
            default. Pass `customerId` for the definitive answer.
      description: >-
        Per-type owner-field, detail-field and capability requirements, already
        resolved for the calling project.
    AccountTypeRequirements:
      type: object
      required:
        - requirements
      properties:
        object:
          type: string
          enum:
            - accountTypeRequirements
        requirements:
          type: object
          additionalProperties:
            $ref: '#/components/schemas/AccountTypeRequirement'
          description: >-
            External Account type → the single resolved ruleset for this
            project.
      description: >-
        Reference response for `GET /reference/account-type-requirements`,
        resolved for the calling project. `requirements` is keyed by External
        Account type and carries exactly one ruleset per type — never a menu of
        vendors for the caller to choose between. A type absent from the map
        cannot be created through `POST /external-accounts` on this project.
        Cards are never listed here; register them with `POST
        /external-accounts/cards`.
    AccountTypeRequirementsCustomerNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CustomerNotFound
        code:
          type: number
          enum:
            - 10001
        msg:
          type: string
          enum:
            - customer not found
        cause:
          type: string
      description: >-
        The `customerId` query parameter did not resolve to a customer on this
        project.
    AccountTypeRequirementsNotMetErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AccountTypeRequirementsNotMet
        code:
          type: number
          enum:
            - 10048
        msg:
          type: string
          enum:
            - account type requirements not met for this request
        cause:
          type: string
    Address:
      type: object
      properties:
        line1:
          type: string
          description: 'Street address, line 1.'
        line2:
          type: string
          description: 'Street address, line 2.'
        city:
          type: string
          description: City.
        state:
          type: string
          description: State / province / region.
        country:
          type: string
          description: ISO 3166-1 alpha-2
        zipCode:
          type: string
          description: ZIP / postal code.
      description: A postal address. country is an ISO 3166-1 alpha-2 country code.
    AddressInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AddressInvalid
        code:
          type: number
          enum:
            - 10167
        msg:
          type: string
          enum:
            - address is invalid
        cause:
          type: string
    AmbiguousAmountErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AmbiguousAmount
        code:
          type: number
          enum:
            - 10162
        msg:
          type: string
          enum:
            - only one of source.amount or destination.amount may be specified
        cause:
          type: string
    AmountAboveMaximumErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AmountAboveMaximum
        code:
          type: number
          enum:
            - 10136
        msg:
          type: string
          enum:
            - amount exceeds the maximum
        cause:
          type: string
    AmountBelowMinimumErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AmountBelowMinimum
        code:
          type: number
          enum:
            - 10135
        msg:
          type: string
          enum:
            - amount is below the minimum
        cause:
          type: string
    AmountExceedsCapErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AmountExceedsCap
        code:
          type: number
          enum:
            - 10275
        msg:
          type: string
          enum:
            - >-
              Simulated amount must be greater than 0.00, at most 10.00, and
              carry at most 2 decimal places.
        cause:
          type: string
    AmountNotMultipleErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AmountNotMultiple
        code:
          type: number
          enum:
            - 10223
        msg:
          type: string
          enum:
            - amount is not a multiple of the required increment
        cause:
          type: string
    AmountNotMultipleOfTwentyErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AmountNotMultipleOfTwenty
        code:
          type: number
          enum:
            - 10163
        msg:
          type: string
          enum:
            - >-
              amount is not a multiple of the required increment (v0.10 cash
              pickup)
        cause:
          type: string
    AmountRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AmountRequired
        code:
          type: number
          enum:
            - 10161
        msg:
          type: string
          enum:
            - source.amount or destination.amount is required
        cause:
          type: string
    AwaitingDepositUnsupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - AwaitingDepositUnsupported
        code:
          type: number
          enum:
            - 10300
        msg:
          type: string
          enum:
            - awaiting-deposit funding is not supported
        cause:
          type: string
    BICInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - BICInvalid
        code:
          type: number
          enum:
            - 10044
        msg:
          type: string
          enum:
            - BIC is required
        cause:
          type: string
    BalanceRefreshFailedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - BalanceRefreshFailed
        code:
          type: number
          enum:
            - 10147
        msg:
          type: string
          enum:
            - failed to refresh fiat wallet balance
        cause:
          type: string
    BankAccountType:
      type: string
      enum:
        - checking
        - savings
      description: Bank account sub-type for US accounts.
    BankBeneficiaryNotVerifiedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - BankBeneficiaryNotVerified
        code:
          type: number
          enum:
            - 10293
        msg:
          type: string
          enum:
            - bank beneficiary is not verified
        cause:
          type: string
    BankCanadaAccount:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - bankCanada
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          enum:
            - usd
            - cad
          description: Lowercase asset.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/BankCanadaInstrumentDetails'
      description: >-
        A Canadian bank account. It carries no rail: how money moved is the
        transfer's `rail`.
      title: Canadian bank account
    BankCanadaDestination:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - bankCanada
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          enum:
            - usd
            - cad
          description: Lowercase asset.
        network:
          type: string
          enum:
            - swift
            - local
          description: The rail the money moves on.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/BankCanadaInstrumentDetails'
        payoutOrigin:
          $ref: '#/components/schemas/PayoutOrigin'
        companyDiscretionaryData:
          type: string
          description: >-
            Echo of the ACH companyDiscretionaryData supplied on the originating
            request. Null/absent on non-ACH destinations or when not supplied.
      title: Canadian bank account
    BankCanadaInstrument:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - bankCanada
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          enum:
            - usd
            - cad
          description: Lowercase asset.
        network:
          type: string
          enum:
            - swift
            - local
          description: The rail the money moves on.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/BankCanadaInstrumentDetails'
      description: A Canadian bank account.
      title: Canadian bank account
    BankCanadaInstrumentDetails:
      type: object
      properties:
        bankName:
          type: string
        accountNumberLast4:
          type: string
        institutionNumber:
          type: string
        transitNumber:
          type: string
        holderName:
          type: string
          description: >-
            The account holder: a counterparty's name, or the sender's name when
            the rail carries it.
        memo:
          type: string
          description: >-
            The free-text message that travelled with the money on this side's
            rail.
      description: Canadian bank account details.
    BankCanadaSideDetails:
      type: object
      required:
        - id
        - asset
        - network
      properties:
        id:
          type: string
          description: Canadian bank ExternalAccount ID (`ext_` prefix).
        asset:
          type: string
          enum:
            - usd
            - cad
          description: Canonical asset identifier.
        network:
          type: string
          enum:
            - swift
            - local
          description: USD uses `swift`; CAD uses `local`. Always explicit.
        memo:
          type: string
          allOf:
            - $ref: '#/components/schemas/paymentMemo'
          nullable: true
          description: >-
            Optional message carried in the SWIFT remittance information and
            passed through to the recipient's bank (max 140 chars, ISO
            20022-allowed characters only). Supported when `network` is `swift`;
            rejected with 422 `MemoNotSupported` on `local`.
    BankCanadaSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - bankCanada
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/BankCanadaSideDetails'
        amount:
          $ref: '#/components/schemas/decimalString'
      description: >-
        Deliver to a Canadian bank account. USD routes over SWIFT; CAD over
        local rails.
      title: Canadian bank account
    BankIbanAccount:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - bankIban
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          description: Lowercase asset.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/BankIbanInstrumentDetails'
      description: >-
        An IBAN bank account. It carries no rail: how money moved is the
        transfer's `rail`.
      title: IBAN bank account
    BankIbanDestination:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - bankIban
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          description: Lowercase asset.
        network:
          type: string
          enum:
            - swift
          description: The rail the money moves on.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/BankIbanInstrumentDetails'
        payoutOrigin:
          $ref: '#/components/schemas/PayoutOrigin'
        companyDiscretionaryData:
          type: string
          description: >-
            Echo of the ACH companyDiscretionaryData supplied on the originating
            request. Null/absent on non-ACH destinations or when not supplied.
      title: IBAN bank account
    BankIbanInstrument:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - bankIban
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          description: Lowercase asset.
        network:
          type: string
          enum:
            - swift
          description: The rail the money moves on.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/BankIbanInstrumentDetails'
      description: An IBAN bank account.
      title: IBAN bank account
    BankIbanInstrumentDetails:
      type: object
      properties:
        bankName:
          type: string
        ibanLast4:
          type: string
        bic:
          type: string
        countryCode:
          type: string
          description: ISO 3166-1 alpha-2 country of the bank.
        bankAddress:
          $ref: '#/components/schemas/Address'
        holderName:
          type: string
          description: >-
            The account holder: a counterparty's name, or the sender's name when
            the rail carries it.
        memo:
          type: string
          description: >-
            The free-text message that travelled with the money on this side's
            rail.
      description: IBAN bank account details.
    BankIbanSideDetails:
      type: object
      required:
        - id
        - asset
      properties:
        id:
          type: string
          description: IBAN ExternalAccount ID (`ext_` prefix).
        asset:
          type: string
          enum:
            - usd
          description: Canonical asset identifier.
        network:
          type: string
          enum:
            - swift
          description: Network identifier.
          default: swift
        memo:
          type: string
          allOf:
            - $ref: '#/components/schemas/paymentMemo'
          nullable: true
          description: >-
            Optional customer-supplied payment memo delivered via SWIFT
            remittance information. See BankUsSideDetails.memo's doc for the
            full contract — this is the same field, same charset/length bound,
            same honored-surface table, applied to the SWIFT rail instead of
            Fedwire.
    BankIbanSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - bankIban
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/BankIbanSideDetails'
        amount:
          $ref: '#/components/schemas/decimalString'
      description: Deliver to an IBAN account over SWIFT (USD).
      title: IBAN bank account
    BankRailNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - BankRailNotSupported
        code:
          type: number
          enum:
            - 10294
        msg:
          type: string
          enum:
            - bank payment rail is not supported for this beneficiary
        cause:
          type: string
    BankRailUnavailableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - BankRailUnavailable
        code:
          type: number
          enum:
            - 10295
        msg:
          type: string
          enum:
            - bank payment rail is unavailable
        cause:
          type: string
    BankRoutingBlock:
      type: object
      required:
        - bankName
        - bankAddress
        - accountNumber
      properties:
        supportedSources:
          type: array
          items:
            $ref: '#/components/schemas/BankRoutingSource'
          description: The assets and rails this routing block accepts deposits on.
        bankName:
          type: string
        bankAddress:
          type: string
        accountNumber:
          type: string
        routingNumber:
          type: string
          description: US ABA routing number; left out when the block has none.
        accountType:
          type: string
          description: >-
            US account type; left out when the block has none. Always "checking"
            when present.
        bic:
          type: string
          description: >-
            SWIFT/BIC code; present when `supportedSources` includes
            `internationalWire`.
        memo:
          type: string
          description: >-
            Reference senders must include when routing through a correspondent
            bank; left out when none is needed.
      description: >-
        One bank-routing entry within VirtualAccountInstructions.bankUs. A
        single entry can accept both US domestic and international deposits; a
        field that applies to none of the rails in `supportedSources` is left
        out.
    BankRoutingSource:
      type: object
      required:
        - asset
        - rail
      properties:
        asset:
          type: string
          description: Lowercase asset.
        rail:
          allOf:
            - $ref: '#/components/schemas/TransferRail'
          description: The rail the deposit arrives on.
      description: >-
        An asset a sender can deposit into a routing block, and the rail it
        arrives on.
    BankUsAccount:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - bankUs
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          enum:
            - usd
          description: Lowercase asset.
        instantRail:
          allOf:
            - $ref: '#/components/schemas/InstantRail'
          description: Only when `network` is `instant`.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/BankUsInstrumentDetails'
      description: >-
        A US bank account. It carries no rail: how money moved is the transfer's
        `rail`.
      title: US bank account
    BankUsDepositAddressDetails:
      type: object
      required:
        - id
        - asset
        - network
      properties:
        id:
          type: string
          description: US bank ExternalAccount ID (`ext_` prefix).
        asset:
          type: string
          enum:
            - usd
          description: Canonical asset identifier.
        memo:
          type: string
          allOf:
            - $ref: '#/components/schemas/paymentMemo'
          nullable: true
          description: >-
            Optional payment memo delivered to the beneficiary's bank with the
            payout.


            Honored on these rails, each with its own limit: - `network: "ach"`
            or `"achSameDay"`: carried as the ACH addenda. NACHA characters only
            (uppercase letters, digits, space and `.&()-+=':?@_#%`), max 80. -
            `network: "wire"` or `"rtp"`: ISO 20022 characters only (see the
            `paymentMemo` scalar), max 140. - A `bankIban` or `bankCanada`
            destination on `swift`: ISO 20022, max 140.


            A memo outside its rail's characters or length is rejected with 422.


            On a Quote, the memo is honored only on a `walletFiat`-source quote,
            or on a `walletCrypto`-source quote to a `bankUs` destination; any
            other corridor rejects it. A Virtual Account destination offers no
            `rtp` rail. On a Deposit Address the memo is read when each payout
            is built, so an edit applies only to payouts built after it, never
            to one already sent.


            Where a memo is not honored — a rail with no remittance field, such
            as `bankCanada`'s `local` leg, or a Quote corridor outside the two
            above — a non-empty memo is rejected with 422 `MemoNotSupported`,
            its `cause` carrying `reason=unsupportedRail`, rather than accepted
            and dropped. Sending `null`, omitting the field, or sending only
            whitespace is always accepted and means no memo of your own: the
            payout then carries the memo OMS composes for the rail, if any.
        companyDiscretionaryData:
          type: string
          allOf:
            - $ref: '#/components/schemas/companyDiscretionaryData'
          nullable: true
          description: >-
            Optional ACH-only field for the originator's internal use (NACHA
            batch header). See the companyDiscretionaryData scalar doc. Honored
            only when network is "ach" or "achSameDay"; 422 `MemoNotSupported`
            on "wire" and "rtp", because the field itself is an ACH-only
            concept.
        network:
          type: string
          enum:
            - ach
            - achSameDay
            - wire
            - rtp
            - instant
            - intraBank
          description: >-
            Rail to deliver on. `ach` (1-3 business days), `achSameDay`, `wire`,
            or `rtp` (Real-Time Payments — seconds, 24/7). `rtp` is available on
            manual Quote and Deposit Address destinations, but not on Virtual
            Accounts. RTP settles irrevocably once accepted and carries no
            return path, so a failed `rtp` delivery falls back to the Deposit
            Address's `returnDestination` like any other rail. The receiving
            bank must participate in RTP — a non-participating account is
            rejected at create/update time with 422
            `destinationBankRailNotSupported`, whose `details.supportedNetworks`
            lists the rails that account can actually receive on. `instant` is
            the same rail as `rtp`, which is accepted as its alias in this API
            version. `intraBank` requires your project's configured outgoing US
            rails to include `crnow`, else the request is rejected with
            `intraBankNotSupported` (422).
      description: >-
        The Deposit Address `bankUs` destination details — the same shared
        `BankUsSideDetailsBase` used by Quote and VA bankUs arms. Quote and
        Deposit Address destinations include `rtp`; Virtual Accounts retain a
        three-rail network enum.
    BankUsDepositAddressSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - bankUs
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/BankUsDepositAddressDetails'
        amount:
          $ref: '#/components/schemas/decimalString'
      description: >-
        Deliver to a US bank account — the Deposit Address arm. It remains
        distinct from the Quote arm so the standing-destination contract can
        evolve without coupling the two surfaces; see
        `BankUsDepositAddressDetails`.
      title: US bank account
    BankUsDestination:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - bankUs
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          enum:
            - usd
          description: Lowercase asset.
        network:
          type: string
          enum:
            - ach
            - achSameDay
            - wire
            - rtp
            - instant
          description: >-
            The rail the money moves on. `instant` is an RTP or FedNow payment,
            named in `instantRail`; a record created before the umbrella names
            were introduced keeps `rtp`.
        instantRail:
          allOf:
            - $ref: '#/components/schemas/InstantRail'
          description: Only when `network` is `instant`.
        secCode:
          allOf:
            - $ref: '#/components/schemas/SecCode'
          description: >-
            ACH SEC code, only on `ach` and `achSameDay`. Derived from the
            destination owner's and the customer's entity type.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/BankUsInstrumentDetails'
        payoutOrigin:
          $ref: '#/components/schemas/PayoutOrigin'
        companyDiscretionaryData:
          type: string
          description: >-
            Echo of the ACH companyDiscretionaryData supplied on the originating
            request. Null/absent on non-ACH destinations or when not supplied.
      title: US bank account
    BankUsInstrument:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - bankUs
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          enum:
            - usd
          description: Lowercase asset.
        network:
          type: string
          enum:
            - ach
            - achSameDay
            - wire
            - rtp
            - instant
          description: >-
            The rail the money moves on. `instant` is an RTP or FedNow payment,
            named in `instantRail`; a record created before the umbrella names
            were introduced keeps `rtp`.
        instantRail:
          allOf:
            - $ref: '#/components/schemas/InstantRail'
          description: Only when `network` is `instant`.
        secCode:
          allOf:
            - $ref: '#/components/schemas/SecCode'
          description: >-
            ACH SEC code, only on `ach` and `achSameDay`. Derived from the
            destination owner's and the customer's entity type.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/BankUsInstrumentDetails'
      description: A US bank account.
      title: US bank account
    BankUsInstrumentDetails:
      type: object
      properties:
        bankName:
          type: string
        accountNumberLast4:
          type: string
        routingNumber:
          type: string
        accountType:
          $ref: '#/components/schemas/BankAccountType'
        holderName:
          type: string
          description: >-
            The account holder: a counterparty's name, or the sender's name when
            the rail carries it.
        memo:
          type: string
          description: >-
            The free-text message that travelled with the money on this side's
            rail.
      description: US bank account details.
    BankUsSideDetails:
      type: object
      required:
        - id
        - asset
        - network
      properties:
        id:
          type: string
          description: US bank ExternalAccount ID (`ext_` prefix).
        asset:
          type: string
          enum:
            - usd
          description: Canonical asset identifier.
        memo:
          type: string
          allOf:
            - $ref: '#/components/schemas/paymentMemo'
          nullable: true
          description: >-
            Optional payment memo delivered to the beneficiary's bank with the
            payout.


            Honored on these rails, each with its own limit: - `network: "ach"`
            or `"achSameDay"`: carried as the ACH addenda. NACHA characters only
            (uppercase letters, digits, space and `.&()-+=':?@_#%`), max 80. -
            `network: "wire"` or `"rtp"`: ISO 20022 characters only (see the
            `paymentMemo` scalar), max 140. - A `bankIban` or `bankCanada`
            destination on `swift`: ISO 20022, max 140.


            A memo outside its rail's characters or length is rejected with 422.


            On a Quote, the memo is honored only on a `walletFiat`-source quote,
            or on a `walletCrypto`-source quote to a `bankUs` destination; any
            other corridor rejects it. A Virtual Account destination offers no
            `rtp` rail. On a Deposit Address the memo is read when each payout
            is built, so an edit applies only to payouts built after it, never
            to one already sent.


            Where a memo is not honored — a rail with no remittance field, such
            as `bankCanada`'s `local` leg, or a Quote corridor outside the two
            above — a non-empty memo is rejected with 422 `MemoNotSupported`,
            its `cause` carrying `reason=unsupportedRail`, rather than accepted
            and dropped. Sending `null`, omitting the field, or sending only
            whitespace is always accepted and means no memo of your own: the
            payout then carries the memo OMS composes for the rail, if any.
        companyDiscretionaryData:
          type: string
          allOf:
            - $ref: '#/components/schemas/companyDiscretionaryData'
          nullable: true
          description: >-
            Optional ACH-only field for the originator's internal use (NACHA
            batch header). See the companyDiscretionaryData scalar doc. Honored
            only when network is "ach" or "achSameDay"; 422 `MemoNotSupported`
            on "wire" and "rtp", because the field itself is an ACH-only
            concept.
        network:
          type: string
          enum:
            - ach
            - achSameDay
            - wire
            - rtp
            - instant
            - intraBank
          description: >-
            Rail the payout moves on. `instant` settles within seconds, around
            the clock, and requires both that the rail is enabled for your
            project and that the beneficiary's bank can receive on it — either
            gate failing is a 422 `BankRailNotSupported`. `memo` is honored on
            `instant` (ISO 20022, max 140); `companyDiscretionaryData` is not.
            `rtp` is accepted as an alias of `instant` in this API version.
            `intraBank` requires your project's configured outgoing US rails to
            include `crnow`, else the request is rejected with
            `intraBankNotSupported` (422).
    BankUsSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - bankUs
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/BankUsSideDetails'
        amount:
          $ref: '#/components/schemas/decimalString'
      description: Deliver to a US bank account.
      title: US bank account
    BillingAddressInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - BillingAddressInvalid
        code:
          type: number
          enum:
            - 10063
        msg:
          type: string
          enum:
            - billingAddress.city is required
        cause:
          type: string
    BillingAddressSource:
      type: string
      enum:
        - provided
        - customerDefault
      description: >-
        Where a card's billing address came from. `provided` = supplied on the
        request; `customerDefault` = filled from the owning customer's address
        because the request omitted it.
    BlockchainAddressInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - BlockchainAddressInvalid
        code:
          type: number
          enum:
            - 10049
        msg:
          type: string
          enum:
            - blockchainAddress is required
        cause:
          type: string
    BlockchainAsset:
      type: object
      required:
        - protocol
        - chainId
        - tokenId
      properties:
        protocol:
          $ref: '#/components/schemas/BlockchainProtocol'
        chainId:
          type: string
        tokenId:
          type: string
    BlockchainProtocol:
      type: string
      enum:
        - evm
        - svm
        - sui
        - tvm
    BuyNotAllowedAtLocationErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - BuyNotAllowedAtLocation
        code:
          type: number
          enum:
            - 10120
        msg:
          type: string
          enum:
            - the specified cash location does not allow buy transactions
        cause:
          type: string
    CVVInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CVVInvalid
        code:
          type: number
          enum:
            - 10058
        msg:
          type: string
          enum:
            - cvv must be 3-4 digits
        cause:
          type: string
    CannotDeletePendingVirtualAccountErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CannotDeletePendingVirtualAccount
        code:
          type: number
          enum:
            - 10202
        msg:
          type: string
          enum:
            - cannot delete a pending virtual account
        cause:
          type: string
    CardBrand:
      type: string
      enum:
        - visa
        - mastercard
        - amex
        - discover
      description: >-
        Card network/brand. Derived server-side from the PAN; never accepted on
        a request.
    CardCreateDetails:
      type: object
      required:
        - cardNumber
        - cvv
        - expiryMonth
        - expiryYear
      properties:
        cardNumber:
          type: string
          description: >-
            Write-only card number. VGS-enabled environments require a VGS alias
            and reject raw values with `CardNumberInvalid`. Sandbox environments
            with VGS disabled require a 12–19 digit test card number and reject
            aliases. Never returned; the response carries `details.last4`.
        cvv:
          type: string
          description: >-
            Write-only CVV. VGS-enabled environments require a VGS alias and
            reject raw values with `CVVInvalid`. Sandbox environments with VGS
            disabled require a 3–4 digit test CVV and reject aliases. Never
            returned.
        expiryMonth:
          type: integer
          format: int32
          description: 1-12.
        expiryYear:
          type: integer
          format: int32
          description: Four-digit calendar year.
      description: >-
        Card number, CVV and expiry. VGS-enabled environments require aliases
        for `cardNumber` and `cvv`; sandbox environments with VGS disabled
        require raw digits from test cards and reject aliases. Never send real
        card data directly to the API. Both fields are write-only and never
        returned or stored; only the last four digits, brand and expiry are
        kept.
    CardCustomerNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CustomerNotFound
        code:
          type: number
          enum:
            - 10001
        msg:
          type: string
          enum:
            - customer not found
        cause:
          type: string
      description: The customer does not exist on this project.
    CardDestination:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - card
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: The external account (`ext_`).
        asset:
          type: string
          enum:
            - usd
          description: Lowercase asset.
        network:
          type: string
          enum:
            - card
          description: The rail the money moves on.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/CardInstrumentDetails'
        payoutOrigin:
          $ref: '#/components/schemas/PayoutOrigin'
        companyDiscretionaryData:
          type: string
          description: >-
            Echo of the ACH companyDiscretionaryData supplied on the originating
            request. Null/absent on non-ACH destinations or when not supplied.
      title: Card
    CardExpiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CardExpired
        code:
          type: number
          enum:
            - 10060
        msg:
          type: string
          enum:
            - card has expired
        cause:
          type: string
    CardExpiryInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CardExpiryInvalid
        code:
          type: number
          enum:
            - 10059
        msg:
          type: string
          enum:
            - expiryMonth must be between 1 and 12
        cause:
          type: string
    CardInstrument:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - card
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: The external account (`ext_`).
        asset:
          type: string
          enum:
            - usd
          description: Lowercase asset.
        network:
          type: string
          enum:
            - card
          description: The rail the money moves on.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/CardInstrumentDetails'
      description: A card.
      title: Card
    CardInstrumentDetails:
      type: object
      properties:
        brand:
          $ref: '#/components/schemas/CardBrand'
        last4:
          type: string
        cardType:
          $ref: '#/components/schemas/CardType'
        expiryMonth:
          type: integer
          format: int32
        expiryYear:
          type: integer
          format: int32
        billingAddressSource:
          $ref: '#/components/schemas/BillingAddressSource'
      description: Card details.
    CardLegacyBadRequestErrorResponse:
      type: object
      required:
        - error
        - code
      properties:
        error:
          type: string
        code:
          type: string
          enum:
            - invalidRequestBody
            - unknownField
            - invalidCustomerId
        details:
          type: object
          additionalProperties: {}
      description: 'A malformed request body, unknown field, or invalid customer ID.'
    CardLegacyBodyTooLargeErrorResponse:
      type: object
      required:
        - error
        - code
      properties:
        error:
          type: string
        code:
          type: string
          enum:
            - requestBodyTooLarge
      description: The request body exceeds the size limit.
    CardLegacyInternalErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
        code:
          type: string
      description: An internal error prevented registration.
    CardLegacyProjectMissingErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          enum:
            - missing project context
      description: The request has no project context.
    CardLegacyProviderErrorResponse:
      type: object
      required:
        - error
        - code
      properties:
        error:
          type: string
        code:
          type: string
          enum:
            - providerError
      description: The card provider could not authenticate the request.
    CardLegacyScreenUnavailableErrorResponse:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          enum:
            - country screen unavailable
      description: Country screening is temporarily unavailable.
    CardLimitReachedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CardLimitReached
        code:
          type: number
          enum:
            - 10055
        msg:
          type: string
          enum:
            - >-
              customer has reached the maximum number of cards; delete an
              existing card before adding another
        cause:
          type: string
    CardMustUseCardEndpointErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CardMustUseCardEndpoint
        code:
          type: number
          enum:
            - 10056
        msg:
          type: string
          enum:
            - >-
              card external accounts must be created via POST
              /external-accounts/cards
        cause:
          type: string
    CardNotEligibleErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CardNotEligible
        code:
          type: number
          enum:
            - 10258
        msg:
          type: string
          enum:
            - card not found or not a card
        cause:
          type: string
    CardNotEnabledForProjectErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CardNotEnabledForProject
        code:
          type: number
          enum:
            - 10336
        msg:
          type: string
          enum:
            - cards are not enabled for this project
        cause:
          type: string
    CardNumberInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CardNumberInvalid
        code:
          type: number
          enum:
            - 10057
        msg:
          type: string
          enum:
            - cardNumber must be 12-19 digits
        cause:
          type: string
    CardProviderErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CardProvider
        code:
          type: number
          enum:
            - 10034
        msg:
          type: string
          enum:
            - card provider rejected the card
        cause:
          type: string
    CardRailUnavailableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CardRailUnavailable
        code:
          type: number
          enum:
            - 10145
        msg:
          type: string
          enum:
            - card payment rail is unavailable
        cause:
          type: string
    CardRequest:
      type: object
      required:
        - customerId
        - details
        - webSessionId
        - deviceFingerprint
      properties:
        customerId:
          type: string
          description: Owning customer ID (`cst_` prefix). Cards must be customer-owned.
        details:
          allOf:
            - $ref: '#/components/schemas/CardCreateDetails'
          description: >-
            Card number and CVV plus expiry (write-only); see
            `CardCreateDetails` for VGS-enabled and sandbox test-input
            requirements.
        billingAddress:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountCardBillingAddress'
          description: >-
            Card billing address (issuer AVS / fraud). Optional: when omitted,
            the owning customer's address is used (see `billingAddressSource`).
        webSessionId:
          type: string
          minLength: 1
          maxLength: 1024
          pattern: '^[!-~]+$'
          description: >-
            SDK risk session paired with deviceFingerprint. Required, 1–1024
            printable non-space ASCII characters in every environment, including
            sandbox. Forwarded unchanged; write-only, never returned.
        deviceFingerprint:
          type: string
          minLength: 1
          maxLength: 1024
          pattern: '^[!-~]+$'
          description: >-
            SDK device fingerprint paired with webSessionId. Required, 1–1024
            printable non-space ASCII characters in every environment, including
            sandbox. Forwarded unchanged; write-only, never returned.
        label:
          type: string
        metadata:
          type: object
          additionalProperties:
            type: string
      description: >-
        Register a card as a customer-owned External Account, via the dedicated
        `POST /external-accounts/cards` endpoint. Cards are always
        customer-owned, so `customerId` is supplied directly here (no owner
        discriminator). The owner must be an individual customer, and the
        cardholder name is always that customer's `firstName` and `lastName` (a
        name the card issuer cannot accept fails with `422
        cardholderNameInvalid`). The card number and CVV live under `details`,
        using aliases in VGS-enabled environments or test digits in sandbox
        environments with VGS disabled. `brand` and `cardType` are derived
        server-side from the card number and are not accepted on the request.
    CardSideDetails:
      type: object
      required:
        - id
        - asset
      properties:
        id:
          type: string
          description: Card ExternalAccount ID (`ext_` prefix).
        asset:
          type: string
          enum:
            - usd
          description: Canonical asset identifier.
    CardSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - card
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/CardSideDetails'
        amount:
          $ref: '#/components/schemas/decimalString'
      description: >-
        A registered debit card. Valid as a source (pull-from-card funding) or a
        destination (push-to-card payout). `network` is inferred server-side and
        returned on the response only.
      title: Card
    CardType:
      type: string
      enum:
        - debit
        - credit
        - prepaid
      description: >-
        Card funding type, derived server-side from the PAN. Only `debit` is
        supported today; `credit` and `prepaid` are reserved for future
        push-to-card / pull-from-card support.
    CardholderNameInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CardholderNameInvalid
        code:
          type: number
          enum:
            - 10380
        msg:
          type: string
          enum:
            - the owning customer's name cannot be used as a cardholder name
        cause:
          type: string
    CashDestination:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - cash
        asset:
          type: string
          description: Lowercase asset.
        details:
          $ref: '#/components/schemas/CashInstrumentDetails'
        payoutOrigin:
          $ref: '#/components/schemas/PayoutOrigin'
        pickupCode:
          type: string
          description: >-
            Retail pickup code for a cash payout. Populated only on cash-out
            (pickup) destinations.
        companyDiscretionaryData:
          type: string
          description: >-
            Echo of the ACH companyDiscretionaryData supplied on the originating
            request. Null/absent on non-ACH destinations or when not supplied.
      title: Cash
    CashFlow:
      type: string
      enum:
        - cash_in
        - cash_out
      description: >-
        Direction of a cash flow. cash_in moves cash to crypto; cash_out moves
        crypto to cash.
    CashIn:
      type: object
      required:
        - id
        - status
        - customer
        - source
        - destination
        - depositInstructions
        - pricing
        - createdAt
        - updatedAt
        - expiresAt
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Cash-in ID (`ci_` prefix).
        status:
          allOf:
            - $ref: '#/components/schemas/CashInStatus'
          description: Current lifecycle status of the cash-in.
        customer:
          allOf:
            - $ref: '#/components/schemas/CustomerRef'
          description: The customer that owns this record.
        failure:
          allOf:
            - $ref: '#/components/schemas/Reason'
          description: Why the cash-in failed. Present only when `status` is `failed`.
        source:
          allOf:
            - $ref: '#/components/schemas/CashInstrument'
          description: The retail location the customer deposits cash at.
        destination:
          allOf:
            - $ref: '#/components/schemas/CashInDestinationInstrument'
          description: The customer's wallet the converted funds are delivered to.
        depositInstructions:
          allOf:
            - $ref: '#/components/schemas/CashInDepositInstructions'
          description: The code the customer presents at the retail location.
        pricing:
          allOf:
            - $ref: '#/components/schemas/Pricing'
          description: >-
            The cash amount, what arrives in the wallet, the rate and the fees.
            `pricing.source.amount` is the indicated amount before the cash is
            paid, then the amount authorised at the register once the cash is
            paid.
        transactionId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The Transaction linked to this cash-in. Set once the linked
            transaction exists; null while pending.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: Free-form key-value pairs supplied at creation or update.
        createdAt:
          type: string
          format: date-time
          description: When the cash-in was created.
        updatedAt:
          type: string
          format: date-time
          description: When the cash-in was last updated.
        completedAt:
          type: string
          format: date-time
          description: >-
            When the cash-in completed. Present only when `status` is
            `completed`.
        consumedAt:
          type: string
          format: date-time
          description: >-
            Leg 1 start: when the customer scanned the cash-in code at the
            retail location.
        fulfilledAt:
          type: string
          format: date-time
          description: >-
            Leg 1 done: when the cash was loaded and the provider can no longer
            cancel it.
        buyConfirmedAt:
          type: string
          format: date-time
          description: 'Leg 2 done: when the crypto purchase was confirmed.'
        expiresAt:
          type: string
          format: date-time
          description: >-
            Expiry of the `cashInCode` — the single expiry field for a cash-in.
            Refreshing the cash-in issues a new `cashInCode` but does not extend
            this expiry. Once it has passed, the cash-in can no longer be
            refreshed.
      description: >-
        A code-based cash deposit. The customer takes the issued code to a
        retail location and deposits cash, which OMS converts to crypto and
        delivers to the destination. Amounts start as estimates and are
        finalized once the cash is deposited.
      example:
        id: ci_44vxe2xk8gfsjehfcw3npt5bg8
        status: pending
        customer:
          id: cst_vfa0nxw6zvyws9g237jrxn4y7k
        source:
          type: cash
          asset: usd
          details:
            locationId: loc_01H9Xd
            locationName: 'CVS Pharmacy #4521'
            locationAddress:
              line1: 123 Main St
              city: San Francisco
              state: CA
              zipCode: '94105'
              country: US
            locationProvider: greendot
        destination:
          type: walletCrypto
          id: wlt_5h4jzzpr9xre3bamd9ca7qyghn
          asset: usdc
          network: polygon
          details:
            address: '0x7b3a9f2c4d1ea8bf6390ce5d2b7fa104c8e3d9b1'
        pricing:
          source:
            asset: usd
            amount: '200.00'
          destination:
            asset: usdc
            amount: '200.000000'
          fees: []
          exchangeRate: '1.0000'
          fixedAmountSide: source
          sponsorGas: true
        depositInstructions:
          cashInCode: 483 291
        expiresAt: '2026-05-15T18:32:48Z'
        createdAt: '2026-05-15T17:32:48Z'
        updatedAt: '2026-05-15T17:32:48Z'
    CashInAlreadyDepositedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashInAlreadyDeposited
        code:
          type: number
          enum:
            - 10393
        msg:
          type: string
          enum:
            - the cash for this cash-in was already deposited at the register
        cause:
          type: string
    CashInAlreadyScannedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashInAlreadyScanned
        code:
          type: number
          enum:
            - 10390
        msg:
          type: string
          enum:
            - the cash-in's code was already scanned at the cash location
        cause:
          type: string
    CashInBarcodeInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashInBarcodeInvalid
        code:
          type: number
          enum:
            - 10394
        msg:
          type: string
          enum:
            - the barcode of this cash-in is no longer valid
        cause:
          type: string
    CashInDepositInstructions:
      type: object
      required:
        - cashInCode
      properties:
        cashInCode:
          type: string
          description: Machine-readable code the customer presents at the register.
      description: The deposit code a customer presents at the retail location.
    CashInDestination:
      type: object
      properties:
        wallet:
          $ref: '#/components/schemas/CashInDestinationWallet'
        asset:
          type: string
          description: Canonical asset identifier.
        network:
          type: string
          description: Network identifier.
        amountGross:
          type: string
          description: Amount on this side before fees are applied.
        amountNet:
          type: string
          description: >-
            Amount after fees - what is actually pulled from a source, or
            delivered to a destination.
        feesDeducted:
          $ref: '#/components/schemas/FeesDeducted'
      description: The crypto destination a cash-in is converted to and delivered to.
    CashInDestinationInstrument:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletCryptoInstrument'
        - $ref: '#/components/schemas/WalletExternalInstrument'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletCryptoInstrument'
          walletExternal: '#/components/schemas/WalletExternalInstrument'
      description: >-
        The wallet a cash-in delivers to: an OMS wallet given by id, or an
        address given without one.
    CashInDestinationWallet:
      type: object
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Unique identifier.
        externalAccount:
          type: string
          description: 'Registered External Account receiving the funds, when applicable.'
        blockchainAddress:
          type: string
          description: >-
            On-chain address. For an EVM network the address must be
            all-lowercase, all-uppercase, or a valid EIP-55 checksummed form; an
            inconsistent mixed-case address is rejected as a likely casing typo,
            and the zero address is rejected. Solana/SUI are validated per their
            own network rules.
      description: The wallet receiving the converted funds.
    CashInExpiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashInExpired
        code:
          type: number
          enum:
            - 10392
        msg:
          type: string
          enum:
            - the cash-in has expired
        cause:
          type: string
    CashInList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/CashIn'
          description: The page of results.
      description: A paginated list of cash-ins.
    CashInNotCancellableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashInNotCancellable
        code:
          type: number
          enum:
            - 10391
        msg:
          type: string
          enum:
            - only a pending cash-in can be cancelled
        cause:
          type: string
    CashInNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashInNotFound
        code:
          type: number
          enum:
            - 10113
        msg:
          type: string
          enum:
            - cash-in not found
        cause:
          type: string
    CashInSource:
      type: object
      required:
        - asset
      properties:
        asset:
          type: string
          description: Canonical asset identifier.
        network:
          type: string
          description: Network identifier.
        email:
          type: string
          description: Email address.
        indicatedAmount:
          type: string
          description: The cash amount the customer indicated they will deposit.
        amount:
          type: string
          description: 'The cash amount, as a decimal string.'
        amountGross:
          type: string
          description: Amount on this side before fees are applied.
        amountNet:
          type: string
          description: >-
            Amount after fees - what is actually pulled from a source, or
            delivered to a destination.
        feesDeducted:
          $ref: '#/components/schemas/FeesDeducted'
      description: 'Cash side of a cash-in: the fiat asset and amounts.'
    CashInStatus:
      type: string
      enum:
        - pending
        - processing
        - completed
        - failed
        - expired
        - cancelled
      description: >-
        Lifecycle of a cash-in. pending: code issued, awaiting the register
        scan. processing: the barcode was scanned and the purchase outcome is
        pending. completed: converted and delivered. failed: the deposit or
        conversion did not succeed. expired: the code expired before any
        deposit. cancelled: cancelled by the partner, or superseded by a new
        cash-in, before the code was scanned, or voided by the cashier after the
        scan but before the cash was loaded (`fulfilledAt` unset).
    CashInfo:
      type: object
      required:
        - locationId
        - locationReference
      properties:
        locationId:
          type: string
          description: Cash location ID from `GET /cash-locations`.
        locationReference:
          type: string
          description: 'Provider reference for the location, from `GET /cash-locations`.'
      description: >-
        The retail location chosen for the deposit, by ID and provider
        reference.
    CashInstrument:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - cash
        asset:
          type: string
          description: Lowercase asset.
        details:
          $ref: '#/components/schemas/CashInstrumentDetails'
      description: A cash location. It has no id; the location is in `details`.
      title: Cash
    CashInstrumentDetails:
      type: object
      properties:
        locationId:
          type: string
        locationName:
          type: string
        locationAddress:
          $ref: '#/components/schemas/Address'
        locationProvider:
          type: string
          description: >-
            The cash network the location belongs to, lowercase, such as
            `greendot`.
      description: Cash location details.
    CashLocation:
      type: object
      required:
        - id
        - object
        - cashLocationReference
        - name
        - provider
        - address
        - city
        - state
        - zipCode
        - country
        - coordinates
        - buyAllowed
        - sellAllowed
      properties:
        id:
          type: string
          description: >-
            Cash-location ID (`loc_` prefix). Pass it as `cash.locationId` when
            creating a cash-in, or as `details.cashLocationId` on the cash side
            of a quote or transaction for a cash payout. The part after the
            prefix is the provider's own catalog identifier rather than a
            generated ID (e.g. `loc_CVS10804`), so treat the whole value as an
            opaque string.
        object:
          type: string
          enum:
            - cashLocation
          description: Resource type discriminator. Always "cashLocation".
        cashLocationReference:
          type: string
          description: 'Provider reference for the location, from `GET /cash-locations`.'
        name:
          type: string
          description: Display name.
        provider:
          type: string
          description: Cash provider.
        address:
          type: string
          description: Postal address.
        city:
          type: string
          description: City.
        state:
          type: string
          description: State / province / region.
        zipCode:
          type: string
          description: ZIP / postal code.
        country:
          type: string
          description: ISO 3166-1 alpha-2 country code.
        coordinates:
          $ref: '#/components/schemas/CashLocationCoordinates'
        distance:
          type: number
          format: double
          description: Distance from the search coordinates.
        distanceUnit:
          type: string
          description: 'Unit for `distance` (e.g. mi, km).'
        buyAllowed:
          type: boolean
          description: Whether cash-in (buy) is supported at this location.
        sellAllowed:
          type: boolean
          description: Whether cash-out (sell) is supported at this location.
        hours:
          type: string
          description: Opening hours.
        supportedAssets:
          type: array
          items:
            type: string
          description: Assets supported at this location.
        maxTransaction:
          type: string
          description: Maximum single-transaction amount at this provider.
        maxDailyPerCustomer:
          type: string
          description: Maximum daily total per customer at this provider.
      description: >-
        A retail location where a customer can deposit or pick up cash, with its
        capabilities and distance from the search coordinates.
    CashLocationCoordinates:
      type: object
      required:
        - latitude
        - longitude
      properties:
        latitude:
          type: number
          format: double
          description: Latitude in decimal degrees.
        longitude:
          type: number
          format: double
          description: Longitude in decimal degrees.
      description: Latitude/longitude pair.
    CashLocationList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/CashLocation'
          description: The page of results.
      description: 'Cash locations in range, nearest first.'
    CashNotAvailableInCountryErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashNotAvailableInCountry
        code:
          type: number
          enum:
            - 10105
        msg:
          type: string
          enum:
            - >-
              cash deposit is only available in the customer's registered
              country
        cause:
          type: string
    CashNotAvailableInStateErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashNotAvailableInState
        code:
          type: number
          enum:
            - 10106
        msg:
          type: string
          enum:
            - cash onramp not available in this customer's state
        cause:
          type: string
    CashPayoutExceedsMaximumErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashPayoutExceedsMaximum
        code:
          type: number
          enum:
            - 10164
        msg:
          type: string
          enum:
            - amount exceeds the maximum (v0.10 cash pickup)
        cause:
          type: string
    CashPickupInstrument:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - cash
        asset:
          type: string
          description: Lowercase asset.
        details:
          $ref: '#/components/schemas/CashInstrumentDetails'
        pickupCode:
          type: string
          description: Retail pickup code for a cash payout.
      description: A cash location a payout is collected at.
      title: Cash
    CashPickupNotAllowedInCountryErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashPickupNotAllowedInCountry
        code:
          type: number
          enum:
            - 10155
        msg:
          type: string
          enum:
            - cash pickup is only available in the customer's registered country
        cause:
          type: string
    CashPickupNotAllowedInStateErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CashPickupNotAllowedInState
        code:
          type: number
          enum:
            - 10156
        msg:
          type: string
          enum:
            - cash pickup is only available in the customer's registered state
        cause:
          type: string
    CashSideDetails:
      type: object
      required:
        - asset
        - cashLocationId
        - cashLocationReference
        - amount
      properties:
        asset:
          type: string
          enum:
            - usd
          description: Canonical asset identifier.
        cashLocationId:
          type: string
          description: Cash location ID from `GET /cash-locations`.
        cashLocationReference:
          type: string
          description: 'Provider reference for the location, from `GET /cash-locations`.'
        amount:
          allOf:
            - $ref: '#/components/schemas/decimalString'
          description: 'Multiple of 20.00, at most 400.00.'
    CashSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - cash
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/CashSideDetails'
      description: >-
        Deliver as a cash pickup at a retail payout location. Amount is required
        in `details` and must be a multiple of 20.00, up to a maximum of 400.00
        per transaction.
      title: Cash
    CoinmeAddressClaimedByOtherFlowErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CoinmeAddressClaimedByOtherFlow
        code:
          type: number
          enum:
            - 10314
        msg:
          type: string
          enum:
            - >-
              this customer's custodial address for this asset and chain family
              is already claimed by another active flow
        cause:
          type: string
    CoinmeVirtualAccountsNotEnabledErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CoinmeVirtualAccountsNotEnabled
        code:
          type: number
          enum:
            - 10337
        msg:
          type: string
          enum:
            - custodial virtual accounts are not enabled for this project
        cause:
          type: string
    ConcurrentModificationErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ConcurrentModification
        code:
          type: number
          enum:
            - 10232
        msg:
          type: string
          enum:
            - >-
              pair changed since it was inspected; re-read its status and retry
              with the current version
        cause:
          type: string
    ConflictErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - Conflict
        code:
          type: number
          enum:
            - 4000
        msg:
          type: string
          enum:
            - resource conflict
        cause:
          type: string
    ConvertingSendInFlightErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ConvertingSendInFlight
        code:
          type: number
          enum:
            - 10366
        msg:
          type: string
          enum:
            - >-
              a converting send to this external account is pending, processing,
              or failed but still owned by recovery; a retry succeeds only once
              that send has completed, recovery has finished with it, or
              operations have closed it; to cut the account off now, use
              emergencyRevoke=true
        cause:
          type: string
    Counterparty:
      type: object
      required:
        - customer
      properties:
        id:
          $ref: '#/components/schemas/typeId'
        customer:
          allOf:
            - $ref: '#/components/schemas/CustomerRef'
          description: The customer whose address book holds this counterparty.
        status:
          $ref: '#/components/schemas/CounterpartyStatus'
        failure:
          allOf:
            - $ref: '#/components/schemas/Reason'
          description: >-
            Why the counterparty was rejected. Present only when `status` is
            `rejected`.
        name:
          type: string
          description: >-
            Single-line display name, read-only and server-composed:
            `businessName` for a `business`, or `firstName` + " " + `lastName`
            for an `individual`. It is the same string an instrument's
            `owner.name` carries. Write the structured fields; read this one.
        entityType:
          allOf:
            - $ref: '#/components/schemas/CounterpartyEntityType'
          description: >-
            Determines which structured name fields apply. Can be absent on
            reads for older counterparties that have not been classified yet.
        firstName:
          type: string
          description: >-
            Given name — present when `entityType` is `individual` and the row
            has structured name fields. Echoed back exactly as supplied.
        lastName:
          type: string
          description: >-
            Family name — present when `entityType` is `individual` and the row
            has structured name fields. Echoed back exactly as supplied.
        businessName:
          type: string
          description: >-
            Registered legal name — present when `entityType` is `business` and
            the row has structured name fields. Echoed back exactly as supplied.
        address:
          allOf:
            - $ref: '#/components/schemas/Address'
          description: >-
            Registered address. Omitted when the counterparty has none, such as
            one created without an address on a project that does not require
            it.
        email:
          type: string
        phone:
          type: string
        taxId:
          type: string
        dateOfBirth:
          type: string
          format: date
        nationality:
          type: string
          description: ISO 3166-1 alpha-2.
        metadata:
          type: object
          additionalProperties:
            type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
      description: >-
        A third party a customer transacts with — an entry in the customer's
        address book. Counterparties will own External Accounts (registered
        payment destinations) in a later slice.
    CounterpartyCreateRequest:
      type: object
      oneOf:
        - $ref: '#/components/schemas/CounterpartyCreateRequestIndividual'
        - $ref: '#/components/schemas/CounterpartyCreateRequestBusiness'
      discriminator:
        propertyName: entityType
        mapping:
          individual: '#/components/schemas/CounterpartyCreateRequestIndividual'
          business: '#/components/schemas/CounterpartyCreateRequestBusiness'
      description: >-
        Create a counterparty. Pick an `entityType`: `business` requires
        `businessName`; `individual` requires both `firstName` and `lastName`.
        The server composes these into the `name` it returns on the response.
        Sending a flat `name` field returns 400.
    CounterpartyCreateRequestBusiness:
      type: object
      required:
        - entityType
        - businessName
        - customerId
      properties:
        entityType:
          type: string
          enum:
            - business
          description: Entity type discriminator.
        businessName:
          type: string
          minLength: 1
          maxLength: 140
          description: Registered legal name of the business. 1..140 chars.
        customerId:
          type: string
          description: Owning customer ID (`cst_` prefix).
        address:
          allOf:
            - $ref: '#/components/schemas/Address'
          description: >-
            Registered address. Required unless your project is configured not
            to require one. When supplied, it is validated in full: non-blank
            line1, city, zipCode and a two-letter ISO country (state required
            for US).
        email:
          type: string
          description: Contact email address.
        phone:
          type: string
          description: Phone in E.164 format.
        taxId:
          type: string
          description: >-
            Tax ID (CPF, CNPJ, SSN, etc.). Required for some external-account
            types.
        nationality:
          type: string
          description: ISO 3166-1 alpha-2.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
      description: >-
        Business counterparty create arm. The server composes the response
        `name` from `businessName`.
      title: business
      example:
        entityType: business
        customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
        businessName: Acme Inc.
        address:
          line1: 6 Acme Way
          city: Bentonville
          state: AR
          country: US
          zipCode: '72712'
        email: ap@acme.example
        taxId: 81-1234567
    CounterpartyCreateRequestIndividual:
      type: object
      required:
        - entityType
        - firstName
        - lastName
        - customerId
      properties:
        entityType:
          type: string
          enum:
            - individual
          description: Entity type discriminator.
        firstName:
          type: string
          minLength: 1
          maxLength: 140
          description: >-
            Given name, as it appears on the counterparty's identity document.
            1..140 chars.
        lastName:
          type: string
          minLength: 1
          maxLength: 140
          description: >-
            Family name, as it appears on the counterparty's identity document.
            1..140 chars.
        dateOfBirth:
          type: string
          format: date
          description: Date of birth (YYYY-MM-DD).
        customerId:
          type: string
          description: Owning customer ID (`cst_` prefix).
        address:
          allOf:
            - $ref: '#/components/schemas/Address'
          description: >-
            Registered address. Required unless your project is configured not
            to require one. When supplied, it is validated in full: non-blank
            line1, city, zipCode and a two-letter ISO country (state required
            for US).
        email:
          type: string
          description: Contact email address.
        phone:
          type: string
          description: Phone in E.164 format.
        taxId:
          type: string
          description: >-
            Tax ID (CPF, CNPJ, SSN, etc.). Required for some external-account
            types.
        nationality:
          type: string
          description: ISO 3166-1 alpha-2.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
      description: >-
        Individual counterparty create arm. The server composes the response
        `name` as `firstName` + " " + `lastName`.
      title: individual
      example:
        entityType: individual
        customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
        firstName: Alice
        lastName: Smith
        address:
          line1: 500 Market Street
          city: San Francisco
          state: CA
          country: US
          zipCode: '94105'
        email: alice@example.com
        phone: '+14155550100'
        nationality: US
    CounterpartyEntityType:
      type: string
      enum:
        - individual
        - business
    CounterpartyHasActiveExternalAccountsErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CounterpartyHasActiveExternalAccounts
        code:
          type: number
          enum:
            - 10174
        msg:
          type: string
          enum:
            - >-
              a counterparty with active or pending external accounts cannot be
              deleted; delete them first
        cause:
          type: string
    CounterpartyList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/Counterparty'
          description: The page of results.
    CounterpartyNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CounterpartyNotFound
        code:
          type: number
          enum:
            - 10173
        msg:
          type: string
          enum:
            - counterparty not found
        cause:
          type: string
    CounterpartyStatus:
      type: string
      enum:
        - active
        - rejected
        - deleted
      description: >-
        Lifecycle of a counterparty. `rejected` is set when compliance screening
        finds a prohibited country, on create or on a later update. A
        counterparty rejected only for `countryProhibited` returns to `active`
        when an update moves its address to an allowed country; `deleted` marks
        a soft-deleted record that remains readable by id.
    CounterpartyUnresolvedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CounterpartyUnresolved
        code:
          type: number
          enum:
            - 10271
        msg:
          type: string
          enum:
            - destination external account is required
        cause:
          type: string
    CounterpartyUpdateRequest:
      type: object
      properties:
        firstName:
          type: string
          minLength: 1
          maxLength: 140
          description: Given name. Individual counterparties only. Recomposes `name`.
        lastName:
          type: string
          minLength: 1
          maxLength: 140
          description: Family name. Individual counterparties only. Recomposes `name`.
        businessName:
          type: string
          minLength: 1
          maxLength: 140
          description: >-
            Registered legal name. Business counterparties only. Recomposes
            `name`.
        address:
          allOf:
            - $ref: '#/components/schemas/Address'
          description: The counterparty's postal address.
        email:
          type: string
          description: Contact email address.
        phone:
          type: string
          description: Phone in E.164 format.
        taxId:
          type: string
          description: >-
            Tax ID (CPF, CNPJ, SSN, etc.). Required for some external-account
            types.
        dateOfBirth:
          type: string
          format: date
          description: Date of birth (YYYY-MM-DD).
        nationality:
          type: string
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
      description: >-
        Partial update — every field optional; omitted fields are unchanged.
        Unknown fields are rejected with 400 (strict decode) by the handler.
        `entityType` cannot be changed (create a new counterparty instead) and
        `name` cannot be written (it is server-composed). Send only the name
        fields matching the counterparty's existing `entityType`: `businessName`
        on an `individual`, or `firstName`/`lastName` on a `business`, is
        rejected with 422 `Validation`.
    CountryInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CountryInvalid
        code:
          type: number
          enum:
            - 10018
        msg:
          type: string
          enum:
            - countryCode must be an ISO 3166-1 alpha-2 code
        cause:
          type: string
    CreateCashInRequest:
      type: object
      required:
        - customerId
        - source
        - destination
        - cash
      properties:
        customerId:
          type: string
          description: The customer depositing cash (`cst_` prefix).
        source:
          allOf:
            - $ref: '#/components/schemas/CashInSource'
          description: Where the customer will deposit cash.
        destination:
          allOf:
            - $ref: '#/components/schemas/CashInDestination'
          description: Crypto instrument to deliver to (walletCrypto or walletExternal).
        cash:
          allOf:
            - $ref: '#/components/schemas/CashInfo'
          description: The cash amount to deposit.
        sponsorGas:
          type: boolean
          description: >-
            When `true`, OMS absorbs the on-chain gas cost for the destination
            delivery. Only `true` is currently supported.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
      description: >-
        Request body for creating a cash-in. Names the customer, the cash source
        location, and the crypto destination.
      example:
        customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
        source:
          asset: usd
          indicatedAmount: '200.00'
        destination:
          asset: usdc
          network: polygon
          wallet:
            id: wlt_5h4jzzpr9xre3bamd9ca7qyghn
        cash:
          locationId: loc_01H9Xd
          locationReference: R1JFRU5ET1QtMjQzNA==
        sponsorGas: true
        metadata:
          orderId: order_12345
    CryptoCustodyInactiveErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CryptoCustodyInactive
        code:
          type: number
          enum:
            - 10374
        msg:
          type: string
          enum:
            - customer does not have an active cryptoCustody endorsement
        cause:
          type: string
    CryptoNetwork:
      type: string
      enum:
        - ethereum
        - polygon
        - base
        - solana
        - tron
        - bnb
      description: >-
        Blockchain network identifier: `ethereum`, `polygon`, `base`, `solana`,
        `tron`, `bnb`. Pass the lowercase name — numeric EVM chain IDs (`1`,
        `137`, `8453`, `56`) are not accepted, and responses always return the
        name. This is the wire vocabulary, not an availability list. A
        `walletExternal` can be registered on `tron` (networkFamily `tron`)
        where the project's provider serves it. Availability is per provider
        rather than per project, so a network your project holds through one
        provider can still be refused for a customer on another. `GET /networks`
        lists the networks your project can route, as the union across every
        provider it holds.
    CryptoOutNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CryptoOutNotSupported
        code:
          type: number
          enum:
            - 10272
        msg:
          type: string
          enum:
            - >-
              walletFiat transactions to a crypto destination are not supported
              in this release
        cause:
          type: string
    CryptoReturnDestination:
      type: object
      required:
        - type
        - network
        - id
      properties:
        type:
          $ref: '#/components/schemas/CryptoReturnDestinationType'
        network:
          allOf:
            - $ref: '#/components/schemas/CryptoNetwork'
          description: >-
            Return network. Must equal the DA's expectedSourceNetwork for the
            return to be usable.
        id:
          type: string
          description: >-
            `walletCrypto`: OMS wallet ID (`acc_` or `wlt_` prefix).
            `walletExternal`: registered External Account ID (`ext_` prefix).
      description: >-
        A crypto return destination — where inbound crypto is sent when its
        outbound leg can't be completed. Pick a `type`: an OMS wallet
        (`walletCrypto`, which must be multi-asset) or a registered external
        wallet (`walletExternal`). Used by the Deposit-Address
        `returnDestination`; the fiat analog on Virtual Accounts is their
        `returnDestination`. `network` must equal the Deposit Address's
        `expectedSourceNetwork` and, for a `walletExternal` target, be one the
        Deposit Address's provider serves for that wallet's network; a
        `walletCrypto` target that is not multi-asset is rejected with 422
        `ReturnDestinationMustBeMultiAsset`.
    CryptoReturnDestinationType:
      type: string
      enum:
        - walletCrypto
        - walletExternal
      description: >-
        The type of a crypto return destination: an OMS wallet (`walletCrypto`)
        or a registered external wallet (`walletExternal`).
    CryptoToCryptoExternalAddressUnsupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CryptoToCryptoExternalAddressUnsupported
        code:
          type: number
          enum:
            - 10311
        msg:
          type: string
          enum:
            - >-
              this route does not deliver crypto-to-crypto transfers to a raw
              destination.details.blockchainAddress; use destination.type
              walletCrypto with destination.details.id for a wallet registered
              in OMS
        cause:
          type: string
    CurrencyNotEnforceableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CurrencyNotEnforceable
        code:
          type: number
          enum:
            - 10011
        msg:
          type: string
          enum:
            - no transfer limit configured for this currency
        cause:
          type: string
    CustodialWalletUnavailableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CustodialWalletUnavailable
        code:
          type: number
          enum:
            - 10304
        msg:
          type: string
          enum:
            - >-
              no usable custodial wallet is available for the requested asset
              and network
        cause:
          type: string
    CustodianInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CustodianInvalid
        code:
          type: number
          enum:
            - 10052
        msg:
          type: string
          enum:
            - custodian is not a recognised value
        cause:
          type: string
    CustodianRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CustodianRequired
        code:
          type: number
          enum:
            - 10361
        msg:
          type: string
          enum:
            - custodian is required for this project
        cause:
          type: string
    CustomerBalanceAggregate:
      type: object
      required:
        - data
      properties:
        data:
          type: object
          properties:
            customerId:
              allOf:
                - $ref: '#/components/schemas/typeId'
              description: 'Public OMS customer ID, format `cst_<typeID>`.'
            estimatedBalanceValue:
              allOf:
                - $ref: '#/components/schemas/fixedDecimalString'
              description: >-
                Estimated total balance value across all customer
                wallets/assets, in the currency requested via the
                `estimatedBalanceCurrencyCode` query param. Defaults to USD when
                the query param is omitted. Decimal string.
            estimatedBalanceCurrencyCode:
              type: string
              description: Currency code used for `estimatedBalanceValue`.
            updatedAt:
              type: string
              format: date-time
              description: >-
                Most recent provider balance timestamp included in the
                aggregate. Omitted when no provider balance timestamps were
                available to aggregate.
            totalBalance:
              allOf:
                - $ref: '#/components/schemas/BpnCustomerTotalBalance'
              description: >-
                USD rollup of the customer's balances — fiat, crypto, and the
                total. Returned by `GET /customers/{id}/balance` only when the
                aggregate is read in USD, so it is omitted whenever
                `estimatedBalanceCurrencyCode` names another currency. Also
                omitted as a whole if either component cannot be read: a partial
                total is never returned. `estimatedBalanceValue` above is
                unaffected and is still returned in the requested currency.
          required:
            - customerId
            - estimatedBalanceValue
            - estimatedBalanceCurrencyCode
      description: >-
        A customer's estimated total balance, aggregated across all of their
        wallets and assets.
    CustomerNotEnrolledWithVendorErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CustomerNotEnrolledWithVendor
        code:
          type: number
          enum:
            - 10306
        msg:
          type: string
          enum:
            - >-
              customer is not enrolled with the provider configured for this
              project
        cause:
          type: string
    CustomerNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CustomerNotFound
        code:
          type: number
          enum:
            - 10001
        msg:
          type: string
          enum:
            - customer not found
        cause:
          type: string
    CustomerRef:
      type: object
      required:
        - id
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: The customer id (`cst_` prefix).
      description: >-
        The customer, referenced by id; its name and details are on the customer
        resource.
    CustomerRejectedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CustomerRejected
        code:
          type: number
          enum:
            - 10079
        msg:
          type: string
          enum:
            - customer rejected by provider
        cause:
          type: string
    CustomerRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - CustomerRequired
        code:
          type: number
          enum:
            - 10125
        msg:
          type: string
          enum:
            - customer_id is required
        cause:
          type: string
    CustomerSummary:
      type: object
      required:
        - id
        - name
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: The OMS customer id (`cst_` prefix).
        name:
          type: string
          description: Customer display name.
      description: >-
        Display-safe summary of a customer — ID plus display name only. Enables
        one-request list rendering: a page of rows needs no per-row detail
        queries. Always the record's owning customer.
    BpnCustomerTotalBalance:
      type: object
      properties:
        totalUsd:
          allOf:
            - $ref: '#/components/schemas/signedFixedDecimalString'
          description: >-
            `fiatUsd + cryptoUsd`, formatted to 2 decimal places, sign preserved
            (e.g. `"25.00"`, `"-15.50"`).
        fiatUsd:
          allOf:
            - $ref: '#/components/schemas/signedFixedDecimalString'
          description: >-
            Signed sum of the customer's USD fiat wallet balances as last
            reported by the bank holding them ("Erebor Bank, N.A." today; see
            `provider` on the wallet), formatted to 2 decimal places. Can be
            negative. `"0.00"` for a project without that bank enabled.
        cryptoUsd:
          allOf:
            - $ref: '#/components/schemas/signedFixedDecimalString'
          description: >-
            Signed sum of the customer's custodial crypto wallet balances,
            valued at the custodian's own per-asset USD estimate and formatted
            to 2 decimal places. `noncustodial` wallets are not valued here.
            `"0.00"` for a customer with no custodial crypto account.
      description: >-
        USD rollup of a customer's balances, returned only on `GET
        /customers/{id}/balance`. `totalUsd` is exactly `fiatUsd + cryptoUsd`,
        and all three are signed decimal strings formatted to 2 decimal places.
        A fiat balance can be negative — an ACH clawback can overdraw the
        deposit account — so the total can be negative too; render the sign
        verbatim and never clamp to zero. `cryptoUsd` covers custodial wallets
        only, so a customer with no custodial crypto account reads `"0.00"`
        there rather than getting an error.
    CustomerWallet:
      type: object
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Unique identifier.
        customerId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The customer that owns the wallet. `cst_` prefix. Never set on `GET
            /customers/{id}/wallets`, where the customer is the path segment.
        walletAddress:
          type: string
          description: On-chain wallet address.
        currencySymbol:
          type: string
          description: Display symbol of the currency.
        currencyName:
          type: string
          description: Display name of the currency.
        assetId:
          type: string
          description: Asset identifier.
        chain:
          type: string
          description: Chain the wallet lives on.
        blockchainAsset:
          $ref: '#/components/schemas/BlockchainAsset'
        balance:
          allOf:
            - $ref: '#/components/schemas/signedFixedDecimalString'
          description: >-
            Current balance as a fixed-point decimal string at the asset's own
            scale, trailing zeros preserved (e.g. `"5.00"` for a two-decimal
            asset, `"5.000000"` for USDC). A leading minus is part of the
            contract — render the sign as-is rather than clamping to zero.
            Absent when no balance has been recorded for the wallet yet.
        createdAt:
          type: string
          format: date-time
          description: When the resource was created.
      description: >-
        A single customer wallet: one asset on one chain, with its balance and
        address.
    CustomerWalletList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/CustomerWallet'
          description: The page of results.
      description: 'Response envelope for `GET /customers/{id}/wallets`.'
    DANotRecoverableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DANotRecoverable
        code:
          type: number
          enum:
            - 10193
        msg:
          type: string
          enum:
            - deposit address status does not allow a destination re-point
        cause:
          type: string
    DailyCountExceededErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DailyCountExceeded
        code:
          type: number
          enum:
            - 10224
        msg:
          type: string
          enum:
            - daily transaction count limit reached
        cause:
          type: string
    DailyLimitExceededErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DailyLimitExceeded
        code:
          type: number
          enum:
            - 10010
        msg:
          type: string
          enum:
            - daily limit exceeded
        cause:
          type: string
    DateOfBirthInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DateOfBirthInvalid
        code:
          type: number
          enum:
            - 10172
        msg:
          type: string
          enum:
            - dateOfBirth is invalid
        cause:
          type: string
    DeleteInProgressErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DeleteInProgress
        code:
          type: number
          enum:
            - 10208
        msg:
          type: string
          enum:
            - a delete is already in progress
        cause:
          type: string
    DeleteNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DeleteNotSupported
        code:
          type: number
          enum:
            - 10204
        msg:
          type: string
          enum:
            - delete is not supported for this resource
        cause:
          type: string
    DepositAddress:
      type: object
      required:
        - customer
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Deposit Address ID (`da_` prefix).
        customer:
          allOf:
            - $ref: '#/components/schemas/CustomerRef'
          description: The customer that owns this record.
        status:
          allOf:
            - $ref: '#/components/schemas/DepositAddressStatus'
          description: Current lifecycle status of the deposit address.
        depositInstructions:
          allOf:
            - $ref: '#/components/schemas/DepositAddressDepositInstructions'
          description: >-
            What a sender deposits and where. The asset and network are there
            from creation; the on-chain `address` is left out until the provider
            issues it. A provider that issues it during the create call returns
            it in the create response; otherwise the deposit address turns
            `active` once it is issued, and reading it returns the address from
            then on.
        destination:
          allOf:
            - $ref: '#/components/schemas/DepositAddressDestination'
          description: >-
            The account deposits are paid out to. A bank account carries no rail
            and no ACH options; they are on `payout`.
        payout:
          allOf:
            - $ref: '#/components/schemas/Payout'
          description: >-
            How a deposit is paid out to a bank or `walletFiat` `destination`:
            the rail and, on `ach` and `achSameDay`, the ACH options. Left out
            for a crypto destination.
        payoutOrigin:
          allOf:
            - $ref: '#/components/schemas/PayoutOrigin'
          description: >-
            Whose name a payout from this Deposit Address goes out under: the
            holder stored when it was created, or its provider's for an address
            created before holders were stored. Left out for a `walletFiat`
            destination or none.
        returnDestination:
          allOf:
            - $ref: '#/components/schemas/DepositAddressReturnDestination'
          description: >-
            Where inbound crypto is sent back when its payout cannot be
            completed. Present only when you set one.
        returnDestinationTypes:
          type: array
          items:
            $ref: '#/components/schemas/CryptoReturnDestinationType'
          description: >-
            The return destination types this Deposit Address accepts, derived
            by OMS from its issuing `provider` and its
            `depositInstructions.network` with the same rules a
            `returnDestination` is validated against on create and PATCH.
            `walletExternal` is listed when the provider serves this network for
            the network's External Account family; `walletCrypto` is listed when
            the provider can return to an OMS wallet. Read-only. Left out when
            no return destination can be configured on this Deposit Address and
            when OMS could not determine it; the create and PATCH validation
            stays authoritative.
        failure:
          allOf:
            - $ref: '#/components/schemas/Reason'
          description: >-
            Why the deposit address failed. Present only when `status` is
            `failed`.
        hold:
          allOf:
            - $ref: '#/components/schemas/Hold'
          description: >-
            What you must do for a deposit address in `inactiveActionRequired`:
            set a new `destination`. Present only in that status.
        sponsorGas:
          type: boolean
          description: >-
            Whether OMS absorbs the on-chain gas cost for the destination
            delivery. Present only when true, the only value a create or update
            request accepts.
        provider:
          type: string
          description: >-
            The institution that issues and custodies this Deposit Address —
            currently "Erebor Bank, N.A." or "Coinme Inc.". Assigned by OMS from
            your project's configuration. It determines which asset and network
            pairs you can create a deposit address for: an unsupported pair is
            rejected at create time with 422
            `depositAddressAssetNetworkNotSupported`, which names the same
            provider in `details.provider`. Read it when you need to tell an end
            user or a support ticket which institution is holding the funds. It
            is *not* the name a payout is sent under, which is the payout
            transfer's `originatorName` and can name a different company. New
            providers may be added, so treat the string as free-form rather than
            a fixed set. Read-only; omitted when the issuing institution is not
            recognised.
        requiresCounterpartyWalletRegistration:
          type: boolean
          description: >-
            Present, and `true`, when a sender's wallet must be registered as a
            `walletExternal` External Account under this Deposit Address's
            customer before it deposits. Derived from the issuing `provider`,
            never supplied by you: Deposit Addresses issued by Erebor Bank, N.A.
            accept a deposit only from a registered counterparty wallet, while
            those issued by Coinme Inc. accept a deposit from any crypto address
            and leave the field out. When `true`, a deposit from an unregistered
            address still arrives, but its transaction parks on a
            `senderAttribution` hold until you register a matching External
            Account (the hold's `matchableExternalAccountCriteria` says what
            will match) and fails at the hold's `deadline` if you never do — so
            capture the sender's address up front. Read it per Deposit Address
            rather than caching it per project. Read-only. Also left out when
            OMS cannot identify the issuing provider.
        label:
          type: string
          description: Partner display label.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: Free-form key-value pairs supplied at creation or update.
        createdAt:
          type: string
          format: date-time
          description: When the deposit address was created.
        updatedAt:
          type: string
          format: date-time
          description: When the deposit address was last updated.
      description: >-
        A reusable crypto deposit configuration. Senders deposit the expected
        asset/network to the assigned on-chain address; OMS converts and
        delivers the funds to the configured bank destination automatically,
        creating a transaction per inbound deposit.


        A Deposit Address is permanent: there is no delete operation for a
        Deposit Address. The on-chain address is published to senders and can
        receive a deposit at any time, so removing the record would strand any
        funds that arrive afterwards with nothing to route them to. The terminal
        `closed` status is not a partner call either: it is reached through the
        provider's own lifecycle or an operator action, and a `closed` Deposit
        Address is still not deleted — it stays retrievable by id. To stop using
        one, stop handing its address to senders. PATCH `destination` changes
        where deposits that arrive afterwards are delivered; a deposit that has
        already arrived keeps the destination that was in effect when it
        arrived. Contrast a Virtual Account, which does support `DELETE` because
        its close is a real provider-side account closure.
    DepositAddressCreateRequest:
      type: object
      required:
        - customerId
        - expectedSourceAsset
        - expectedSourceNetwork
        - destination
      properties:
        customerId:
          type: string
          description: Owning customer ID (`cst_` prefix).
        expectedSourceAsset:
          type: string
          description: >-
            Asset of the inbound crypto the DA expects. "usdc" | "usdt"
            (lowercase).
        expectedSourceNetwork:
          allOf:
            - $ref: '#/components/schemas/CryptoNetwork'
          description: >-
            Network senders will use for the inbound deposit. Availability is
            per-provider rather than one global list: a network outside the
            `CryptoNetwork` vocabulary, or one the provider that issues your
            Deposit Address does not serve, is rejected with 422
            `ExpectedSourceNetworkUnsupported`. `GET /networks` reports the
            networks your project can currently receive on.
        destination:
          allOf:
            - $ref: '#/components/schemas/DepositAddressDestinationRequest'
          description: >-
            Where the Deposit Address delivers converted funds. Pick a `type`: a
            bank account (`bankUs`, on `ach` / `achSameDay` / `wire` / `rtp`;
            `bankIban`; `bankCanada`) or a fiat balance wallet (`walletFiat`)
            for crypto-to-fiat, or a registered external crypto wallet
            (`walletExternal`) for crypto-to-crypto. A `walletExternal` network
            must be one the Deposit Address's own provider serves — per
            provider, not one global list — or it is rejected with 422
            `DestinationNetworkUnsupported`. `walletFiat` credits the customer's
            own fiat wallet by internal book transfer, so the resolved
            destination instrument reads `network: bookTransfer`. `walletCrypto`
            is rejected with 422 `DestinationWalletCryptoNotSupported`. The side
            `details` (asset and network) are validated against the resolved
            External Account or wallet.
        returnDestination:
          allOf:
            - $ref: '#/components/schemas/CryptoReturnDestination'
          description: >-
            Registered crypto return destination, for operations-triggered
            returns of stranded inbound deposits.
        sponsorGas:
          type: boolean
          description: >-
            When `true`, OMS absorbs the on-chain gas cost for the destination
            delivery. Only `true` is currently supported. Ignored for non-crypto
            destinations (no on-chain leg).
          default: true
        label:
          type: string
          description: Partner display label.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
      description: >-
        Create a Deposit Address: the expected inbound asset/network pair plus
        the bank destination that receives the converted funds.
      example:
        customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
        expectedSourceAsset: usdc
        expectedSourceNetwork: ethereum
        destination:
          type: bankUs
          details:
            id: ext_fky491gakzj0dd46qb6whsr2vq
            asset: usd
            network: ach
        sponsorGas: true
        label: Alice deposit address
    DepositAddressDepositInstructions:
      type: object
      required:
        - asset
        - network
      properties:
        asset:
          type: string
          description: >-
            The asset the deposit address accepts, the `expectedSourceAsset` it
            was created with.
        network:
          allOf:
            - $ref: '#/components/schemas/CryptoNetwork'
          description: >-
            The network the deposit address accepts, the `expectedSourceNetwork`
            it was created with.
        address:
          type: string
          description: >-
            The on-chain address to send the inbound deposit to. Its provenance
            differs by provider: a provider that PROVISIONS assigns a fresh
            inlet address it owns and dedicates to this deposit address, while a
            provider that BINDS returns the address of a custodial wallet the
            customer already holds. Either way this is the address senders
            deposit to. Left out until the provider issues it, which the deposit
            address announces by turning `active`.
      description: >-
        What a sender deposits and where: the asset and network the deposit
        address accepts and, once issued, the on-chain address.
    DepositAddressDestination:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletCryptoInstrument'
        - $ref: '#/components/schemas/WalletExternalInstrument'
        - $ref: '#/components/schemas/WalletFiatInstrument'
        - $ref: '#/components/schemas/BankUsAccount'
        - $ref: '#/components/schemas/BankIbanAccount'
        - $ref: '#/components/schemas/BankCanadaAccount'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletCryptoInstrument'
          walletExternal: '#/components/schemas/WalletExternalInstrument'
          walletFiat: '#/components/schemas/WalletFiatInstrument'
          bankUs: '#/components/schemas/BankUsAccount'
          bankIban: '#/components/schemas/BankIbanAccount'
          bankCanada: '#/components/schemas/BankCanadaAccount'
      description: 'The destination of a Deposit Address: one instrument per account type.'
    DepositAddressDestinationRequest:
      type: object
      oneOf:
        - $ref: '#/components/schemas/BankUsDepositAddressSideRequest'
        - $ref: '#/components/schemas/BankIbanSideRequest'
        - $ref: '#/components/schemas/BankCanadaSideRequest'
        - $ref: '#/components/schemas/WalletCryptoSideRequest'
        - $ref: '#/components/schemas/WalletExternalRegisteredSideRequest'
        - $ref: '#/components/schemas/WalletFiatDestinationRequest'
      discriminator:
        propertyName: type
        mapping:
          bankUs: '#/components/schemas/BankUsDepositAddressSideRequest'
          bankIban: '#/components/schemas/BankIbanSideRequest'
          bankCanada: '#/components/schemas/BankCanadaSideRequest'
          walletCrypto: '#/components/schemas/WalletCryptoSideRequest'
          walletExternal: '#/components/schemas/WalletExternalRegisteredSideRequest'
          walletFiat: '#/components/schemas/WalletFiatDestinationRequest'
      description: >-
        Where a Deposit Address delivers converted funds. Bank destinations
        (`bankUs`, `bankIban`, `bankCanada`) and the fiat balance destination
        (`walletFiat`) auto-convert inbound crypto to fiat
        (`cryptoToFiatAccount`); the crypto wallet destination `walletExternal`
        delivers crypto onward to a registered wallet (`cryptoToCrypto`).
        `walletCrypto` is declared here but not currently accepted — it is
        rejected with 422 `DestinationWalletCryptoNotSupported`, so use
        `walletExternal` for an externally held wallet. There is no `amount` —
        the deposited value determines what is delivered, and an `amount` on a
        reused side arm is rejected. `bankUs` here additionally accepts the
        `rtp` rail, which Virtual-Account bank destinations do not. A
        `walletExternal` destination must be on a network the Deposit Address's
        own provider serves, and that set is per provider rather than one global
        list, so the same wallet network can be accepted on one Deposit Address
        and rejected with 422 `DestinationNetworkUnsupported` on another.
        `walletFiat` credits the customer's own fiat wallet by internal book
        transfer and needs the book-transfer outgoing rail enabled for your
        project (403 `DestinationRailNotAllowed`). The side `details` (asset and
        network) are validated against the resolved External Account or wallet.
    DepositAddressInstrument:
      type: object
      required:
        - type
        - asset
        - network
      properties:
        type:
          type: string
          enum:
            - depositAddress
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: The deposit address (`da_`).
        asset:
          type: string
          description: Lowercase asset.
        network:
          type: string
          description: Lowercase blockchain.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/DepositAddressInstrumentDetails'
      description: A deposit address.
      title: Deposit address
    DepositAddressInstrumentDetails:
      type: object
      properties:
        address:
          type: string
          description: On-chain address.
      description: Deposit address details.
    DepositAddressList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/DepositAddress'
          description: The page of results.
      description: Paginated list of DepositAddress resources.
    DepositAddressNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DepositAddressNotFound
        code:
          type: number
          enum:
            - 10195
        msg:
          type: string
          enum:
            - deposit address not found
        cause:
          type: string
    DepositAddressReturnDestination:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletCryptoInstrument'
        - $ref: '#/components/schemas/WalletExternalInstrument'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletCryptoInstrument'
          walletExternal: '#/components/schemas/WalletExternalInstrument'
      description: >-
        The return destination of a Deposit Address: an OMS wallet or a
        registered external wallet.
    DepositAddressStatus:
      type: string
      enum:
        - pending
        - active
        - frozen
        - closed
        - failed
        - inactiveActionRequired
      description: >-
        Lifecycle of a Deposit Address. pending: awaiting on-chain address
        assignment. active: accepting deposits. frozen: deposits held by
        compliance. inactiveActionRequired: destination unusable, re-point
        `destination` to recover. closed: permanently disabled. failed:
        provisioning failed.
    DepositAddressUpdateRequest:
      type: object
      properties:
        destination:
          allOf:
            - $ref: '#/components/schemas/DepositAddressDestinationRequest'
          description: >-
            Re-point the DA destination (bank-type External Account by EA id, a
            registered walletExternal crypto wallet, or a walletFiat fiat
            wallet). Re-validated exactly like create; walletCrypto is NOT
            currently supported — 422 destinationWalletCryptoNotSupported.
            Switching between destination kinds (bank / cryptoWallet /
            walletFiat) involving walletFiat is rejected with 422
            destinationTypeSwitchNotSupported.
        returnDestination:
          allOf:
            - $ref: '#/components/schemas/CryptoReturnDestination'
          description: >-
            Re-point the registered crypto return destination. Send explicit
            `null` to clear.
        sponsorGas:
          type: boolean
          description: >-
            When `true`, OMS absorbs the on-chain gas cost for the destination
            delivery. Only `true` is currently supported; accepted for
            forward-compatibility.
          default: true
        label:
          type: string
          description: Partner display label.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
      description: >-
        Partial update payload for a Deposit Address. The patchable fields are
        `destination` (re-point to a different bank-type External Account),
        `returnDestination`, `label`, and `metadata`. Any additional key in the
        JSON body is rejected with 400 by the handler (strict whitelist).


        Re-pointing `destination` to a healthy bank External Account recovers a
        DA from `inactiveActionRequired` back to `active`; a re-point on an
        already `active` DA updates the target without a status transition.
    DestinationAssetRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationAssetRequired
        code:
          type: number
          enum:
            - 10128
        msg:
          type: string
          enum:
            - destination.asset is required
        cause:
          type: string
    DestinationAssetUnsupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationAssetUnsupported
        code:
          type: number
          enum:
            - 10182
        msg:
          type: string
          enum:
            - >-
              destination.details.asset is not a fiat asset the resolved bank
              flavour settles
        cause:
          type: string
    DestinationCustodian:
      type: string
      enum:
        - ANCHORAGE_SG
        - ANCHORAGE_US
        - AQUANOW_CA
        - B2C2_UK
        - B2C2_US
        - BITGO_SG
        - BITGO_US
        - BITSTAMP_US
        - BVNK_US
        - CIRCLE_FR
        - CIRCLE_US
        - CITIBANK_US
        - COINBASE_US
        - COINSMART_CA
        - COPPER_CH
        - COPPER_UK
        - CUMBERLAND_DRW_LLC_US
        - CUMBERLAND_SG
        - EREBOR_BANK_US
        - FALCONX_US
        - FIDELITY_UK
        - FIDELITY_US
        - FIREBLOCKS_APAC
        - FIREBLOCKS_US
        - GALAXY_KY
        - GEMINI_US
        - KRAKEN_BVI
        - KRAKEN_EU_IE
        - KRAKEN_UK
        - KRAKEN_US
        - NUBANK_BR
        - PAXOS_US
        - RAMP_NETWORK_US
        - ROBINHOOD_US
        - WINTERMUTE_GB
        - SELF_HOSTED
        - OTHER
    DestinationExternalAccountAddressMissingErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationExternalAccountAddressMissing
        code:
          type: number
          enum:
            - 10322
        msg:
          type: string
          enum:
            - destination external account has no registered blockchain address
        cause:
          type: string
    DestinationExternalAccountNetworkMismatchErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationExternalAccountNetworkMismatch
        code:
          type: number
          enum:
            - 10323
        msg:
          type: string
          enum:
            - >-
              destination external account is registered on a different network
              family than the requested destination network
        cause:
          type: string
    DestinationExternalAccountNotActiveErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationExternalAccountNotActive
        code:
          type: number
          enum:
            - 10321
        msg:
          type: string
          enum:
            - destination external account is not active
        cause:
          type: string
    DestinationExternalAccountNotWalletExternalErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationExternalAccountNotWalletExternal
        code:
          type: number
          enum:
            - 10320
        msg:
          type: string
          enum:
            - destination external account is not a walletExternal account
        cause:
          type: string
    DestinationExternalAccountVendorMismatchErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationExternalAccountVendorMismatch
        code:
          type: number
          enum:
            - 10325
        msg:
          type: string
          enum:
            - >-
              destination external account was provisioned by a different vendor
              than the route
        cause:
          type: string
    DestinationInvalidReferenceErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationInvalidReference
        code:
          type: number
          enum:
            - 10177
        msg:
          type: string
          enum:
            - invalid destination.details.id
        cause:
          type: string
    DestinationNetworkNotSupportedByProviderErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationNetworkNotSupportedByProvider
        code:
          type: number
          enum:
            - 10324
        msg:
          type: string
          enum:
            - >-
              the requested destination network has no provider chain mapping
              and cannot be delivered to
        cause:
          type: string
    DestinationNetworkRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationNetworkRequired
        code:
          type: number
          enum:
            - 10130
        msg:
          type: string
          enum:
            - destination.network is required
        cause:
          type: string
    DestinationNetworkUnsupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationNetworkUnsupported
        code:
          type: number
          enum:
            - 10183
        msg:
          type: string
          enum:
            - destination external account does not serve the requested network
        cause:
          type: string
    DestinationNotActiveErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationNotActive
        code:
          type: number
          enum:
            - 10180
        msg:
          type: string
          enum:
            - destination external account is not active
        cause:
          type: string
    DestinationNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationNotFound
        code:
          type: number
          enum:
            - 10178
        msg:
          type: string
          enum:
            - destination fiat wallet not found
        cause:
          type: string
    DestinationRailNotAllowedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationRailNotAllowed
        code:
          type: number
          enum:
            - 10184
        msg:
          type: string
          enum:
            - destination rail is not enabled for this project
        cause:
          type: string
    DestinationRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationRequired
        code:
          type: number
          enum:
            - 10176
        msg:
          type: string
          enum:
            - destination.details.id is required
        cause:
          type: string
    DestinationTypeInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationTypeInvalid
        code:
          type: number
          enum:
            - 10175
        msg:
          type: string
          enum:
            - destination type is not a known bank-EA discriminator
        cause:
          type: string
    DestinationTypeMismatchErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationTypeMismatch
        code:
          type: number
          enum:
            - 10181
        msg:
          type: string
          enum:
            - >-
              destination external account flavour does not match
              destination.type
        cause:
          type: string
    DestinationTypeSwitchNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationTypeSwitchNotSupported
        code:
          type: number
          enum:
            - 10253
        msg:
          type: string
          enum:
            - >-
              cannot switch a deposit address between walletFiat and bank/crypto
              destinations
        cause:
          type: string
    DestinationWalletCryptoNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationWalletCryptoNotSupported
        code:
          type: number
          enum:
            - 10185
        msg:
          type: string
          enum:
            - walletCrypto destination is not supported
        cause:
          type: string
    DestinationWalletMismatchErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationWalletMismatch
        code:
          type: number
          enum:
            - 10360
        msg:
          type: string
          enum:
            - >-
              destination wallet cannot receive this cash-in: its asset and
              network are missing or do not match destination.asset and
              destination.network
        cause:
          type: string
    DestinationWrongTypeErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - DestinationWrongType
        code:
          type: number
          enum:
            - 10179
        msg:
          type: string
          enum:
            - destination external account is not a walletExternal account
        cause:
          type: string
    DirectionalFlag:
      type: object
      required:
        - asSource
        - asDestination
      properties:
        asSource:
          type: boolean
        asDestination:
          type: boolean
      description: >-
        Whether a resource can use a network as a transaction source, a
        destination, or both. Both flags are always present; `false` means
        checked-and-no.
    EmailInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - EmailInvalid
        code:
          type: number
          enum:
            - 10169
        msg:
          type: string
          enum:
            - email is invalid
        cause:
          type: string
    EmptyUpdateErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - EmptyUpdate
        code:
          type: number
          enum:
            - 10019
        msg:
          type: string
          enum:
            - at least one field must be provided
        cause:
          type: string
    EntityTypeInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - EntityTypeInvalid
        code:
          type: number
          enum:
            - 10166
        msg:
          type: string
          enum:
            - entityType is invalid
        cause:
          type: string
    EreborConfigMissingErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - EreborConfigMissing
        code:
          type: number
          enum:
            - 10025
        msg:
          type: string
          enum:
            - the provider integration is not configured for this partner
        cause:
          type: string
    EreborCustomerNotMappedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - EreborCustomerNotMapped
        code:
          type: number
          enum:
            - 10026
        msg:
          type: string
          enum:
            - customer is not yet set up with the provider
        cause:
          type: string
    EreborResponseInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - EreborResponseInvalid
        code:
          type: number
          enum:
            - 10028
        msg:
          type: string
          enum:
            - the provider returned an invalid response
        cause:
          type: string
    EreborValidationFailedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - EreborValidationFailed
        code:
          type: number
          enum:
            - 10027
        msg:
          type: string
          enum:
            - the provider rejected the provisioning request
        cause:
          type: string
    ExpectedSourceAssetUnsupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ExpectedSourceAssetUnsupported
        code:
          type: number
          enum:
            - 10188
        msg:
          type: string
          enum:
            - expectedSourceAsset is not a recognised inbound crypto asset
        cause:
          type: string
    ExpectedSourceNetworkUnsupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ExpectedSourceNetworkUnsupported
        code:
          type: number
          enum:
            - 10187
        msg:
          type: string
          enum:
            - expectedSourceNetwork is not a network the vendor currently serves
        cause:
          type: string
    ExpectedSourceRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ExpectedSourceRequired
        code:
          type: number
          enum:
            - 10186
        msg:
          type: string
          enum:
            - expectedSourceAsset or expectedSourceNetwork is empty
        cause:
          type: string
    ExternalAccount:
      type: object
      required:
        - customer
        - details
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: External Account ID (`ext_` prefix).
        type:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountType'
          description: The account type; decides which `details` keys are present.
        customer:
          allOf:
            - $ref: '#/components/schemas/CustomerRef'
          description: >-
            The customer the account is registered for, also when one of their
            counterparties owns it.
        owner:
          allOf:
            - $ref: '#/components/schemas/InstrumentOwner'
          description: >-
            The counterparty that owns the account. Left out when the account is
            the customer's own.
        asset:
          type: string
          description: >-
            `usd` on bank accounts and cards. Left out on wallets, which list
            their assets in `supportedDestinations`.
        supportedDestinations:
          type: array
          items:
            $ref: '#/components/schemas/ExternalAccountSupportedDestination'
          description: >-
            Where this account can be paid, computed per account. A US bank
            account lists the rails it can receive on, narrowed by what your
            project and the platform enable; an account Erebor Bank, N.A.
            provisions reports `ach`, `achSameDay` and `wire`, so a missing
            `rtp` there means unverified, not refused. A wallet lists `usdc` and
            `usdt` on each network its family serves. Left out for IBAN and
            Canadian bank accounts and cards.
        unavailableDestinations:
          type: array
          items:
            $ref: '#/components/schemas/UnavailableBankDestination'
          description: >-
            US bank accounts: rails the project has turned on that this account
            cannot be paid over, each with its reason.
        details:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountDetails'
          description: The account's type-specific values.
        status:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountStatus'
          description: >-
            Current lifecycle status. A transition to `invalid` always fires the
            `externalAccount.statusChanged` webhook.
        failure:
          allOf:
            - $ref: '#/components/schemas/Reason'
          description: >-
            Why the account failed, was rejected or became invalid. Present only
            when `status` is `failed`, `rejected` or `invalid`.
        label:
          type: string
          description: Optional display label.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: Free-form key-value pairs supplied at creation or update.
        createdAt:
          type: string
          format: date-time
          description: When the external account was registered.
        updatedAt:
          type: string
          format: date-time
          description: When the external account was last updated.
      description: >-
        A saved payment destination registered for a customer or one of their
        counterparties. Write-only secrets (full account number, full IBAN) are
        never present on reads, only their last-4 renderings.
    ExternalAccountAlreadyRegisteredDetails:
      type: object
      required:
        - existingAccountId
        - existingAccountStatus
        - matchedOn
      properties:
        existingAccountId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Public id (`ext_…`) of the live account that already holds the key.
        existingAccountStatus:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountStatus'
          description: >-
            Lifecycle status of that account. `failed` and `rejected` never
            appear here — re-registering such an account re-drives it and
            returns `201`.
        matchedOn:
          type: string
          description: >-
            Which uniqueness rule the request collided with:
            `blockchainAddressNetworkFamilyOwner` for `walletExternal` (owner,
            normalised blockchain address and network family), or
            `routingNumberAccountNumberCustomer` for `bankUs` with a custodial
            provider (customer, routing and account number, across every owner).
            Open vocabulary — tolerate a value you do not recognise.
      description: >-
        Machine-readable context for a `409 externalAccountAlreadyRegistered`:
        which account already holds the registration, what state it is in, and
        which uniqueness rule the request collided with.
    ExternalAccountAlreadyRegisteredErrorResponse:
      type: object
      required:
        - error
        - code
      properties:
        error:
          type: string
        code:
          type: string
          enum:
            - externalAccountAlreadyRegistered
        details:
          $ref: '#/components/schemas/ExternalAccountAlreadyRegisteredDetails'
      description: >-
        This owner, or for a `bankUs` account with a custodial provider this
        customer, has already registered this external account. Returned as 409
        `externalAccountAlreadyRegistered`, and on this error `code` carries
        that same string rather than the numeric `code` of the standard error
        envelope; branch on it as a string here.


        `details` names the account that already holds the registration and is
        returned on the `walletExternal` and `bankUs` create paths. It is absent
        when the provider reports the duplicate itself: always on `POST
        /external-accounts/cards`, where card de-duplication spans the card
        provider's whole platform, so the blocking registration is not
        necessarily one of yours and cannot be named; and on `bankUs` when two
        registrations of the same number race.
    ExternalAccountBankCanadaRequest:
      type: object
      required:
        - institutionNumber
        - transitNumber
        - accountNumber
      properties:
        institutionNumber:
          type: string
          description: Three-digit institution number.
        transitNumber:
          type: string
          description: Five-digit transit number.
        accountNumber:
          type: string
          description: >-
            Canadian bank account number (7-12 digits). Write-only; never
            returned (reads expose `accountNumberLast4`).
        bankName:
          type: string
          description: Bank display name.
      description: bankCanada create detail.
    ExternalAccountBankIbanRequest:
      type: object
      required:
        - iban
        - BIC
      properties:
        iban:
          type: string
          description: >-
            IBAN value. Write-only; never returned (reads expose `ibanLast4`).
            Shape `^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$`.
        BIC:
          type: string
          description: SWIFT BIC (8 or 11 chars).
        bankAddress:
          allOf:
            - $ref: '#/components/schemas/Address'
          description: Structured bank postal address (canonical Address).
        countryCode:
          type: string
          description: >-
            ISO 3166-1 alpha-2. Optional - derived from the IBAN's first two
            letters when omitted; validated against any supplied value.
      description: bankIban create detail.
    ExternalAccountBankUsRequest:
      type: object
      required:
        - accountNumber
        - routingNumber
      properties:
        accountNumber:
          type: string
          description: >-
            US bank account number. Write-only; never returned (reads expose
            `accountNumberLast4`).
        routingNumber:
          type: string
          description: Nine-digit ABA routing number.
        accountType:
          allOf:
            - $ref: '#/components/schemas/BankAccountType'
          description: >-
            Optional; defaults to `checking`. Send the account's actual type —
            an ACH entry with the wrong account type can be returned by the
            receiving bank (NACHA return codes R03 / R04), which fails the
            transaction. If you do not know the type, ask the account holder
            rather than relying on the default.
        bankName:
          type: string
          description: Bank display name.
      description: bankUs create detail.
    ExternalAccountCardBillingAddress:
      type: object
      properties:
        firstName:
          type: string
          description: >-
            Ignored. Accepted for compatibility only: the cardholder name is
            always the owning customer's `firstName` and `lastName`.
          deprecated: true
        lastName:
          type: string
          description: >-
            Ignored. Accepted for compatibility only: the cardholder name is
            always the owning customer's `firstName` and `lastName`.
          deprecated: true
        line1:
          type: string
          description: 'Street address, line 1.'
        line2:
          type: string
          description: 'Street address, line 2.'
        city:
          type: string
          description: City.
        state:
          type: string
          description: State / province / region.
        country:
          type: string
          description: ISO 3166-1 alpha-2
        zipCode:
          type: string
          description: ZIP / postal code.
      description: >-
        Card billing address — the address the card issuer has on file for the
        payment instrument, used for issuer AVS / fraud screening. A customer
        may hold cards with differing billing addresses, so it is supplied per
        card by the partner. It is optional: when omitted, the owning customer's
        address is used and the response reports `billingAddressSource =
        customerDefault`.
    ExternalAccountCreateRequest:
      type: object
      required:
        - owner
        - type
      properties:
        owner:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountOwner'
          description: >-
            Who owns this account - `{ kind: customer, customerId }` or `{ kind:
            counterparty, counterpartyId }`. Cards must be customer-owned.
        type:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountCreateType'
          description: >-
            The instrument type. Exactly one matching per-type detail object
            must be supplied.
        label:
          type: string
          description: Optional display label.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
        bankUs:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountBankUsRequest'
          description: Required when `type = bankUs`.
        bankIban:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountBankIbanRequest'
          description: Required when `type = bankIban`.
        bankCanada:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountBankCanadaRequest'
          description: Required when `type = bankCanada`.
        walletExternal:
          allOf:
            - $ref: '#/components/schemas/ExternalAccountWalletExternalRequest'
          description: Required when `type = walletExternal`.
      description: >-
        Create an External Account. Exactly one per-type detail object must be
        supplied, matching `type`; the service validates the correct subset and
        rejects mismatches with 422.
    ExternalAccountCreateType:
      type: string
      enum:
        - bankUs
        - bankIban
        - bankCanada
        - walletExternal
      description: >-
        Instrument type accepted by `POST /external-accounts`. Register cards
        with `POST /external-accounts/cards`.
      x-go-type: ExternalAccountType
    ExternalAccountDetails:
      type: object
      properties:
        bankName:
          type: string
          description: Bank accounts.
        accountNumberLast4:
          type: string
          description: '`bankUs` and `bankCanada`.'
        routingNumber:
          type: string
          description: '`bankUs`.'
        accountType:
          allOf:
            - $ref: '#/components/schemas/BankAccountType'
          description: '`bankUs`.'
        holderName:
          type: string
          description: >-
            Bank accounts: the counterparty's name on a counterparty's account,
            the customer's name on the customer's own. Left out when the
            counterparty has no name or the customer's name cannot be read.
        ibanLast4:
          type: string
          description: '`bankIban`.'
        bic:
          type: string
          description: '`bankIban`.'
        countryCode:
          type: string
          description: '`bankIban`: ISO 3166-1 alpha-2 country of the bank.'
        bankAddress:
          allOf:
            - $ref: '#/components/schemas/Address'
          description: '`bankIban`.'
        institutionNumber:
          type: string
          description: '`bankCanada`.'
        transitNumber:
          type: string
          description: '`bankCanada`.'
        brand:
          allOf:
            - $ref: '#/components/schemas/CardBrand'
          description: '`card`.'
        last4:
          type: string
          description: '`card`.'
        cardType:
          allOf:
            - $ref: '#/components/schemas/CardType'
          description: '`card`.'
        expiryMonth:
          type: integer
          format: int32
          description: '`card`.'
        expiryYear:
          type: integer
          format: int32
          description: '`card`.'
        billingAddressSource:
          allOf:
            - $ref: '#/components/schemas/BillingAddressSource'
          description: '`card`.'
        address:
          type: string
          description: '`walletExternal`: the on-chain address, as submitted.'
        custodian:
          type: string
          description: '`walletExternal`: who custodies the wallet, in lowerCamelCase.'
        otherCustodian:
          type: string
          description: '`walletExternal`: the custodian''s name when `custodian` is `other`.'
        networkFamily:
          allOf:
            - $ref: '#/components/schemas/NetworkFamily'
          description: '`walletExternal`.'
      description: >-
        An external account's type-specific values. The keys present depend on
        `type`, and a value OMS does not hold is left out.
    ExternalAccountEmergencyRevoke:
      type: object
      required:
        - revokedTransactionIds
        - sendsNotRecalledTransactionIds
      properties:
        revokedTransactionIds:
          type: array
          items:
            $ref: '#/components/schemas/typeId'
          description: >-
            Converting sends to this account (a crypto send that swaps to
            another asset, then sends to this account) whose send had not been
            issued yet, and which the revoke stopped. Their funds stay with the
            provider and are held for operations review: nothing is sent to this
            account, and nothing is returned automatically. The transaction
            never completes: it reads `failed`, with the funds held for review.
        sendsNotRecalledTransactionIds:
          type: array
          items:
            $ref: '#/components/schemas/typeId'
          description: >-
            Sends to this account that may already have been issued and may
            still complete. Only crypto to crypto sends by Coinme are covered: a
            converting or same-asset withdrawal or deposit address crypto
            payout, a retry of one, or any other crypto to crypto send by that
            provider to this account (such as a virtual account's crypto
            forward). One is listed while it is pending or processing, or
            recorded as failed after an unclear provider answer that the
            provider may still deliver. An issued send cannot be recalled: it is
            not affected by the revoke. A pending send is listed even if its
            call had not gone out yet, because that cannot be told apart from
            one already on its way; if it had not, it fails when it re-checks
            the account. A converting send whose send was never issued is in
            `revokedTransactionIds` instead.


            One narrow case is in neither list: a same-asset send whose re-check
            of the account passed in the instant before the delete committed,
            and whose transaction did not exist yet when the lists were read,
            can still be issued. The transaction query below finds it only once
            its transaction exists, so repeat the query shortly after the
            revoke.


            Not covered, so never listed: every other send to this account,
            notably any deposit address or virtual account crypto payout by
            Erebor, and any crypto buy delivered to this account. An empty list
            does not mean nothing can still reach the account. To find those,
            list the customer's transactions that are `pending` or `processing`
            (`GET /transactions` with `customerId` and `status`) and check those
            whose `destination` is `walletExternal` with this account's `id`.
      description: >-
        The outcome of `DELETE
        /external-accounts/{externalAccountId}?emergencyRevoke=true`. The
        account is deleted in every case. Both lists name transactions by their
        `txn_` id and are empty when nothing matched.
    ExternalAccountIDRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ExternalAccountIDRequired
        code:
          type: number
          enum:
            - 10212
        msg:
          type: string
          enum:
            - destination.type walletExternal requires destination.details.id
        cause:
          type: string
    ExternalAccountList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/ExternalAccount'
          description: The page of results.
      description: Paginated list of ExternalAccount resources.
    ExternalAccountNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ExternalAccountNotFound
        code:
          type: number
          enum:
            - 10066
        msg:
          type: string
          enum:
            - external account not found
        cause:
          type: string
    ExternalAccountNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ExternalAccountNotSupported
        code:
          type: number
          enum:
            - 10123
        msg:
          type: string
          enum:
            - external account destinations are not yet supported
        cause:
          type: string
    ExternalAccountOwner:
      type: object
      oneOf:
        - $ref: '#/components/schemas/OwnerCustomer'
        - $ref: '#/components/schemas/OwnerCounterparty'
      discriminator:
        propertyName: kind
        mapping:
          customer: '#/components/schemas/OwnerCustomer'
          counterparty: '#/components/schemas/OwnerCounterparty'
      description: Who owns the External Account.
    ExternalAccountRejectedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ExternalAccountRejected
        code:
          type: number
          enum:
            - 10072
        msg:
          type: string
          enum:
            - the provider rejected this external account
        cause:
          type: string
    ExternalAccountStatus:
      type: string
      enum:
        - active
        - pending
        - rejected
        - invalid
        - deleted
        - failed
      description: >-
        `pending`: being validated with the provider. `active`: usable.
        `failed`: the account could not be provisioned — the provider declined
        it, provisioning timed out, or an internal error stopped it (see
        `failure`). `rejected`: failed validation at creation (see `failure`).
        `invalid`: became unusable after activation (see `failure`). `deleted`:
        soft-deleted by the developer.
    ExternalAccountSupportedDestination:
      type: object
      required:
        - asset
      properties:
        asset:
          type: string
          description: 'Lowercase asset, e.g. `usd` or `usdc`.'
        network:
          allOf:
            - $ref: '#/components/schemas/CryptoNetwork'
          description: 'Wallets: the network the asset can be delivered on.'
        rail:
          type: string
          enum:
            - ach
            - achSameDay
            - wire
            - rtp
            - instant
            - intraBank
          description: 'US bank accounts: the rail the account can be paid over.'
        minimumAmount:
          allOf:
            - $ref: '#/components/schemas/decimalString'
          description: >-
            US bank accounts: the minimum transfer amount on this rail. Absent
            when no limit is published for it.
        maximumAmount:
          allOf:
            - $ref: '#/components/schemas/decimalString'
          description: >-
            US bank accounts: the maximum transfer amount on this rail. Absent
            on the same terms as `minimumAmount`.
        default:
          type: boolean
          description: >-
            US bank accounts: true on the rail to pre-select. The client still
            names the rail on every request: OMS never picks one.
        defaultInstantRail:
          allOf:
            - $ref: '#/components/schemas/InstantRail'
          description: 'US bank accounts, instant rail: the instant rail to pre-select.'
        intraBankRail:
          allOf:
            - $ref: '#/components/schemas/IntraBankRail'
          description: 'US bank accounts, intraBank rail: which same-bank rail applies.'
      description: >-
        A destination an external account can be paid to: an (asset, rail) pair
        with its limits for a US bank account, or an (asset, network) pair for a
        wallet.
    ExternalAccountType:
      type: string
      enum:
        - bankUs
        - bankIban
        - bankCanada
        - card
        - walletExternal
      description: >-
        External Account type. `card` accounts are registered with `POST
        /external-accounts/cards`.
    ExternalAccountUpdateRequest:
      type: object
      properties:
        label:
          type: string
          description: Optional display label.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
      description: >-
        Partial update - only `label` and `metadata` are mutable. Financial /
        identity fields are immutable (re-pointing a destination is create-new +
        re-point). Any other JSON key in the body is rejected with 400.
    ExternalAccountWalletExternalRequest:
      type: object
      required:
        - blockchainAddress
        - networkFamily
      properties:
        blockchainAddress:
          type: string
          description: >-
            Blockchain wallet address. For `networkFamily = evm` the address
            must be all-lowercase, all-uppercase, or a valid EIP-55 checksummed
            form; an inconsistent mixed-case address is rejected as a likely
            casing typo, and the zero address is rejected. Solana is validated
            structurally. For `networkFamily = tron` the address must be a
            mainnet Base58Check address (leading `T`, case-sensitive); the zero
            account is rejected.
        networkFamily:
          $ref: '#/components/schemas/NetworkFamily'
        custodian:
          allOf:
            - $ref: '#/components/schemas/DestinationCustodian'
          description: >-
            DestinationCustodian enum value (reused from VA). Required unless
            the project's walletExternal accounts are provisioned by Coinme, in
            which case it is optional.
        otherCustodian:
          type: string
          description: Required iff `custodian = OTHER`; max 100 chars.
      description: >-
        walletExternal create detail. The address is stored as submitted and
        matched exactly; the service normalizes it (EVM lowercased, Solana and
        Tron raw) for the upsert key.
    ExternalDeliveryWalletRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ExternalDeliveryWalletRequired
        code:
          type: number
          enum:
            - 10270
        msg:
          type: string
          enum:
            - an external buy requires an on-chain delivery wallet
        cause:
          type: string
    FeatureNotEnabledErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - FeatureNotEnabled
        code:
          type: number
          enum:
            - 10153
        msg:
          type: string
          enum:
            - cash offramp is not enabled for this partner
        cause:
          type: string
    FeesDeducted:
      type: object
      required:
        - total
        - developer
        - oms
        - gas
      properties:
        total:
          type: string
        developer:
          type: string
          description: >-
            Per-side aggregated developer fee total in this side's asset. Always
            "0" in alpha - alpha invariant, mirrors the gas line.
        oms:
          type: string
        gas:
          type: string
      description: >-
        Per-side breakdown of fees deducted in-line from the transaction.
        End-of-month billable fees will be reported separately in the future
        (planned `feesInvoice` sibling). Denominated in that side's asset.
    FiatReturnDestination:
      type: object
      oneOf:
        - $ref: '#/components/schemas/FiatReturnDestinationBankUs'
        - $ref: '#/components/schemas/FiatReturnDestinationBankIban'
        - $ref: '#/components/schemas/FiatReturnDestinationBankCanada'
        - $ref: '#/components/schemas/FiatReturnDestinationWalletFiat'
      discriminator:
        propertyName: type
        mapping:
          bankUs: '#/components/schemas/FiatReturnDestinationBankUs'
          bankIban: '#/components/schemas/FiatReturnDestinationBankIban'
          bankCanada: '#/components/schemas/FiatReturnDestinationBankCanada'
          walletFiat: '#/components/schemas/FiatReturnDestinationWalletFiat'
      description: >-
        Where inbound fiat is returned when its outbound leg can't be completed.
        Pick a `type`: a bank account (`bankUs` / `bankIban` / `bankCanada`,
        each with a required `network` naming the rail) or a fiat balance wallet
        (`walletFiat` — no network, internal ledger). Shared by the Virtual
        Account `returnDestination` and (later) the return policy's
        `fiat.returnDestinations`. `walletFiat`, and `bankCanada` with a `local`
        network (CAD), are rejected with 422 `RailNotSupported` in v1 — bank
        rails (USD) only.
    FiatReturnDestinationBankCanada:
      type: object
      required:
        - type
        - network
        - id
      properties:
        type:
          type: string
          enum:
            - bankCanada
          description: Type discriminator.
        network:
          type: string
          enum:
            - swift
            - local
          description: USD uses swift; CAD uses local (CAD rejected 422 in v1).
        id:
          type: string
          description: Canadian bank ExternalAccount id (ext_ prefix).
      description: >-
        Registered Canadian bank fiat return destination. USD uses `swift`; CAD
        (`local`) is rejected with 422 in v1 (USD-only).
      title: Canadian bank account
    FiatReturnDestinationBankIban:
      type: object
      required:
        - type
        - network
        - id
      properties:
        type:
          type: string
          enum:
            - bankIban
          description: Type discriminator.
        network:
          type: string
          enum:
            - swift
        id:
          type: string
          description: IBAN ExternalAccount id (ext_ prefix).
      description: Registered IBAN fiat return destination.
      title: IBAN bank account
    FiatReturnDestinationBankUs:
      type: object
      required:
        - type
        - network
        - id
      properties:
        type:
          type: string
          enum:
            - bankUs
          description: Type discriminator.
        network:
          type: string
          enum:
            - ach
            - achSameDay
            - wire
          description: Rail to return on.
        id:
          type: string
          description: US bank ExternalAccount id (ext_ prefix).
      description: Registered US bank fiat return destination.
      title: US bank account
    FiatReturnDestinationWalletFiat:
      type: object
      required:
        - type
        - id
      properties:
        type:
          type: string
          enum:
            - walletFiat
          description: Type discriminator.
        id:
          type: string
          description: >-
            OMS fiat wallet id (wlt_ prefix; a legacy wlt_fiat_ id is also
            accepted). Rejected 422 in v1.
      description: >-
        Fiat balance wallet return destination. Not supported yet: rejected with
        422.
      title: Fiat wallet
    FiatWalletLimitReachedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - FiatWalletLimitReached
        code:
          type: number
          enum:
            - 10329
        msg:
          type: string
          enum:
            - >-
              the customer already holds the maximum number of fiat wallets
              permitted
        cause:
          type: string
    FieldRequirement:
      type: string
      enum:
        - required
        - recommended
        - optional
      description: >-
        How strongly an owner field is required for a given account type /
        provider.
    Hold:
      type: object
      required:
        - code
        - message
      properties:
        code:
          allOf:
            - $ref: '#/components/schemas/HoldCode'
          description: Why the resource is held.
        message:
          type: string
          description: 'A fixed, vendor-neutral sentence for `code`.'
        deadline:
          type: string
          format: date-time
          description: >-
            When the hold times out and the transaction fails. Only on
            `senderAttribution`.
        match:
          allOf:
            - $ref: '#/components/schemas/HoldMatch'
          description: >-
            The sender's address and network to register to release the hold.
            Only on `senderAttribution`.
      description: >-
        What the partner must do for a transaction in `awaitingAction`, or a
        deposit address or a virtual account in `inactiveActionRequired`.
        `message` is a fixed sentence for each `code`.
    HoldCode:
      type: string
      enum:
        - senderAttribution
        - payoutDestinationMissing
      description: >-
        Why a transaction is held in `awaitingAction`, or a deposit address in
        `inactiveActionRequired`.
    HoldMatch:
      type: object
      required:
        - address
        - network
      properties:
        address:
          type: string
          description: The sender's on-chain address.
        network:
          allOf:
            - $ref: '#/components/schemas/NetworkFamily'
          description: The network family of the sender's address.
      description: >-
        The address the partner registers to attribute a held deposit to its
        sender.
    IBANInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - IBANInvalid
        code:
          type: number
          enum:
            - 10043
        msg:
          type: string
          enum:
            - 'iban must match ^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$'
        cause:
          type: string
    IdempotencyKeyReuseErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - IdempotencyKeyReuse
        code:
          type: number
          enum:
            - 10277
        msg:
          type: string
          enum:
            - Idempotency key already used with a different request
        cause:
          type: string
    InstantRail:
      type: string
      enum:
        - rtp
        - fednow
      description: >-
        The rail an `instant` payment rides: `rtp` (RTP over The Clearing House)
        or `fednow`.
    InstitutionNumberInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InstitutionNumberInvalid
        code:
          type: number
          enum:
            - 10045
        msg:
          type: string
          enum:
            - institutionNumber must be exactly 3 digits
        cause:
          type: string
    Instrument:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletCryptoInstrument'
        - $ref: '#/components/schemas/WalletExternalInstrument'
        - $ref: '#/components/schemas/WalletFiatInstrument'
        - $ref: '#/components/schemas/BankUsAccount'
        - $ref: '#/components/schemas/BankIbanAccount'
        - $ref: '#/components/schemas/BankCanadaAccount'
        - $ref: '#/components/schemas/CardInstrument'
        - $ref: '#/components/schemas/CashInstrument'
        - $ref: '#/components/schemas/DepositAddressInstrument'
        - $ref: '#/components/schemas/VirtualAccountInstrument'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletCryptoInstrument'
          walletExternal: '#/components/schemas/WalletExternalInstrument'
          walletFiat: '#/components/schemas/WalletFiatInstrument'
          bankUs: '#/components/schemas/BankUsAccount'
          bankIban: '#/components/schemas/BankIbanAccount'
          bankCanada: '#/components/schemas/BankCanadaAccount'
          card: '#/components/schemas/CardInstrument'
          cash: '#/components/schemas/CashInstrument'
          depositAddress: '#/components/schemas/DepositAddressInstrument'
          virtualAccount: '#/components/schemas/VirtualAccountInstrument'
      description: >-
        A transaction's source or a transfer's end: one instrument per account
        type. A bank account carries no rail and no ACH options; they are on the
        transfer.
    InstrumentOwner:
      type: object
      required:
        - kind
        - id
      properties:
        kind:
          type: string
          enum:
            - counterparty
            - customer
          description: '`counterparty`, or `customer` for another customer''s account.'
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: The counterparty (`ctp_`) or customer (`cst_`).
        name:
          type: string
          description: >-
            The counterparty's name. A customer's name is on the customer
            resource.
      description: Who owns an account that is not the resource's customer's.
    InsufficientBalanceErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InsufficientBalance
        code:
          type: number
          enum:
            - 10249
        msg:
          type: string
          enum:
            - available balance is less than the requested amount
        cause:
          type: string
    InsufficientFundsErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InsufficientFunds
        code:
          type: number
          enum:
            - 10084
        msg:
          type: string
          enum:
            - insufficient funds
        cause:
          type: string
    InternalErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - Internal
        code:
          type: number
          enum:
            - 10124
        msg:
          type: string
          enum:
            - internal error
        cause:
          type: string
    IntraBankNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - IntraBankNotSupported
        code:
          type: number
          enum:
            - 10376
        msg:
          type: string
          enum:
            - intra-bank requested on a project that has not enabled it
        cause:
          type: string
    IntraBankRail:
      type: string
      enum:
        - bookTransfer
        - crnow
        - ereborRail
      description: >-
        The rail an `intraBank` payment rides between two accounts at the same
        bank: `bookTransfer`, `crnow` or `ereborRail`.
    InvalidAmountFormatErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidAmountFormat
        code:
          type: number
          enum:
            - 10016
        msg:
          type: string
          enum:
            - amount must be positive
        cause:
          type: string
    InvalidAssetErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidAsset
        code:
          type: number
          enum:
            - 10107
        msg:
          type: string
          enum:
            - source.asset must be 'usd' for cash deposits
        cause:
          type: string
    InvalidCounterpartyIDErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidCounterpartyID
        code:
          type: number
          enum:
            - 10068
        msg:
          type: string
          enum:
            - invalid counterparty id
        cause:
          type: string
    InvalidCursorErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidCursor
        code:
          type: number
          enum:
            - 10088
        msg:
          type: string
          enum:
            - invalid
        cause:
          type: string
    InvalidCustomerIDErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidCustomerID
        code:
          type: number
          enum:
            - 10000
        msg:
          type: string
          enum:
            - invalid customer_id
        cause:
          type: string
    InvalidDestinationTypeErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidDestinationType
        code:
          type: number
          enum:
            - 10142
        msg:
          type: string
          enum:
            - destination has an unsupported or missing type
        cause:
          type: string
    InvalidExternalAccountIDErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidExternalAccountID
        code:
          type: number
          enum:
            - 10067
        msg:
          type: string
          enum:
            - invalid destination external account id
        cause:
          type: string
    InvalidFilterErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidFilter
        code:
          type: number
          enum:
            - 10267
        msg:
          type: string
          enum:
            - startingAfter and endingBefore are mutually exclusive
        cause:
          type: string
    InvalidLocationErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidLocation
        code:
          type: number
          enum:
            - 10102
        msg:
          type: string
          enum:
            - cash.locationId must start with 'loc_' prefix
        cause:
          type: string
    InvalidMetadataErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidMetadata
        code:
          type: number
          enum:
            - 10133
        msg:
          type: string
          enum:
            - invalid metadata
        cause:
          type: string
    InvalidParameterErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidParameter
        code:
          type: number
          enum:
            - 10006
        msg:
          type: string
          enum:
            - a request parameter is invalid
        cause:
          type: string
    InvalidParamsErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidParams
        code:
          type: number
          enum:
            - 10078
        msg:
          type: string
          enum:
            - invalid parameters
        cause:
          type: string
    InvalidProviderErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidProvider
        code:
          type: number
          enum:
            - 10007
        msg:
          type: string
          enum:
            - provider is not supported
        cause:
          type: string
    InvalidQuoteErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidQuote
        code:
          type: number
          enum:
            - 10269
        msg:
          type: string
          enum:
            - invalid quote
        cause:
          type: string
    InvalidRequestBodyErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidRequestBody
        code:
          type: number
          enum:
            - 10091
        msg:
          type: string
          enum:
            - invalid request body
        cause:
          type: string
    InvalidRequestErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidRequest
        code:
          type: number
          enum:
            - 10005
        msg:
          type: string
          enum:
            - the request is invalid
        cause:
          type: string
    InvalidSourceTypeErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidSourceType
        code:
          type: number
          enum:
            - 10141
        msg:
          type: string
          enum:
            - source has an unsupported or missing type
        cause:
          type: string
    InvalidStatusErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidStatus
        code:
          type: number
          enum:
            - 10114
        msg:
          type: string
          enum:
            - invalid status value
        cause:
          type: string
    InvalidWalletAddressErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidWalletAddress
        code:
          type: number
          enum:
            - 10112
        msg:
          type: string
          enum:
            - >-
              destination.wallet.blockchainAddress is not valid for
              destination.network
        cause:
          type: string
    InvalidWalletIDErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidWalletID
        code:
          type: number
          enum:
            - 10138
        msg:
          type: string
          enum:
            - invalid source fiat wallet id
        cause:
          type: string
    InvalidWalletTargetErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidWalletTarget
        code:
          type: number
          enum:
            - 10131
        msg:
          type: string
          enum:
            - destination.wallet is required
        cause:
          type: string
    InvalidWalletTypeErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - InvalidWalletType
        code:
          type: number
          enum:
            - 10149
        msg:
          type: string
          enum:
            - missing or unrecognized wallet type
        cause:
          type: string
    KYCPendingErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - KYCPending
        code:
          type: number
          enum:
            - 10009
        msg:
          type: string
          enum:
            - customer KYC is pending; retry shortly
        cause:
          type: string
    KYCRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - KYCRequired
        code:
          type: number
          enum:
            - 10008
        msg:
          type: string
          enum:
            - customer KYC verification is required
        cause:
          type: string
    LimitExceededErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - LimitExceeded
        code:
          type: number
          enum:
            - 10036
        msg:
          type: string
          enum:
            - provider transaction/velocity limit exceeded
        cause:
          type: string
    LimitMisconfiguredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - LimitMisconfigured
        code:
          type: number
          enum:
            - 10227
        msg:
          type: string
          enum:
            - transfer limit is misconfigured
        cause:
          type: string
    MemoNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MemoNotSupported
        code:
          type: number
          enum:
            - 10023
        msg:
          type: string
          enum:
            - memo is not supported on this rail
        cause:
          type: string
    MetadataKeyTooLongErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MetadataKeyTooLong
        code:
          type: number
          enum:
            - 10075
        msg:
          type: string
          enum:
            - metadata key must be 64 characters or fewer
        cause:
          type: string
    MetadataTooManyKeysErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MetadataTooManyKeys
        code:
          type: number
          enum:
            - 10074
        msg:
          type: string
          enum:
            - metadata may have at most 20 keys
        cause:
          type: string
    MetadataValueTooLongErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MetadataValueTooLong
        code:
          type: number
          enum:
            - 10076
        msg:
          type: string
          enum:
            - metadata value must be 500 characters or fewer
        cause:
          type: string
    MissingBillingAddressErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MissingBillingAddress
        code:
          type: number
          enum:
            - 10062
        msg:
          type: string
          enum:
            - billingAddress.line1 is required
        cause:
          type: string
    MissingCashLocationErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MissingCashLocation
        code:
          type: number
          enum:
            - 10132
        msg:
          type: string
          enum:
            - cash location not found
        cause:
          type: string
    MissingCustomerErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MissingCustomer
        code:
          type: number
          enum:
            - 10100
        msg:
          type: string
          enum:
            - request must include customer
        cause:
          type: string
    MissingLocationErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MissingLocation
        code:
          type: number
          enum:
            - 10101
        msg:
          type: string
          enum:
            - cash.locationId is required
        cause:
          type: string
    MissingLocationReferenceErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MissingLocationReference
        code:
          type: number
          enum:
            - 10109
        msg:
          type: string
          enum:
            - cash.locationReference is required
        cause:
          type: string
    MissingParameterErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MissingParameter
        code:
          type: number
          enum:
            - 10108
        msg:
          type: string
          enum:
            - destination.asset and destination.network are required
        cause:
          type: string
    MissingRequiredFieldErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MissingRequiredField
        code:
          type: number
          enum:
            - 10154
        msg:
          type: string
          enum:
            - destination.cash is required for cash off-ramp
        cause:
          type: string
    MissingWalletErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MissingWallet
        code:
          type: number
          enum:
            - 10104
        msg:
          type: string
          enum:
            - >-
              destination.wallet.id or destination.wallet.blockchainAddress is
              required
        cause:
          type: string
    MonthlyCountExceededErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MonthlyCountExceeded
        code:
          type: number
          enum:
            - 10226
        msg:
          type: string
          enum:
            - monthly transaction count limit reached
        cause:
          type: string
    MonthlyLimitExceededErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - MonthlyLimitExceeded
        code:
          type: number
          enum:
            - 10221
        msg:
          type: string
          enum:
            - monthly limit exceeded
        cause:
          type: string
    NameInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - NameInvalid
        code:
          type: number
          enum:
            - 10165
        msg:
          type: string
          enum:
            - name is invalid
        cause:
          type: string
    NationalityInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - NationalityInvalid
        code:
          type: number
          enum:
            - 10168
        msg:
          type: string
          enum:
            - nationality is invalid
        cause:
          type: string
    NetworkAsset:
      type: object
      required:
        - asset
      properties:
        asset:
          type: string
          description: 'Lowercase canonical asset code, e.g. `usdc`.'
        contractAddress:
          type: string
          nullable: true
          description: >-
            Token contract address. OMITTED — the JSON key is absent, not sent
            as an explicit `null` — for a native asset and for any asset with no
            on-chain identity record. "Key absent" and "explicit null" are
            equivalent here; no case needs telling the two apart.
        decimals:
          type: integer
          format: int32
          nullable: true
          description: >-
            Count of decimal places in the on-chain smallest unit. OMITTED (key
            absent, not explicit `null`) — see `contractAddress` for why absent
            and null are equivalent here — when there is no on-chain identity
            record for this (asset, network): the scale is then genuinely
            unknown, not zero. A partner must not assume a default scale and
            must not format an amount in this asset while `decimals` is absent —
            the same "absent means unproven, not false" convention
            `supportedBy.wallet` uses for a capability instead of a scale.
      description: One asset available on a network.
    NetworkCategory:
      type: string
      enum:
        - crypto
        - fiatAccount
        - cash
      description: Which broad class of network this is.
    NetworkFamily:
      type: string
      enum:
        - evm
        - solana
        - tron
      description: >-
        Crypto network family for a registered external wallet. A walletExternal
        is registered per family (an EVM address is valid across every EVM
        chain), and the registration covers every served network in that family.
        A create for a family the provider that provisions this project's
        walletExternal accounts does not serve is refused before anything is
        written, with 422 `NetworkFamilyNotServed`; depending on the provider,
        the refusal can be 403 `VendorConfigMissing` instead.
    NetworkFamilyInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - NetworkFamilyInvalid
        code:
          type: number
          enum:
            - 10051
        msg:
          type: string
          enum:
            - 'networkFamily must be one of: evm, solana, tron'
        cause:
          type: string
    NetworkFamilyNotServedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - NetworkFamilyNotServed
        code:
          type: number
          enum:
            - 10351
        msg:
          type: string
          enum:
            - >-
              networkFamily is not served by the vendor that provisions
              walletExternal accounts for this project
        cause:
          type: string
    NetworkKind:
      type: string
      enum:
        - blockchain
        - bankRail
        - card
        - physical
      description: The transport a network uses.
    NetworkList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/SupportedNetwork'
          description: The page of results.
      description: 'Supported networks, ordered by `network`.'
    NoRouteAvailableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - NoRouteAvailable
        code:
          type: number
          enum:
            - 10013
        msg:
          type: string
          enum:
            - no route available for this corridor
        cause:
          type: string
    NonZeroBalanceErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - NonZeroBalance
        code:
          type: number
          enum:
            - 10203
        msg:
          type: string
          enum:
            - virtual account has a non-zero balance
        cause:
          type: string
    NotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - NotFound
        code:
          type: number
          enum:
            - 3000
        msg:
          type: string
          enum:
            - resource not found
        cause:
          type: string
    OtherCustodianRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - OtherCustodianRequired
        code:
          type: number
          enum:
            - 10053
        msg:
          type: string
          enum:
            - otherCustodian is required when custodian is OTHER
        cause:
          type: string
    OtherCustodianTooLongErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - OtherCustodianTooLong
        code:
          type: number
          enum:
            - 10054
        msg:
          type: string
          enum:
            - otherCustodian must be at most 100 characters
        cause:
          type: string
    OwnerCounterparty:
      type: object
      required:
        - kind
        - counterpartyId
      properties:
        kind:
          type: string
          enum:
            - counterparty
          description: Owner kind discriminator.
        counterpartyId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Counterparty (ctp_…) id.
      description: Counterparty-owned External Account (an address-book entry).
      title: Counterparty-owned
    OwnerCustomer:
      type: object
      required:
        - kind
        - customerId
      properties:
        kind:
          type: string
          enum:
            - customer
          description: Owner kind discriminator.
        customerId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Owning customer ID (`cst_` prefix).
      description: Customer-owned External Account.
      title: Customer-owned
    OwnerInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - OwnerInvalid
        code:
          type: number
          enum:
            - 10047
        msg:
          type: string
          enum:
            - owner is required
        cause:
          type: string
    OwnerNotActiveErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - OwnerNotActive
        code:
          type: number
          enum:
            - 10070
        msg:
          type: string
          enum:
            - counterparty owner is not active
        cause:
          type: string
    PaymentMethodNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - PaymentMethodNotFound
        code:
          type: number
          enum:
            - 10083
        msg:
          type: string
          enum:
            - payment method not found
        cause:
          type: string
    Payout:
      type: object
      required:
        - rail
      properties:
        rail:
          allOf:
            - $ref: '#/components/schemas/TransferRail'
          description: >-
            The rail payouts move on from now on. Once the public-name cutover
            has passed, the same value as the `rail` of a payout transfer sent
            after it; a transfer sent before keeps its older name.
        instantRail:
          allOf:
            - $ref: '#/components/schemas/InstantRail'
          description: >-
            Only when `rail` is `instant`, the same value as the payout
            transfer's `instantRail`.
        intraBankRail:
          allOf:
            - $ref: '#/components/schemas/IntraBankRail'
          description: >-
            Only when `rail` is `intraBank`, the same value as the payout
            transfer's `intraBankRail`.
        secCode:
          allOf:
            - $ref: '#/components/schemas/SecCode'
          description: >-
            ACH SEC code, only on `ach` and `achSameDay`. Derived from the
            destination owner's and the customer's entity type; left out while
            either is unknown. Never on a return.
        companyDiscretionaryData:
          type: string
          description: >-
            The ACH company discretionary data sent with each payout, only on
            `ach` and `achSameDay` and only when you set it. Never on a return.
      description: >-
        How a Deposit Address or a Virtual Account pays a deposit out to its
        bank or fiat-wallet destination, or how a Virtual Account returns one to
        its bank return destination.
    PayoutOrigin:
      type: object
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - bank
            - blockchain
        id:
          $ref: '#/components/schemas/typeId'
        accountHolder:
          allOf:
            - $ref: '#/components/schemas/PayoutOriginAccountHolder'
          description: >-
            Whose legal identity the payment is sent under. Determined by OMS
            from the route's configuration — not a request field. Left out when
            OMS cannot determine it, and on destinations that have no sending
            legal identity (cash payouts, and crypto payouts outside a Deposit
            Address). A bank payout that goes out under the payment provider or
            the partner records that holder just before it is sent to the
            provider, and reports it only while a payout was or may have been
            created there; a send interrupted after the holder was recorded and
            before it went out has an unknown outcome and may report it. A
            failed send known to have created no payout at the provider, and a
            payout sent before holders were recorded whose holder could not be
            recovered afterwards, report the fallback value instead, which may
            differ from the holder actually used. The fallback value, also
            reported before a holder is recorded and for payouts that always go
            out under the customer's own name, is the holder the Deposit Address
            fixed for the destination type the transaction pays on a transaction
            created from a Deposit Address, and the value its route implies on
            any other.
        accountHolderName:
          type: string
          description: >-
            The legal name the payment is sent under, resolved from
            `accountHolder` — the customer's own legal name for `customer`, the
            owning customer's legal name for `partner` (for now; a partner-level
            name may replace it later), or the payment provider's name for
            `paymentProvider`, which differs between a `bank` origin ("Coinme
            Inc FBO its Customers") and a `blockchain` origin. This is what the
            recipient sees as the sender. Like `accountHolder` and unlike `id`,
            it is populated as soon as it is determinable, so it appears on
            Quote, Deposit Address and Virtual Account responses as well as
            Transactions. Left out whenever `accountHolder` is, and when the
            customer's name cannot be read at that moment.
      description: >-
        Where last-mile delivery is sent *from*, as a uniform `{type, id}`
        reference — response-only. `id` is the Virtual Account (`va_`) or OMS
        wallet (`wlt_`) funding the leg; left out before execution (Quote /
        Deposit Address echo the choice only) or when the origin has no
        partner-visible resource. Rail identifiers for the last-mile transfer
        live in the top-level `tracking` array with `leg: destination` — not
        here.
    PayoutOriginAccountHolder:
      type: string
      enum:
        - customer
        - paymentProvider
        - partner
      description: >-
        Whose legal name an outbound payment is sent under — the name that
        appears on the recipient's statement. Determined by which institution
        executes the payout and by your project's configuration, not by anything
        you send: outbound fiat executed by Erebor Bank, N.A. goes out under the
        customer's own legal name (`customer`), while outbound fiat executed by
        Cross River Bank goes out under the payment provider (`paymentProvider`,
        `accountHolderName` "Coinme Inc FBO its Customers") or, on a project
        configured to send under its own name, under the partner (`partner`). A
        Deposit Address created while its customer holds an active Virtual
        Account from the same provider fixes `customer` as its bank holder;
        payouts are not sent from that account, so each of its transactions
        reports the holder described on `PayoutOrigin.accountHolder`. Crypto
        sent from a Deposit Address goes out under whoever holds the sending
        wallet. Read the pair rather than inferring either from a resource's
        `provider` field, which names the custodian of the account and can be a
        different company entirely. On a Virtual Account the pair is reported as
        a top-level `payoutOrigin`, present for its bank and crypto-wallet
        destinations and absent for `walletFiat`. A cash payout has no
        `payoutOrigin`, and a crypto payout outside a Deposit Address leaves the
        pair out. New values may be added.
    PendingTransactionsExistErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - PendingTransactionsExist
        code:
          type: number
          enum:
            - 10209
        msg:
          type: string
          enum:
            - pending transactions exist for this virtual account
        cause:
          type: string
    PhoneInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - PhoneInvalid
        code:
          type: number
          enum:
            - 10170
        msg:
          type: string
          enum:
            - phone is invalid
        cause:
          type: string
    Precursor:
      type: object
      required:
        - type
        - id
      properties:
        type:
          type: string
          enum:
            - quote
            - depositAddress
            - virtualAccount
            - cashIn
            - manual
            - walletDeposit
        id:
          type: string
          allOf:
            - $ref: '#/components/schemas/typeId'
          nullable: true
          description: >-
            `qt_` / `da_` / `va_` / `ci_`. Null for `manual` and
            `walletDeposit`.
      description: >-
        What created this transaction, as a uniform `{type, id}` reference.
        Dereference the resource by `id` for its full record — deposit
        instructions live on the Virtual Account / Deposit Address / Cash-In,
        not here. `id` is null only for `manual` (operator-initiated, no origin
        resource) and `walletDeposit` (a custodial-wallet deposit, no
        originating OMS resource). The `precursor` field on Transaction is
        itself nullable separately, for out-of-band arrivals with no originating
        OMS resource and no recognised origin.
    Pricing:
      type: object
      required:
        - fees
      properties:
        source:
          allOf:
            - $ref: '#/components/schemas/PricingSide'
          description: 'The source side, in the source asset.'
        destination:
          allOf:
            - $ref: '#/components/schemas/PricingSide'
          description: 'The destination side, in the destination asset.'
        fees:
          type: array
          items:
            $ref: '#/components/schemas/PricingFee'
          description: >-
            Every fee charged across both sides. `[]` when there are none —
            never omitted, never null.
        exchangeRate:
          type: string
          description: >-
            Mid-market rate from the source asset to the destination asset, set
            together with the destination amount. Identity: (source.amount − Σ
            source fees) × exchangeRate = destination.amount + Σ destination
            fees.
        fixedAmountSide:
          type: string
          enum:
            - source
            - destination
          description: >-
            The side whose amount was fixed at creation. OMS calculated the
            other side.
        sponsorGas:
          type: boolean
          description: >-
            Present and `true` when OMS absorbs the destination gas cost;
            omitted otherwise.
      description: >-
        Consolidated economics for a quote, transaction or cash-in: per-side
        amounts, a flat fee list, the mid-market rate and gas sponsorship.
    PricingFee:
      type: object
      required:
        - type
        - side
        - asset
        - amount
      properties:
        type:
          type: string
          description: >-
            Fee kind. OPEN — clients must tolerate an unrecognised type. Known
            values today: "developer", "oms", "gas".
        side:
          type: string
          enum:
            - source
            - destination
          description: Which side this fee was deducted from.
        asset:
          type: string
          description: Currency this fee is denominated in — that side's asset.
        amount:
          type: string
          description: 'Fee amount in `asset`, at the asset''s precision.'
      description: >-
        A fee charged on one side of a quote, transaction or cash-in. A fee is
        listed only when it is not zero.
    PricingSide:
      type: object
      required:
        - asset
      properties:
        amount:
          type: string
          description: >-
            On the source, the gross amount the customer pays; on the
            destination, the amount that arrives. A decimal string at the
            asset's precision. Always set on the source; set on the destination
            once priced.
        asset:
          type: string
          description: >-
            Lowercase asset of this side, the same as the side's instrument
            asset.
      description: >-
        One side of `pricing`, in that side's asset. Fees are listed in
        `Pricing.fees`.
    ProductDailyLimitReachedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ProductDailyLimitReached
        code:
          type: number
          enum:
            - 10381
        msg:
          type: string
          enum:
            - the daily instant payout limit has been reached
        cause:
          type: string
    ProjectMissingCoinmeIDErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ProjectMissingCoinmeID
        code:
          type: number
          enum:
            - 10073
        msg:
          type: string
          enum:
            - project is not enrolled with a custodial wallet provider
        cause:
          type: string
    ProviderErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - Provider
        code:
          type: number
          enum:
            - 10002
        msg:
          type: string
          enum:
            - invalid provider balance response
        cause:
          type: string
    ProviderRefreshFailedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ProviderRefreshFailed
        code:
          type: number
          enum:
            - 10116
        msg:
          type: string
          enum:
            - failed to refresh deposit code; old code remains valid
        cause:
          type: string
    ProviderRequestFailedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ProviderRequestFailed
        code:
          type: number
          enum:
            - 10375
        msg:
          type: string
          enum:
            - the provider could not complete the request
        cause:
          type: string
    ProviderTimeoutErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ProviderTimeout
        code:
          type: number
          enum:
            - 10021
        msg:
          type: string
          enum:
            - the provider's refresh service did not respond in time
        cause:
          type: string
    ProviderUnavailableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ProviderUnavailable
        code:
          type: number
          enum:
            - 10121
        msg:
          type: string
          enum:
            - cash location provider is temporarily unavailable
        cause:
          type: string
    ProviderUnreachableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ProviderUnreachable
        code:
          type: number
          enum:
            - 10087
        msg:
          type: string
          enum:
            - upstream provider unreachable
        cause:
          type: string
    ProviderUserAccountNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ProviderUserAccountNotFound
        code:
          type: number
          enum:
            - 10029
        msg:
          type: string
          enum:
            - provider account not provisioned for this customer
        cause:
          type: string
    Quote:
      type: object
      required:
        - id
        - object
        - status
        - customerId
        - source
        - destination
        - pricing
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Quote ID (`qt_` prefix).
        object:
          type: string
          enum:
            - quote
          description: Resource type discriminator. Always "quote".
        status:
          allOf:
            - $ref: '#/components/schemas/QuoteStatus'
          description: Current status of the quote.
        sourceToDestination:
          allOf:
            - $ref: '#/components/schemas/SourceToDestination'
          description: Corridor composite derived from the two sides.
        customerId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: The OMS customer that owns this record (`cst_` prefix).
        customer:
          allOf:
            - $ref: '#/components/schemas/CustomerSummary'
          description: >-
            Display-safe summary of the owning customer (`customer.id` equals
            `customerId`). Omitted when the customer cannot be resolved.
        source:
          allOf:
            - $ref: '#/components/schemas/TransactionSide'
          description: >-
            The funding side, echoed from the request with resolved instrument
            detail.
        destination:
          allOf:
            - $ref: '#/components/schemas/TransactionDestination'
          description: >-
            The receiving side, echoed from the request with resolved instrument
            detail.
        pricing:
          allOf:
            - $ref: '#/components/schemas/Pricing'
          description: Consolidated economics.
        expiresAt:
          type: string
          format: date-time
          description: When the locked pricing expires.
        createdAt:
          type: string
          format: date-time
          description: When the quote was created.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: Free-form key-value pairs supplied at creation or update.
      description: >-
        A price quote for moving money between two instruments. It locks an
        exchange rate and the amounts for a short window; execute it by creating
        a transaction that references this quote's id.
      example:
        id: qt_0gq9aesz4wb5etdv88z1j61qcm
        object: quote
        status: open
        sourceToDestination: cryptoToFiatAccount
        customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
        customer:
          id: cst_vfa0nxw6zvyws9g237jrxn4y7k
          name: Jane Smith
        source:
          type: walletCrypto
          id: wlt_5h4jzzpr9xre3bamd9ca7qyghn
          asset: usdc
          network: polygon
          details:
            address: '0x7B3A9F2C4D1eA8bf6390cE5D2b7fA104c8e3D9B1'
        destination:
          owner:
            kind: counterparty
            id: ctp_yp5z8m7n22svc0vh6edqgcfdat
            name: Alice Smith
          type: bankUs
          id: ext_fky491gakzj0dd46qb6whsr2vq
          asset: usd
          network: ach
          details:
            accountNumberLast4: '1234'
            holderName: Alice Smith
          payoutOrigin:
            type: bank
            accountHolder: customer
            accountHolderName: Jane Smith
        pricing:
          source:
            asset: usdc
            amount: '100.000000'
          destination:
            asset: usd
            amount: '100.00'
          fees: []
          exchangeRate: '1.0000'
          fixedAmountSide: source
          sponsorGas: true
        expiresAt: '2026-03-14T19:15:00Z'
        createdAt: '2026-03-14T19:00:00Z'
    QuoteConsumedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - QuoteConsumed
        code:
          type: number
          enum:
            - 10262
        msg:
          type: string
          enum:
            - quote has already been consumed
        cause:
          type: string
    QuoteCreateRequest:
      type: object
      required:
        - customerId
        - source
        - destination
      properties:
        customerId:
          type: string
          description: The customer this quote is for (`cst_` prefix).
        source:
          allOf:
            - $ref: '#/components/schemas/QuoteSourceRequest'
          description: >-
            What funds the transaction. Pick a `type`: an OMS crypto wallet
            (`walletCrypto`) or a registered card (`card`, pull-from-card).
        destination:
          allOf:
            - $ref: '#/components/schemas/QuoteSideRequest'
          description: >-
            The instrument that receives the funds. Pick a `type`: a wallet
            (`walletCrypto` / `walletExternal`), a bank account (`bankUs` /
            `bankIban` / `bankCanada`), a `card`, or `cash`.
        sponsorGas:
          type: boolean
          description: >-
            When `true`, OMS absorbs the on-chain gas cost for the destination
            delivery. Only `true` is currently supported. Ignored for non-crypto
            destinations (no on-chain leg).
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the quote and copied to the
            resulting transaction.
      description: >-
        Request body for creating a quote. Pick a `type` on each side and set
        the amount on exactly one side; OMS calculates the other.
      example:
        customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
        source:
          type: walletCrypto
          details:
            id: wlt_5h4jzzpr9xre3bamd9ca7qyghn
            asset: usdc
            network: polygon
          amount: '100.00'
        destination:
          type: bankUs
          details:
            id: ext_fky491gakzj0dd46qb6whsr2vq
            asset: usd
            network: ach
        sponsorGas: true
        metadata:
          orderId: order_12345
    QuoteExpiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - QuoteExpired
        code:
          type: number
          enum:
            - 10077
        msg:
          type: string
          enum:
            - quote has expired
        cause:
          type: string
    QuoteMissingCustomerErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - QuoteMissingCustomer
        code:
          type: number
          enum:
            - 10256
        msg:
          type: string
          enum:
            - quote has no customer
        cause:
          type: string
    QuoteNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - QuoteNotFound
        code:
          type: number
          enum:
            - 10260
        msg:
          type: string
          enum:
            - quote not found
        cause:
          type: string
    QuoteRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - QuoteRequired
        code:
          type: number
          enum:
            - 10268
        msg:
          type: string
          enum:
            - quoteId is required
        cause:
          type: string
    QuoteSideRequest:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletCryptoSideRequest'
        - $ref: '#/components/schemas/WalletExternalSideRequest'
        - $ref: '#/components/schemas/BankUsSideRequest'
        - $ref: '#/components/schemas/BankIbanSideRequest'
        - $ref: '#/components/schemas/BankCanadaSideRequest'
        - $ref: '#/components/schemas/CardSideRequest'
        - $ref: '#/components/schemas/CashSideRequest'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletCryptoSideRequest'
          walletExternal: '#/components/schemas/WalletExternalSideRequest'
          bankUs: '#/components/schemas/BankUsSideRequest'
          bankIban: '#/components/schemas/BankIbanSideRequest'
          bankCanada: '#/components/schemas/BankCanadaSideRequest'
          card: '#/components/schemas/CardSideRequest'
          cash: '#/components/schemas/CashSideRequest'
      description: >-
        The instrument that receives the funds: a wallet (`walletCrypto` /
        `walletExternal`), a bank account (`bankUs` / `bankIban` /
        `bankCanada`), a `card`, or `cash`.
    QuoteSourceRequest:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletCryptoSideRequest'
        - $ref: '#/components/schemas/WalletFiatSideRequest'
        - $ref: '#/components/schemas/CardSideRequest'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletCryptoSideRequest'
          walletFiat: '#/components/schemas/WalletFiatSideRequest'
          card: '#/components/schemas/CardSideRequest'
      description: >-
        What funds a quote: an OMS Multi-Chain Wallet (`walletCrypto`), a fiat
        balance wallet (`walletFiat`), or a registered card (`card`,
        pull-from-card). `card` requires `asset: usd`.
    QuoteStatus:
      type: string
      enum:
        - open
        - accepted
        - expired
      description: >-
        Status of a quote. open: pricing locked, awaiting acceptance. accepted:
        a transaction has been created from it. expired: the pricing window
        elapsed.
    QuoteTypeMismatchErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - QuoteTypeMismatch
        code:
          type: number
          enum:
            - 10261
        msg:
          type: string
          enum:
            - unsupported quote type for transactions
        cause:
          type: string
    RailNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - RailNotSupported
        code:
          type: number
          enum:
            - 10235
        msg:
          type: string
          enum:
            - outbound rail does not support re-drive
        cause:
          type: string
    Reason:
      type: object
      required:
        - code
        - message
        - retryable
      properties:
        code:
          allOf:
            - $ref: '#/components/schemas/ReasonCode'
          description: What went wrong.
        message:
          type: string
          description: 'A fixed, vendor-neutral sentence for `code`.'
        retryable:
          type: boolean
          description: Whether trying the same thing again can succeed.
        bankCode:
          type: string
          description: >-
            The bank's own return code, only on an external account a bank
            return made invalid.
      description: >-
        Why a resource failed, was rejected or became invalid. `message` and
        `retryable` are fixed for each `code`.
    ReasonCode:
      type: string
      enum:
        - providerError
        - providerRejected
        - providerTimeout
        - expired
        - systemError
        - provisioningTimeout
        - insufficientFunds
        - providerAmountBelowMinimum
        - limitExceeded
        - outsideSellBounds
        - outsideSellVelocityBounds
        - unusableAmount
        - unsupportedCorridor
        - outgoingRailNotEnabled
        - ssnNotVerified
        - riskRejected
        - cardDeclined
        - bankSellDeclined
        - payoutFailed
        - priceMoved
        - returningToSender
        - returnedToSender
        - returnFailed
        - depositFailed
        - attributionTimeout
        - assetMismatch
        - chainMismatch
        - misattributedArrival
        - depositAddressNotActive
        - virtualAccountNotActive
        - counterpartyArchived
        - destinationUnavailable
        - walletClaimed
        - walletBoundToCustodialFlow
        - projectSuspended
        - memoInvalid
        - cashDepositFailed
        - noMatchingNetwork
        - blockchainAddressInUse
        - bankAccountInUse
        - bankAccountRejected
        - deletePendingTimeout
        - providerAccountMissing
        - cardInUse
        - cardLimitReached
        - countryProhibited
        - countryNotSupported
        - cardVerificationDeclined
        - bankVerificationDeclined
        - accountClosed
        - accountFrozenByBank
        - routingOrAccountNumberInvalid
        - accountHolderDeceased
        - accountDoesNotSupportTransfers
        - payeeNameMismatch
        - walletUnreachableOnNetwork
        - billingAddressMismatch
        - cardExpired
        - cardClosedOrLostStolen
        - pushToCardUnsupported
        - cardDeclinedByIssuer
      description: The reasons a resource reports in `failure`.
    RefreshExpiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - RefreshExpired
        code:
          type: number
          enum:
            - 10115
        msg:
          type: string
          enum:
            - refresh window has expired; original 24-hour TTL has passed
        cause:
          type: string
    RefreshLimitReachedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - RefreshLimitReached
        code:
          type: number
          enum:
            - 10117
        msg:
          type: string
          enum:
            - cash-in has already been refreshed the maximum number of times
        cause:
          type: string
    RefreshTooFrequentErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - RefreshTooFrequent
        code:
          type: number
          enum:
            - 10118
        msg:
          type: string
          enum:
            - minimum interval between refreshes has not yet elapsed
        cause:
          type: string
    RequestTooLargeErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - RequestTooLarge
        code:
          type: number
          enum:
            - 2002
        msg:
          type: string
          enum:
            - request body too large
        cause:
          type: string
    ReturnDestinationMustBeMultiAssetErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ReturnDestinationMustBeMultiAsset
        code:
          type: number
          enum:
            - 10192
        msg:
          type: string
          enum:
            - only a multi-asset wallet is a valid return target
        cause:
          type: string
    ReturnWalletInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ReturnWalletInvalid
        code:
          type: number
          enum:
            - 10191
        msg:
          type: string
          enum:
            - >-
              returnWallet reference failed structural validation or DB-backed
              resolution
        cause:
          type: string
    RiskRejectedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - RiskRejected
        code:
          type: number
          enum:
            - 10033
        msg:
          type: string
          enum:
            - card provider rejected the card on risk review
        cause:
          type: string
    RiskSessionRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - RiskSessionRequired
        code:
          type: number
          enum:
            - 10307
        msg:
          type: string
          enum:
            - >-
              A webSessionId (generated by the Sardine SDK) is required when the
              quote's source or destination is a card.
        cause:
          type: string
    RouteDisabledErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - RouteDisabled
        code:
          type: number
          enum:
            - 10014
        msg:
          type: string
          enum:
            - route is currently disabled
        cause:
          type: string
    RoutingNumberInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - RoutingNumberInvalid
        code:
          type: number
          enum:
            - 10041
        msg:
          type: string
          enum:
            - routingNumber must be exactly 9 digits
        cause:
          type: string
    SSNNotVerifiedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - SSNNotVerified
        code:
          type: number
          enum:
            - 10032
        msg:
          type: string
          enum:
            - card provider could not verify the customer's SSN
        cause:
          type: string
    SecCode:
      type: string
      enum:
        - ccd
        - ppd
        - web
      description: >-
        ACH SEC code. Present only when the destination bank network is
        `ach`/`achSameDay`. Server-derived from the destination owner's and the
        source customer's `entityType`.
    SelfTransferNotAllowedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - SelfTransferNotAllowed
        code:
          type: number
          enum:
            - 10140
        msg:
          type: string
          enum:
            - self-transfer not allowed
        cause:
          type: string
    SellNotAllowedAtLocationErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - SellNotAllowedAtLocation
        code:
          type: number
          enum:
            - 10157
        msg:
          type: string
          enum:
            - the specified cash location does not allow sell transactions
        cause:
          type: string
    ServiceUnavailableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ServiceUnavailable
        code:
          type: number
          enum:
            - 5003
        msg:
          type: string
          enum:
            - service unavailable
        cause:
          type: string
    SimulateCashInCancelRequest:
      type: object
      required:
        - cashInCode
        - amount
        - originalConfirmationId
      properties:
        cashInCode:
          type: string
        amount:
          $ref: '#/components/schemas/decimalString'
        originalConfirmationId:
          type: string
          description: The `confirmationId` returned by `present-code`.
    SimulateCashInCancelResponse:
      type: object
      required:
        - responseCode
        - responseText
        - responseId
      properties:
        responseCode:
          type: string
        responseText:
          type: string
        responseId:
          type: string
    SimulateCashInDepositCashRequest:
      type: object
      required:
        - cashInCode
        - amount
        - originalConfirmationId
      properties:
        cashInCode:
          type: string
        amount:
          $ref: '#/components/schemas/decimalString'
        originalConfirmationId:
          type: string
          description: The `confirmationId` returned by `present-code`.
    SimulateCashInDepositCashResponse:
      type: object
      required:
        - responseCode
        - responseText
        - responseId
        - confirmationId
        - authorizedAmount
      properties:
        responseCode:
          type: string
        responseText:
          type: string
        responseId:
          type: string
        confirmationId:
          type: string
          description: Confirmation of the completed deposit.
        authorizedAmount:
          allOf:
            - $ref: '#/components/schemas/decimalString'
          description: Amount deposited.
    SimulateCashInPresentCodeRequest:
      type: object
      required:
        - cashInCode
        - amount
      properties:
        cashInCode:
          type: string
          description: >-
            The cash-in's `depositInstructions.code` — what the customer
            presents at the register.
        amount:
          $ref: '#/components/schemas/decimalString'
    SimulateCashInPresentCodeResponse:
      type: object
      required:
        - responseCode
        - responseText
        - responseId
        - confirmationId
        - authorizedAmount
        - balance
      properties:
        responseCode:
          type: string
        responseText:
          type: string
        responseId:
          type: string
        confirmationId:
          type: string
          description: >-
            Authorization confirmation — pass as `originalConfirmationId` to
            `deposit-cash` or `cancel`.
        authorizedAmount:
          allOf:
            - $ref: '#/components/schemas/decimalString'
          description: Amount the provider authorized.
        balance:
          allOf:
            - $ref: '#/components/schemas/decimalString'
          description: >-
            Provider-reported running balance for this cash-in code after the
            authorization.
    SimulateVaBankIbanInboundRequest:
      type: object
      required:
        - type
        - network
        - asset
        - amount
      properties:
        type:
          type: string
          enum:
            - bankIban
          description: Rail discriminator. Always `bankIban` for an international inbound.
        network:
          type: string
          enum:
            - swift
          description: Always "swift" for the international rail.
        asset:
          type: string
          enum:
            - usd
          description: 'Always "usd", the only asset the VA rail supports today.'
        amount:
          allOf:
            - $ref: '#/components/schemas/decimalString'
          description: >-
            Must be greater than 0.00 and at most 10.00 (400 `AmountExceedsCap`
            beyond).
      description: International (SWIFT) inbound simulation against a Virtual Account.
      title: International bank account (SWIFT)
    SimulateVaBankUsInboundRequest:
      type: object
      required:
        - type
        - network
        - asset
        - amount
      properties:
        type:
          type: string
          enum:
            - bankUs
          description: Rail discriminator. Always `bankUs` for a US domestic inbound.
        network:
          allOf:
            - $ref: '#/components/schemas/SimulateVaBankUsNetwork'
          description: Which US rail to simulate.
        asset:
          type: string
          enum:
            - usd
          description: 'Always "usd", the only asset the VA rail supports today.'
        amount:
          allOf:
            - $ref: '#/components/schemas/decimalString'
          description: >-
            Must be greater than 0.00 and at most 10.00 (400 `AmountExceedsCap`
            beyond).
      description: >-
        US domestic (ACH, Wire or RTP) inbound simulation against a Virtual
        Account.
      title: 'US bank account (ACH, Wire or RTP)'
    SimulateVaBankUsNetwork:
      type: string
      enum:
        - ach
        - wire
        - rtp
      description: >-
        Network for a `bankUs` (US domestic) inbound simulation. Not every rail
        is available on every Virtual Account; one whose provider does not offer
        the requested rail refuses the request.
    SimulateVaInboundTransferNetwork:
      type: string
      enum:
        - ach
        - wire
        - rtp
        - swift
      description: Network actually used — the union of both request rails' networks.
    SimulateVaInboundTransferRequest:
      type: object
      oneOf:
        - $ref: '#/components/schemas/SimulateVaBankUsInboundRequest'
        - $ref: '#/components/schemas/SimulateVaBankIbanInboundRequest'
      discriminator:
        propertyName: type
        mapping:
          bankUs: '#/components/schemas/SimulateVaBankUsInboundRequest'
          bankIban: '#/components/schemas/SimulateVaBankIbanInboundRequest'
      description: >-
        Type-discriminated request for POST
        /virtual-accounts/{id}/simulate/inbound-transfer.
    SimulateVaInboundTransferResponse:
      type: object
      required:
        - virtualAccountId
        - type
        - network
        - asset
        - amount
        - status
        - submittedAt
        - referenceId
      properties:
        virtualAccountId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The Virtual Account that received the simulated transfer (`va_`
            prefix).
        type:
          allOf:
            - $ref: '#/components/schemas/SimulateVaInboundTransferType'
          description: Echoes the request's rail discriminator.
        network:
          allOf:
            - $ref: '#/components/schemas/SimulateVaInboundTransferNetwork'
          description: The rail the transfer settled on.
        asset:
          type: string
          enum:
            - usd
          description: Always "usd".
        amount:
          allOf:
            - $ref: '#/components/schemas/decimalString'
          description: The simulated transfer amount.
        status:
          type: string
          enum:
            - submitted
            - pending
          description: >-
            "submitted" for ach/wire/rtp; "pending" for swift — the upstream
            provider settles SWIFT asynchronously.
        submittedAt:
          type: string
          format: date-time
          description: When the simulated transfer was submitted.
        referenceId:
          type: string
          nullable: true
          description: >-
            Correlation id for the subsequent webhook. `null` for ach/wire/rtp;
            an `intl_wire_in_…` id for swift.
      description: >-
        Flat (non-discriminated) response for POST
        /virtual-accounts/{id}/simulate/inbound-transfer.
    SimulateVaInboundTransferType:
      type: string
      enum:
        - bankUs
        - bankIban
      description: Echoes the request's `type` discriminator on the response.
    SourceAssetRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - SourceAssetRequired
        code:
          type: number
          enum:
            - 10127
        msg:
          type: string
          enum:
            - source.asset is required
        cause:
          type: string
    SourceNetworkRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - SourceNetworkRequired
        code:
          type: number
          enum:
            - 10129
        msg:
          type: string
          enum:
            - source.network is required
        cause:
          type: string
    SourceToDestination:
      type: string
      enum:
        - cryptoToCrypto
        - cryptoToCash
        - cryptoToFiatAccount
        - cashToCrypto
        - fiatAccountToCrypto
        - fiatAccountToFiatAccount
      description: >-
        Composite of source and destination instrument categories, inferred from
        each side. The cash corridors (`cryptoToCash`, `cashToCrypto`) are
        derived from a cash-pickup destination / cash-in source respectively;
        the rest map straight from the internal corridor type.
    SourceWalletRequiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - SourceWalletRequired
        code:
          type: number
          enum:
            - 10126
        msg:
          type: string
          enum:
            - source.details.id is required
        cause:
          type: string
    SupportedBy:
      type: object
      properties:
        externalAccount:
          type: object
          properties:
            asSource:
              type: array
              items:
                type: string
            asDestination:
              type: array
              items:
                type: string
          required:
            - asSource
            - asDestination
          description: >-
            External-account types usable on this network, per direction — e.g.
            `["walletExternal"]` on a chain, `["bankUs"]` on `ach`.
        depositAddress:
          $ref: '#/components/schemas/DirectionalFlag'
        virtualAccount:
          $ref: '#/components/schemas/DirectionalFlag'
        cashIn:
          $ref: '#/components/schemas/DirectionalFlag'
        card:
          allOf:
            - $ref: '#/components/schemas/DirectionalFlag'
          description: >-
            Whether a card transaction (a `card` source or destination on `POST
            /quotes`) can use this network on that side. On the `card` network,
            `asSource` means pull-from-card funding is available and
            `asDestination` means push-to-card payout is available. On any other
            network, `asDestination` means a card-funded transaction can deliver
            onto it and `asSource` means it can fund a push-to-card payout.


            Always present. `false` means no enabled card route available to the
            calling project uses this network in that direction.
        wallet:
          allOf:
            - $ref: '#/components/schemas/DirectionalFlag'
          description: >-
            Whether an OMS-custodied wallet can hold value on this network and
            use it as a source or destination.


            ABSENT means unproven, not false: wallet custody is only reported
            for networks where it is established. A network that omits this
            property may gain it later as a data change, not a contract change.
      description: >-
        Which OMS resources can use this network, and in which direction.


        Every property is optional, and absence is meaningful: it means the
        answer is not established, NOT that the answer is no. A client must not
        treat a missing property as `false`. `wallet` is the field this applies
        to in practice — see its own description.
    SupportedNetwork:
      type: object
      required:
        - network
        - category
        - type
        - displayName
        - assets
        - supportedBy
      properties:
        network:
          type: string
          description: >-
            Partner-facing network token — the value to send in a request
            `network` field. Always a camelCase public token (for example
            `swift`), never a snake_case internal code. `local` is a
            contract-legal request value with no distinct entry here: routes are
            validated against the coarser `swift` rail, so `local` availability
            is reported under `swift`. Same-day ACH is its own entry,
            `achSameDay`, and the fiat wallet is always listed, as
            `bookTransfer` before the public-name cutover and `intraBank` after.
        category:
          $ref: '#/components/schemas/NetworkCategory'
        type:
          $ref: '#/components/schemas/NetworkKind'
        chainId:
          type: integer
          format: int64
          nullable: true
          description: >-
            EVM chain id. OMITTED (key absent, not explicit `null`) for a
            non-EVM network — see `contractAddress` for why absent and null are
            equivalent here. A network whose chain identifier is not an integer
            (for example Solana, identified by a base58 genesis hash) omits the
            key.
        networkFamily:
          allOf:
            - $ref: '#/components/schemas/NetworkFamily'
          nullable: true
          description: >-
            OMITTED (key absent, not explicit `null`) for non-blockchain
            networks — see `contractAddress` for why absent and null are
            equivalent here.
        displayName:
          type: string
          description: 'Human-readable label, e.g. "Polygon PoS".'
        assets:
          type: array
          items:
            $ref: '#/components/schemas/NetworkAsset'
        supportedBy:
          $ref: '#/components/schemas/SupportedBy'
      description: >-
        A network OMS supports, with its identifiers, assets, and capability
        map.
    TaxIDInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - TaxIDInvalid
        code:
          type: number
          enum:
            - 10171
        msg:
          type: string
          enum:
            - taxId is invalid
        cause:
          type: string
    TooManyCardAttemptsErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - TooManyCardAttempts
        code:
          type: number
          enum:
            - 10065
        msg:
          type: string
          enum:
            - >-
              too many card registration attempts for this customer; please
              retry later
        cause:
          type: string
    Transaction:
      type: object
      required:
        - id
        - status
        - subStatus
        - customer
        - source
        - destination
        - pricing
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Transaction ID (`txn_` prefix).
        status:
          allOf:
            - $ref: '#/components/schemas/TransactionStatus'
          description: Current lifecycle status. See `subStatus` for finer granularity.
        subStatus:
          allOf:
            - $ref: '#/components/schemas/TransactionSubStatus'
          description: >-
            Status-scoped sub-state (e.g. `processing.fundsPulled`). Always
            present: each status carries a default member (e.g.
            `processing.initiated`) when no more specific value applies.
        customer:
          allOf:
            - $ref: '#/components/schemas/CustomerRef'
          description: The customer that owns this record — the sender on a transaction.
        precursor:
          allOf:
            - $ref: '#/components/schemas/Precursor'
          description: >-
            What created this transaction, as a uniform `{type, id}` reference —
            dereference the resource by `id` for its full record. A
            custodial-wallet deposit renders `{type: walletDeposit}`. Left out
            for a genuine out-of-band arrival with no recognised origin at all;
            the `manual` arm is reserved for a future operator-initiated
            transaction, distinct from either.
        source:
          allOf:
            - $ref: '#/components/schemas/Instrument'
          description: >-
            The funding side, as an instrument. A bank account carries no rail:
            how the money moved is on the transaction's transfers.
        destination:
          allOf:
            - $ref: '#/components/schemas/TransactionDestinationInstrument'
          description: >-
            The receiving side, as an instrument. The rail and the ACH options
            are on the transaction's payout transfer.
        payoutOrigin:
          allOf:
            - $ref: '#/components/schemas/PayoutOrigin'
          description: >-
            Whose name the payout goes out under. Left out when nothing is paid
            out to a bank account, a card or a wallet.
        pricing:
          allOf:
            - $ref: '#/components/schemas/Pricing'
          description: Consolidated economics.
        transfers:
          type: array
          items:
            $ref: '#/components/schemas/TransferRef'
          description: >-
            The transaction's transfers, in creation order: each movement of its
            money on one rail. Left out until the first transfer exists; fetch
            one with `GET /transfers/{transferId}`.
        failure:
          allOf:
            - $ref: '#/components/schemas/Reason'
          description: Why the transaction failed. Present only when `status` is `failed`.
        hold:
          allOf:
            - $ref: '#/components/schemas/Hold'
          description: >-
            What the partner must do while `status` is `awaitingAction`. Left
            out in every other status.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: Free-form key-value pairs supplied at creation or update.
        createdAt:
          type: string
          format: date-time
          description: When the transaction was created.
        updatedAt:
          type: string
          format: date-time
          description: When the transaction was last updated.
      description: >-
        A single movement of money from a source to a destination. Created by
        accepting a quote, or generated automatically by a deposit address,
        virtual account, or cash-in. Track its progress with status.
    TransactionCreateRequest:
      type: object
      required:
        - quoteId
      properties:
        quoteId:
          type: string
          description: >-
            The quote to accept (`qt_` prefix). Must be `open` with non-expired
            pricing.
        deviceFingerprint:
          type: string
          description: 'Device fingerprint of the end user, used for risk screening.'
        webSessionId:
          type: string
          description: >-
            Risk-session identifier generated client-side by the Sardine SDK
            (initialized with the customer's `riskId`). Required when the
            precursor quote's source or destination funding instrument is a
            `card`; ignored otherwise. Missing when required is rejected with
            422 `RiskSessionRequired`.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
      description: >-
        Request body for executing a transaction. References the quote to
        accept; the card and source wallet are taken from that quote. An
        external buy delivers to the quote's destination address when the
        destination is `walletExternal`, and otherwise to the customer's custody
        wallet on the destination chain; with no such address it is rejected
        with 422 `ExternalDeliveryWalletRequired`.
      example:
        quoteId: qt_0gq9aesz4wb5etdv88z1j61qcm
        metadata:
          orderId: order_12345
    TransactionDestination:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletCryptoDestination'
        - $ref: '#/components/schemas/WalletExternalDestination'
        - $ref: '#/components/schemas/WalletFiatDestination'
        - $ref: '#/components/schemas/BankUsDestination'
        - $ref: '#/components/schemas/BankIbanDestination'
        - $ref: '#/components/schemas/BankCanadaDestination'
        - $ref: '#/components/schemas/CardDestination'
        - $ref: '#/components/schemas/CashDestination'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletCryptoDestination'
          walletExternal: '#/components/schemas/WalletExternalDestination'
          walletFiat: '#/components/schemas/WalletFiatDestination'
          bankUs: '#/components/schemas/BankUsDestination'
          bankIban: '#/components/schemas/BankIbanDestination'
          bankCanada: '#/components/schemas/BankCanadaDestination'
          card: '#/components/schemas/CardDestination'
          cash: '#/components/schemas/CashDestination'
      description: >-
        The destination side of a transaction/quote: a typed instrument plus
        `payoutOrigin`. Amounts live only in `pricing`.
    TransactionDestinationInstrument:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletCryptoInstrument'
        - $ref: '#/components/schemas/WalletExternalInstrument'
        - $ref: '#/components/schemas/WalletFiatInstrument'
        - $ref: '#/components/schemas/BankUsAccount'
        - $ref: '#/components/schemas/BankIbanAccount'
        - $ref: '#/components/schemas/BankCanadaAccount'
        - $ref: '#/components/schemas/CardInstrument'
        - $ref: '#/components/schemas/CashPickupInstrument'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletCryptoInstrument'
          walletExternal: '#/components/schemas/WalletExternalInstrument'
          walletFiat: '#/components/schemas/WalletFiatInstrument'
          bankUs: '#/components/schemas/BankUsAccount'
          bankIban: '#/components/schemas/BankIbanAccount'
          bankCanada: '#/components/schemas/BankCanadaAccount'
          card: '#/components/schemas/CardInstrument'
          cash: '#/components/schemas/CashPickupInstrument'
      description: >-
        The receiving side of a transaction: one instrument per account type.
        The rail, the ACH options and where the payout is sent from are on the
        transaction's payout transfer.
    TransactionList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/Transaction'
          description: The page of results.
      description: A paginated list of transactions.
    TransactionNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - TransactionNotFound
        code:
          type: number
          enum:
            - 10231
        msg:
          type: string
          enum:
            - transaction not found
        cause:
          type: string
    TransactionPrecursorType:
      type: string
      enum:
        - quote
        - depositAddress
        - virtualAccount
        - cashIn
        - manual
        - walletDeposit
      description: >-
        The kind of resource that originated a transaction: `quote` for a
        transaction created by accepting a quote, and `depositAddress` /
        `virtualAccount` / `cashIn` for one created automatically by that
        resource. `walletDeposit` covers a custodial-wallet deposit with no
        originating OMS resource; its `id` is always null. `manual` covers a
        transaction with no known origin resource and does not include wallet
        deposits; the `manual` arm (`id: null`) is reserved for a future
        operator-initiated transaction and is not emitted yet.
    TransactionSide:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletCryptoInstrument'
        - $ref: '#/components/schemas/WalletExternalInstrument'
        - $ref: '#/components/schemas/WalletFiatInstrument'
        - $ref: '#/components/schemas/BankUsInstrument'
        - $ref: '#/components/schemas/BankIbanInstrument'
        - $ref: '#/components/schemas/BankCanadaInstrument'
        - $ref: '#/components/schemas/CardInstrument'
        - $ref: '#/components/schemas/CashInstrument'
        - $ref: '#/components/schemas/DepositAddressInstrument'
        - $ref: '#/components/schemas/VirtualAccountInstrument'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletCryptoInstrument'
          walletExternal: '#/components/schemas/WalletExternalInstrument'
          walletFiat: '#/components/schemas/WalletFiatInstrument'
          bankUs: '#/components/schemas/BankUsInstrument'
          bankIban: '#/components/schemas/BankIbanInstrument'
          bankCanada: '#/components/schemas/BankCanadaInstrument'
          card: '#/components/schemas/CardInstrument'
          cash: '#/components/schemas/CashInstrument'
          depositAddress: '#/components/schemas/DepositAddressInstrument'
          virtualAccount: '#/components/schemas/VirtualAccountInstrument'
      description: >-
        A source or destination: one instrument per account type. Amounts live
        in `pricing`.
    TransactionStatus:
      type: string
      enum:
        - processing
        - awaitingAction
        - completed
        - failed
      description: >-
        Lifecycle of a transaction. processing: funds in motion. awaitingAction:
        non-terminal, blocked on developer/upstream/compliance (see `hold`);
        returns to processing once cleared. completed: delivered. failed: the
        payment ended without delivering. Both can still change afterwards: a
        bank can take back money that settled (a returned payout or refund reads
        `processing.underReview`, a returned deposit `failed.returnedToSender`),
        a deposit that failed can still settle (a late provider report or an
        operator redrive), and a return to the sender can start after a failure
        (`processing.returningToSender`).
    TransactionSubStatus:
      type: string
      enum:
        - processing.fundsPulled
        - processing.cashPickupReady
        - processing.underReview
        - processing.payoutRetrying
        - processing.payoutUnconfirmed
        - processing.payoutHeld
        - processing.returningToSender
        - completed.cashPickupCollected
        - completed.cashPickupExpired
        - awaitingAction.informationRequested
        - awaitingAction.awaitingSenderAttribution
        - awaitingAction.payoutDestinationMissing
        - awaitingAction.depositAddressFrozen
        - failed.attributionTimeout
        - failed.depositAddressFrozenTimeout
        - failed.depositAddressInactiveTimeout
        - failed.depositAddressClosed
        - processing.awaitingCryptoOut
        - processing.cryptoOut
        - processing.awaitingFiatOut
        - processing.fiatOut
        - processing.inboundPending
        - processing.inboundProcessing
        - failed.inboundFailed
        - failed.returnedToSender
        - processing.initiated
        - completed.settled
        - failed.unspecified
        - failed.expired
        - failed.providerDeclined
        - failed.outboundFailed
      description: >-
        Granular sub-status in dotted form — the prefix before the dot is always
        the coarse `status`. Required and never null: `processing`, `completed`
        and `failed` each carry a default member (`processing.initiated`,
        `completed.settled`, `failed.unspecified`) emitted when no more specific
        value applies; `failed.unspecified` means the transaction failed with no
        recorded reason. `awaitingAction` has no default member: every
        `awaitingAction.*` value names a specific blocking reason, and the ones
        below pair with the transaction's `hold`:
        `awaitingAction.awaitingSenderAttribution` → `hold.code`
        `senderAttribution`, `awaitingAction.payoutDestinationMissing` →
        `payoutDestinationMissing`. Each value means one thing whichever vendor
        or flow produced it: `processing.payoutRetrying` is a new attempt of a
        payout that failed, `processing.payoutUnconfirmed` is a payout we
        stopped waiting on because the provider never confirmed it,
        `processing.payoutHeld` is a payout the provider accepted and holds
        until the partner's prefunded balance covers it (topping up releases
        it), `processing.returningToSender` is a refund in flight, and
        `processing.underReview` is money we hold while we decide what happens
        next. Neither `processing.payoutUnconfirmed` nor
        `processing.underReview` has a deadline: the transaction stays there
        until the provider answers or we resolve it, and its next
        `transaction.statusChanged` event carries the outcome.
        `failed.returnedToSender` means the money reached the sender again,
        whichever way: we sent the deposit back (crypto or bank), or the bank
        returned the deposit (an ACH or wire return). It never means a payout or
        refund the receiving bank returned: that money comes back to us, and the
        transaction reads `processing.underReview` while we decide what happens
        next. New members may be added without an API version bump, so clients
        MUST tolerate unknown values by falling back to the prefix before the
        dot (the dotted form exists precisely for this). The values below are
        the complete set emitted by this release; a client that validates
        against this list, including one generated from this schema, must be
        updated before it can accept a new member.
    TransactionType:
      type: string
      enum:
        - credit
        - debit
        - hold
        - release
      description: 'Type of account ledger entry: a credit, debit, hold, or release.'
    Transfer:
      type: object
      required:
        - id
        - transactionId
        - role
        - rail
        - attempt
        - status
        - amount
        - from
        - to
        - createdAt
        - updatedAt
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Transfer ID (`trf_` prefix).
        transactionId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: The transaction the transfer belongs to (`txn_` prefix).
        role:
          $ref: '#/components/schemas/TransferRole'
        rail:
          $ref: '#/components/schemas/TransferRail'
        instantRail:
          allOf:
            - $ref: '#/components/schemas/InstantRail'
          description: Only when `rail` is `instant`.
        intraBankRail:
          allOf:
            - $ref: '#/components/schemas/IntraBankRail'
          description: Only when `rail` is `intraBank`.
        attempt:
          type: integer
          format: int32
          description: >-
            1 for the first send; a payout sent again after a confirmed failure
            is a new transfer with `attempt` + 1. These stay the same transfer:
            a re-send of a payout whose outcome is unknown, a failed refund sent
            again, and a fiat wallet payout sent again.
        status:
          $ref: '#/components/schemas/TransferStatus'
        amount:
          $ref: '#/components/schemas/TransferAmount'
        from:
          allOf:
            - $ref: '#/components/schemas/Instrument'
          description: Where the money moved from.
        to:
          allOf:
            - $ref: '#/components/schemas/Instrument'
          description: Where the money moved to.
        secCode:
          allOf:
            - $ref: '#/components/schemas/SecCode'
          description: ACH SEC code the payout was sent with; `ach` and `achSameDay` only.
        companyDiscretionaryData:
          type: string
          description: >-
            ACH company discretionary data the payout was sent with; `ach` and
            `achSameDay` only.
        originatorName:
          type: string
          description: >-
            The name the payout comes from, as the receiving bank sees it: the
            payment provider's, or the customer's when the customer or the
            partner holds the payout origin. Bank and card payouts only; left
            out when the customer's name cannot be read at that moment.
        tracking:
          allOf:
            - $ref: '#/components/schemas/TransferTracking'
          description: Left out until OMS holds a reference.
        failure:
          allOf:
            - $ref: '#/components/schemas/Reason'
          description: Why the transfer failed. Present only when `status` is `failed`.
        return:
          allOf:
            - $ref: '#/components/schemas/Reason'
          description: >-
            Why a bank sent the money back, with its own code in `bankCode` when
            it gave one. Present only when `status` is `returned`.
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        settledAt:
          type: string
          format: date-time
          description: When the transfer settled.
      description: >-
        One movement of money of a transaction, on one rail. A payout sent again
        after a confirmed failure is a new transfer; the failed one stays
        failed.
    TransferAmount:
      type: object
      required:
        - amount
        - asset
      properties:
        amount:
          type: string
          description: Decimal string at the asset's precision.
        asset:
          type: string
          description: Lowercase asset.
      description: The amount a transfer moves.
    TransferNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - TransferNotFound
        code:
          type: number
          enum:
            - 10367
        msg:
          type: string
          enum:
            - transfer not found
        cause:
          type: string
    TransferPairNotPermittedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - TransferPairNotPermitted
        code:
          type: number
          enum:
            - 10012
        msg:
          type: string
          enum:
            - transfer pair not permitted
        cause:
          type: string
    TransferRail:
      type: string
      enum:
        - ach
        - achSameDay
        - wire
        - internationalWire
        - rtp
        - bookTransfer
        - instant
        - intraBank
        - blockchain
        - card
        - cash
      description: >-
        How a transfer's money moved. `instant` is an RTP or FedNow payout,
        named in `instantRail`; `intraBank` stays inside the bank, named in
        `intraBankRail`. A record created before the umbrella names were
        introduced keeps `rtp` or `bookTransfer`.
    TransferRef:
      type: object
      required:
        - id
        - role
        - rail
        - attempt
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Transfer ID (`trf_` prefix).
        role:
          $ref: '#/components/schemas/TransferRole'
        rail:
          $ref: '#/components/schemas/TransferRail'
        instantRail:
          allOf:
            - $ref: '#/components/schemas/InstantRail'
          description: Only when `rail` is `instant`.
        intraBankRail:
          allOf:
            - $ref: '#/components/schemas/IntraBankRail'
          description: Only when `rail` is `intraBank`.
        attempt:
          type: integer
          format: int32
          description: >-
            1 for the first send; a payout sent again after a confirmed failure
            is a new transfer with `attempt` + 1.
      description: A transfer of a transaction.
    TransferRole:
      type: string
      enum:
        - deposit
        - payout
        - refund
      description: >-
        What a transfer does in its transaction. `deposit` brings money in,
        `payout` sends it out and `refund` sends it back to the sender. A bank
        return is the transfer's `returned` status, not a role.
    TransferStatus:
      type: string
      enum:
        - initiated
        - pending
        - settled
        - failed
        - returned
      description: >-
        Where a transfer is. An outgoing transfer (a payout or a refund) goes
        `initiated`, `pending`, `settled`; a deposit goes `pending`, `settled`.
        Any can end `failed`. A payout the receiving bank sends back, or a
        virtual account deposit the sending bank takes back, ends `returned`
        after `settled`.
    TransferTracking:
      type: object
      properties:
        txHash:
          type: string
          description: The on-chain transaction hash.
        imad:
          type: string
          description: The Fedwire input message accountability data.
        uetr:
          type: string
          description: The SWIFT unique end-to-end transaction reference.
        endToEndId:
          type: string
          description: The end-to-end id the rail carries.
        instructionId:
          type: string
          description: The instruction id of an incoming wire.
      description: >-
        Every reference that traces a transfer outside OMS, as soon as OMS holds
        it.
    TransferType:
      type: string
      enum:
        - cryptoToCrypto
        - fiatToCrypto
        - cryptoToFiat
      description: >-
        Direction of value across rails: cryptoToCrypto, fiatToCrypto, or
        cryptoToFiat. Retained for resources not yet on the
        `SourceToDestination` shape (onramp/cash-in, customer filters).
    TransitNumberInvalidErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - TransitNumberInvalid
        code:
          type: number
          enum:
            - 10046
        msg:
          type: string
          enum:
            - transitNumber must be exactly 5 digits
        cause:
          type: string
    TypeUnsupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - TypeUnsupported
        code:
          type: number
          enum:
            - 10020
        msg:
          type: string
          enum:
            - type is not supported
        cause:
          type: string
    UnauthorizedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - Unauthorized
        code:
          type: number
          enum:
            - 1000
        msg:
          type: string
          enum:
            - unauthorized access
        cause:
          type: string
    UnavailableBankDestination:
      type: object
      required:
        - asset
        - network
        - reason
      properties:
        asset:
          type: string
          description: 'Fiat currency, e.g. `usd`.'
        network:
          type: string
          enum:
            - ach
            - achSameDay
            - wire
            - rtp
            - instant
            - intraBank
          description: The rail that cannot be used.
        reason:
          type: string
          enum:
            - notOnInstantRail
            - notWhitelisted
            - useIntraBank
          description: >-
            Why: the bank is not on the instant rails, the account is not on the
            CRNOW whitelist, or the payment stays inside the bank so another
            rail applies.
      description: >-
        A rail the project has turned on that this account cannot be paid over,
        with the reason. A rail the project has not turned on is not listed.
    UnsupportedAssetErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - UnsupportedAsset
        code:
          type: number
          enum:
            - 10151
        msg:
          type: string
          enum:
            - asset is not supported
        cause:
          type: string
    UnsupportedCardBrandErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - UnsupportedCardBrand
        code:
          type: number
          enum:
            - 10061
        msg:
          type: string
          enum:
            - card brand is unsupported
        cause:
          type: string
    UnsupportedCardTypeErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - UnsupportedCardType
        code:
          type: number
          enum:
            - 10064
        msg:
          type: string
          enum:
            - only debit cards are supported
        cause:
          type: string
    UnsupportedCorridorErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - UnsupportedCorridor
        code:
          type: number
          enum:
            - 10085
        msg:
          type: string
          enum:
            - unsupported corridor
        cause:
          type: string
    UnsupportedDestinationErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - UnsupportedDestination
        code:
          type: number
          enum:
            - 10146
        msg:
          type: string
          enum:
            - destination network does not resolve to a supported fiat-out rail
        cause:
          type: string
    UnsupportedInstrumentCombinationErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - UnsupportedInstrumentCombination
        code:
          type: number
          enum:
            - 10148
        msg:
          type: string
          enum:
            - source/destination instrument combination is not supported
        cause:
          type: string
    UnsupportedValueErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - UnsupportedValue
        code:
          type: number
          enum:
            - 10017
        msg:
          type: string
          enum:
            - unsupported value
        cause:
          type: string
    UnsupportedWithdrawalConstraintErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - UnsupportedWithdrawalConstraint
        code:
          type: number
          enum:
            - 10216
        msg:
          type: string
          enum:
            - >-
              partner is not configured for this VA withdrawal rail/vendor
              combination
        cause:
          type: string
    VANotRecoverableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VANotRecoverable
        code:
          type: number
          enum:
            - 10217
        msg:
          type: string
          enum:
            - virtual account status does not allow a destination re-point
        cause:
          type: string
    ValidationErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - Validation
        code:
          type: number
          enum:
            - 10030
        msg:
          type: string
          enum:
            - request validation failed
        cause:
          type: string
    VendorAmbiguousErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VendorAmbiguous
        code:
          type: number
          enum:
            - 10299
        msg:
          type: string
          enum:
            - more than one vendor can serve this request
        cause:
          type: string
    VendorConfigMissingErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VendorConfigMissing
        code:
          type: number
          enum:
            - 10024
        msg:
          type: string
          enum:
            - provider adapter/vendor is not configured for this partner
        cause:
          type: string
    VendorVirtualAccountUnavailableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VendorVirtualAccountUnavailable
        code:
          type: number
          enum:
            - 10302
        msg:
          type: string
          enum:
            - virtual accounts are not yet available for this partner's vendor
        cause:
          type: string
    VersionConflictErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VersionConflict
        code:
          type: number
          enum:
            - 10069
        msg:
          type: string
          enum:
            - counterparty was modified concurrently
        cause:
          type: string
    VirtualAccount:
      type: object
      required:
        - customer
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Virtual Account ID (`va_` prefix).
        customer:
          allOf:
            - $ref: '#/components/schemas/CustomerRef'
          description: The customer that owns this record.
        status:
          allOf:
            - $ref: '#/components/schemas/VirtualAccountStatus'
          description: Current lifecycle status of the virtual account.
        failure:
          allOf:
            - $ref: '#/components/schemas/Reason'
          description: >-
            Why the virtual account failed. Present only when `status` is
            `failed`.
        hold:
          allOf:
            - $ref: '#/components/schemas/Hold'
          description: >-
            What you must do for a virtual account in `inactiveActionRequired`:
            set a new `destination`. Present only in that status.
        depositInstructions:
          allOf:
            - $ref: '#/components/schemas/VirtualAccountInstructions'
          description: >-
            Bank coordinates senders use to deposit into this Virtual Account.
            Left out until the provider has opened the account, so a `pending`
            Virtual Account carries none. Still present while it is `deleting`,
            and left out again once the account has ended, since a `closed`,
            `failed` or `deleted` Virtual Account can no longer receive a
            deposit. Capture it while the account is live if you need it for
            your own records.
        provider:
          type: string
          description: >-
            The institution that issues and custodies this Virtual Account —
            currently "Erebor Bank, N.A." or "Cross River Bank". Assigned by OMS
            from your project's configuration, never supplied by you. Read it
            when you need to tell an end user or a support ticket which
            institution is holding the deposited funds. It is *not* the name a
            payout is sent under, which is the payout transfer's
            `originatorName` and can name a different company. New providers may
            be added, so treat the string as free-form rather than a fixed set.
            Read-only; omitted when OMS cannot determine the institution.
        destination:
          allOf:
            - $ref: '#/components/schemas/VirtualAccountDestination'
          description: >-
            The account deposits are paid out to. A bank account carries no rail
            and no ACH options; they are on `payout`.
        payout:
          allOf:
            - $ref: '#/components/schemas/Payout'
          description: >-
            How a deposit is paid out to a bank or `walletFiat` `destination`:
            the rail and, on `ach` and `achSameDay`, the ACH options. Left out
            for a crypto destination.
        payoutOrigin:
          allOf:
            - $ref: '#/components/schemas/PayoutOrigin'
          description: >-
            Whose name a payout from this Virtual Account goes out under. Left
            out for a `walletFiat` destination or none.
        returnDestination:
          allOf:
            - $ref: '#/components/schemas/VirtualAccountReturnDestination'
          description: >-
            Where inbound fiat is sent back when its payout cannot be completed.
            It carries no rail; a bank return destination's rail is on
            `returnPayout`. Present only when you set one.
        returnPayout:
          allOf:
            - $ref: '#/components/schemas/Payout'
          description: >-
            How a deposit is returned to a bank `returnDestination`: only the
            rail. Left out with no return destination.
        sponsorGas:
          type: boolean
          description: >-
            Whether OMS absorbs the on-chain gas cost for the destination
            delivery. Present only when true, the only value a create or update
            request accepts.
        bankMemo:
          type: string
          description: Wire/ACH memo the customer can include with deposits.
        label:
          type: string
          description: Partner display label.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: Free-form key-value pairs supplied at creation or update.
        createdAt:
          type: string
          format: date-time
          description: When the virtual account was created.
        updatedAt:
          type: string
          format: date-time
          description: When the virtual account was last updated.
        deletionRequestedAt:
          type: string
          format: date-time
          description: When a delete was accepted. Present only after a delete.
      description: >-
        A dedicated bank account number issued for a customer. Inbound fiat
        deposits are automatically converted and delivered to the configured
        destination, creating a transaction per deposit.
    VirtualAccountBankUsSideDetails:
      type: object
      required:
        - id
        - asset
        - network
      properties:
        id:
          type: string
          description: US bank ExternalAccount ID (`ext_` prefix).
        asset:
          type: string
          enum:
            - usd
          description: Canonical asset identifier.
        memo:
          type: string
          allOf:
            - $ref: '#/components/schemas/paymentMemo'
          nullable: true
          description: >-
            Optional payment memo delivered to the beneficiary's bank with the
            payout.


            Honored on these rails, each with its own limit: - `network: "ach"`
            or `"achSameDay"`: carried as the ACH addenda. NACHA characters only
            (uppercase letters, digits, space and `.&()-+=':?@_#%`), max 80. -
            `network: "wire"` or `"rtp"`: ISO 20022 characters only (see the
            `paymentMemo` scalar), max 140. - A `bankIban` or `bankCanada`
            destination on `swift`: ISO 20022, max 140.


            A memo outside its rail's characters or length is rejected with 422.


            On a Quote, the memo is honored only on a `walletFiat`-source quote,
            or on a `walletCrypto`-source quote to a `bankUs` destination; any
            other corridor rejects it. A Virtual Account destination offers no
            `rtp` rail. On a Deposit Address the memo is read when each payout
            is built, so an edit applies only to payouts built after it, never
            to one already sent.


            Where a memo is not honored — a rail with no remittance field, such
            as `bankCanada`'s `local` leg, or a Quote corridor outside the two
            above — a non-empty memo is rejected with 422 `MemoNotSupported`,
            its `cause` carrying `reason=unsupportedRail`, rather than accepted
            and dropped. Sending `null`, omitting the field, or sending only
            whitespace is always accepted and means no memo of your own: the
            payout then carries the memo OMS composes for the rail, if any.
        companyDiscretionaryData:
          type: string
          allOf:
            - $ref: '#/components/schemas/companyDiscretionaryData'
          nullable: true
          description: >-
            Optional ACH-only field for the originator's internal use (NACHA
            batch header). See the companyDiscretionaryData scalar doc. Honored
            only when network is "ach" or "achSameDay"; 422 `MemoNotSupported`
            on "wire" and "rtp", because the field itself is an ACH-only
            concept.
        network:
          type: string
          enum:
            - ach
            - achSameDay
            - wire
          description: Rail to deliver on.
    VirtualAccountBankUsSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - bankUs
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/VirtualAccountBankUsSideDetails'
        amount:
          $ref: '#/components/schemas/decimalString'
      description: >-
        Deliver a Virtual Account payment to a US bank account. RTP is
        deliberately excluded from this standing-destination surface; it is
        available to manual Quotes and Deposit Addresses only.
      title: US bank account
    VirtualAccountCloseRejectedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountCloseRejected
        code:
          type: number
          enum:
            - 10205
        msg:
          type: string
          enum:
            - the provider rejected the close request
        cause:
          type: string
    VirtualAccountCloseUnavailableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountCloseUnavailable
        code:
          type: number
          enum:
            - 10210
        msg:
          type: string
          enum:
            - >-
              the provider's close endpoint is not yet available for this
              account
        cause:
          type: string
    VirtualAccountCreateRequest:
      type: object
      required:
        - customerId
        - source
        - destination
        - type
      properties:
        customerId:
          type: string
          description: Owning customer ID (`cst_` prefix).
        source:
          allOf:
            - $ref: '#/components/schemas/VirtualAccountSource'
          description: Expected inbound bank rail.
        destination:
          allOf:
            - $ref: '#/components/schemas/VirtualAccountDestinationRequest'
          description: >-
            Where to deliver the deposited value — a crypto wallet
            (auto-convert), a bank account (forward onward), or a `walletFiat`
            fiat wallet (hold as a USD balance). An external crypto wallet must
            be a registered External Account; raw addresses are not accepted
            here. `walletCrypto` is available only where the institution issuing
            the Virtual Account custodies wallets itself, and is otherwise
            rejected with 422 `DestinationWalletCryptoNotSupported`. `asset` and
            `network` are validated against the resolved External Account or
            wallet.
        returnDestination:
          allOf:
            - $ref: '#/components/schemas/FiatReturnDestination'
          description: >-
            Optional fiat return destination: where inbound fiat is sent if the
            outbound leg can't be completed. Bank arms only in v1 — `bankUs` /
            `bankIban` / `bankCanada` (network `swift`, USD); `walletFiat` and
            `bankCanada` with network `local` (CAD) are rejected with 422
            `RailNotSupported`.
        type:
          type: string
          description: 'Closed for Alpha: must be "bankUs".'
        sponsorGas:
          type: boolean
          description: >-
            When `true`, OMS absorbs the on-chain gas cost for the destination
            delivery. Only `true` is currently supported.
          default: true
        bankMemo:
          type: string
          description: Optional wire/ACH memo the customer can include.
        label:
          type: string
          description: Partner display label.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
      description: >-
        Create a Virtual Account: the inbound bank rail plus the destination
        that receives the converted funds.
      example:
        customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
        type: bankUs
        source:
          asset: usd
          network: ach
        destination:
          type: walletExternal
          details:
            id: ext_fky491gakzj0dd46qb6whsr2vq
            asset: usdc
            network: ethereum
        sponsorGas: true
        label: Alice USD deposit account
    VirtualAccountCustodialWalletChangeNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountCustodialWalletChangeNotSupported
        code:
          type: number
          enum:
            - 10316
        msg:
          type: string
          enum:
            - >-
              changing the custodial wallet backing a virtual account is not
              supported
        cause:
          type: string
    VirtualAccountDestination:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletCryptoInstrument'
        - $ref: '#/components/schemas/WalletExternalInstrument'
        - $ref: '#/components/schemas/WalletFiatInstrument'
        - $ref: '#/components/schemas/BankUsAccount'
        - $ref: '#/components/schemas/BankIbanAccount'
        - $ref: '#/components/schemas/BankCanadaAccount'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletCryptoInstrument'
          walletExternal: '#/components/schemas/WalletExternalInstrument'
          walletFiat: '#/components/schemas/WalletFiatInstrument'
          bankUs: '#/components/schemas/BankUsAccount'
          bankIban: '#/components/schemas/BankIbanAccount'
          bankCanada: '#/components/schemas/BankCanadaAccount'
      description: 'The destination of a Virtual Account: one instrument per account type.'
    VirtualAccountDestinationRequest:
      type: object
      oneOf:
        - $ref: '#/components/schemas/VirtualAccountBankUsSideRequest'
        - $ref: '#/components/schemas/BankIbanSideRequest'
        - $ref: '#/components/schemas/BankCanadaSideRequest'
        - $ref: '#/components/schemas/WalletCryptoSideRequest'
        - $ref: '#/components/schemas/WalletExternalRegisteredSideRequest'
        - $ref: '#/components/schemas/WalletFiatDestinationRequest'
      discriminator:
        propertyName: type
        mapping:
          bankUs: '#/components/schemas/VirtualAccountBankUsSideRequest'
          bankIban: '#/components/schemas/BankIbanSideRequest'
          bankCanada: '#/components/schemas/BankCanadaSideRequest'
          walletCrypto: '#/components/schemas/WalletCryptoSideRequest'
          walletExternal: '#/components/schemas/WalletExternalRegisteredSideRequest'
          walletFiat: '#/components/schemas/WalletFiatDestinationRequest'
      description: >-
        Where the Virtual Account delivers the deposited value. Pick a `type` —
        `walletCrypto` (an OMS crypto wallet) or `walletExternal` (a registered
        external wallet) to auto-convert inbound fiat to crypto
        (`fiatAccountToCrypto`); a bank account (`bankUs` / `bankIban` /
        `bankCanada`) to auto-forward the inbound USD onward; or `walletFiat` to
        hold the inbound USD as a fiat balance, credited by an internal book
        transfer so the resolved destination instrument reads `network:
        bookTransfer` (both `fiatAccountToFiatAccount`). Same destination shapes
        as Deposit Addresses. Unlike Cash-In, Virtual Accounts require the
        external wallet to be registered — raw unregistered addresses are not
        allowed. `amount` on the chosen arm is not accepted here — the deposited
        value determines what is delivered. A bank destination settles USD only:
        although the shared bank side shape declares `asset: "cad"` and
        `network: "local"` on `bankCanada`, a Virtual Account rejects `cad` with
        422 `DestinationAssetUnsupported` and `local` with 422
        `DestinationNetworkUnsupported`. `walletCrypto` is available only where
        the institution issuing the Virtual Account custodies wallets itself;
        elsewhere it is rejected with 422 `DestinationWalletCryptoNotSupported`,
        and you use `walletExternal` for an externally held wallet. The
        `walletFiat` wallet must belong to the Virtual Account's customer (422
        `WalletCustomerMismatch`), be `active` (422 `WalletNotActive`) and hold
        `usd`, and the internal book-transfer rail must be enabled for your
        project (403 `DestinationRailNotAllowed`).
    VirtualAccountInstructions:
      type: object
      properties:
        bankUs:
          type: array
          items:
            $ref: '#/components/schemas/BankRoutingBlock'
      description: >-
        Virtual Account deposit instructions. bankUs holds the routing blocks a
        sender can use, each listing the rails it accepts in `supportedSources`,
        limited to the incoming rails the partner has enabled.
    VirtualAccountInstrument:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - virtualAccount
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: The virtual account (`va_`).
        asset:
          type: string
          description: Lowercase asset.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/VirtualAccountInstrumentDetails'
      description: A virtual account.
      title: Virtual account
    VirtualAccountInstrumentDetails:
      type: object
      properties:
        bankName:
          type: string
        accountNumberLast4:
          type: string
        routingNumber:
          type: string
      description: >-
        Virtual account details. The full account number is in the virtual
        account's deposit instructions.
    VirtualAccountList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/VirtualAccount'
          description: The page of results.
      description: Paginated list of VirtualAccount resources.
    VirtualAccountNotFoundAtProviderErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountNotFoundAtProvider
        code:
          type: number
          enum:
            - 10327
        msg:
          type: string
          enum:
            - the provider could not find the virtual account being closed
        cause:
          type: string
    VirtualAccountNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountNotFound
        code:
          type: number
          enum:
            - 10200
        msg:
          type: string
          enum:
            - virtual account not found
        cause:
          type: string
    VirtualAccountProviderSetupIncompleteErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountProviderSetupIncomplete
        code:
          type: number
          enum:
            - 10354
        msg:
          type: string
          enum:
            - >-
              virtual account setup at the custodial account provider is
              incomplete for this project
        cause:
          type: string
    VirtualAccountProviderUnavailableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountProviderUnavailable
        code:
          type: number
          enum:
            - 10328
        msg:
          type: string
          enum:
            - the virtual account provider is unavailable
        cause:
          type: string
    VirtualAccountReturnDestination:
      type: object
      oneOf:
        - $ref: '#/components/schemas/BankUsAccount'
        - $ref: '#/components/schemas/BankIbanAccount'
        - $ref: '#/components/schemas/BankCanadaAccount'
        - $ref: '#/components/schemas/WalletFiatInstrument'
      discriminator:
        propertyName: type
        mapping:
          bankUs: '#/components/schemas/BankUsAccount'
          bankIban: '#/components/schemas/BankIbanAccount'
          bankCanada: '#/components/schemas/BankCanadaAccount'
          walletFiat: '#/components/schemas/WalletFiatInstrument'
      description: >-
        The return destination of a Virtual Account: a bank account or a fiat
        wallet.
    VirtualAccountSource:
      type: object
      required:
        - asset
        - network
      properties:
        asset:
          type: string
          description: 'Fixed for Alpha: "usd".'
        network:
          type: string
          description: 'Fixed for Alpha: "usBank".'
      description: >-
        Expected inbound rail for the virtual account: fiat asset and bank
        network.
    VirtualAccountStatus:
      type: string
      enum:
        - pending
        - active
        - frozen
        - closed
        - deleted
        - failed
        - inactiveActionRequired
        - deleting
      description: >-
        Lifecycle of a Virtual Account. pending: awaiting bank provisioning.
        active: accepting deposits. frozen: deposits held by compliance.
        inactiveActionRequired: destination unusable - re-point `destination` to
        recover. deleting: a delete was accepted. closed: permanently disabled.
        deleted: close flow finalized. failed: provisioning failed.
    VirtualAccountUnexpectedCloseStatusErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountUnexpectedCloseStatus
        code:
          type: number
          enum:
            - 10207
        msg:
          type: string
          enum:
            - the provider returned an unexpected account status from close
        cause:
          type: string
    VirtualAccountUpdateCustodialWalletUnavailableErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountUpdateCustodialWalletUnavailable
        code:
          type: number
          enum:
            - 10315
        msg:
          type: string
          enum:
            - >-
              no usable custodial wallet is available for the requested
              destination change
        cause:
          type: string
    VirtualAccountUpdateNotSupportedForVendorErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountUpdateNotSupportedForVendor
        code:
          type: number
          enum:
            - 10313
        msg:
          type: string
          enum:
            - virtual account updates are not yet supported for this vendor
        cause:
          type: string
    VirtualAccountUpdateProvisioningRejectedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountUpdateProvisioningRejected
        code:
          type: number
          enum:
            - 10319
        msg:
          type: string
          enum:
            - the custodial wallet provider rejected this update
        cause:
          type: string
    VirtualAccountUpdateRequest:
      type: object
      properties:
        destination:
          allOf:
            - $ref: '#/components/schemas/VirtualAccountDestinationRequest'
          description: >-
            Re-point the VA destination (walletExternal by registered EA id, a
            bank EA, or a walletFiat fiat wallet — same kind as the current
            destination: a cross-kind switch involving walletFiat is rejected
            with 422 `DestinationTypeSwitchNotSupported`). Re-validated exactly
            like create; walletCrypto is NOT currently supported — 422
            destinationWalletCryptoNotSupported.
        returnDestination:
          allOf:
            - $ref: '#/components/schemas/FiatReturnDestination'
          description: >-
            Re-point or clear the fiat return destination. Re-validated exactly
            like create; an explicit `null` in the JSON body clears a previously
            set return destination.
        sponsorGas:
          type: boolean
          description: >-
            When `true`, OMS absorbs the on-chain gas cost for the destination
            delivery. Only `true` is currently supported; accepted for
            forward-compatibility.
          default: true
        label:
          type: string
          description: Partner display label.
        metadata:
          type: object
          additionalProperties:
            type: string
          description: >-
            Free-form key-value pairs stored on the resource and echoed back on
            reads.
      description: >-
        Partial update payload for a Virtual Account. The patchable fields are
        `destination` (re-point to a different walletExternal or bank target),
        `returnDestination` (re-point or clear the fiat return destination),
        `sponsorGas`, `label`, and `metadata`. Any additional key in the JSON
        body is rejected with 400 by the handler (strict whitelist).


        Re-pointing `destination` to a healthy External Account recovers a VA
        from `inactiveActionRequired` back to `active`; a re-point on an already
        `active` VA updates the target without a status transition.
    VirtualAccountWalletInUseErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - VirtualAccountWalletInUse
        code:
          type: number
          enum:
            - 10312
        msg:
          type: string
          enum:
            - >-
              another virtual account in this project already uses this
              custodial wallet
        cause:
          type: string
    BpnWallet:
      type: object
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Wallet ID.
        object:
          type: string
          enum:
            - wallet
          description: Resource type discriminator. Always "wallet".
        customerId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: The OMS customer that owns this record (`cst_` prefix).
        type:
          allOf:
            - $ref: '#/components/schemas/WalletType'
          description: '`internal` (OMS-managed) or `external` (held outside OMS).'
        asset:
          type: string
          description: Asset held by this wallet.
        chain:
          type: string
          description: Chain the wallet lives on.
        blockchainAsset:
          allOf:
            - $ref: '#/components/schemas/BlockchainAsset'
          description: Resolved asset/network detail for the wallet's asset.
        address:
          type: string
          description: On-chain address of the wallet.
        status:
          allOf:
            - $ref: '#/components/schemas/WalletStatus'
          description: Current lifecycle status of the wallet.
        createdAt:
          type: string
          format: date-time
          description: When the wallet was created.
        updatedAt:
          type: string
          format: date-time
          description: When the wallet was last updated.
      description: >-
        A wallet holding a single asset on one chain for a customer. internal
        wallets are OMS-managed; external wallets are held outside OMS.
    WalletAssetMismatchErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletAssetMismatch
        code:
          type: number
          enum:
            - 10139
        msg:
          type: string
          enum:
            - source wallet asset/network does not match request
        cause:
          type: string
    WalletBalance:
      type: object
      properties:
        data:
          type: object
          properties:
            id:
              allOf:
                - $ref: '#/components/schemas/typeId'
              description: 'Public wallet ID, format `wlt_<typeID>`.'
            customerId:
              allOf:
                - $ref: '#/components/schemas/typeId'
              description: 'Public OMS customer ID, format `cst_<typeID>`.'
            asset:
              type: string
              description: Canonical asset symbol (e.g. "usdc").
            chain:
              type: string
              description: Canonical chain name (e.g. "polygon").
            blockchainAsset:
              allOf:
                - $ref: '#/components/schemas/BlockchainAsset'
              description: On-chain identity for the wallet asset and chain.
            address:
              type: string
              description: On-chain wallet address.
            balance:
              allOf:
                - $ref: '#/components/schemas/signedFixedDecimalString'
              description: >-
                Current balance. Mirrors the provider truthfully — can be
                negative (e.g. an ACH clawback after funds were spent). A
                fixed-point decimal string at the asset's own scale, trailing
                zeros preserved (e.g. `"5.00"` for a two-decimal asset,
                `"5.000000"` for USDC).
            currencyName:
              type: string
              description: Human-readable currency name (e.g. "USD Coin").
            estimatedBalanceValue:
              type: string
              description: >-
                Estimated balance value in the currency requested via the
                `estimatedBalanceCurrencyCode` query param, computed by the
                upstream provider at read time. Defaults to USD when the query
                param is omitted.
            updatedAt:
              type: string
              format: date-time
              description: When the cached OMS-side balance row was last updated.
          description: The balance entry for the wallet.
      description: >-
        The current balance of a single wallet, with its estimated value in the
        requested currency.
    WalletBoundToCustodialFlowErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletBoundToCustodialFlow
        code:
          type: number
          enum:
            - 10317
        msg:
          type: string
          enum:
            - >-
              this wallet's blockchain address is already bound to an active
              custodial deposit address or virtual account and cannot be used
              for this operation
        cause:
          type: string
    WalletClaimStatus:
      type: string
      enum:
        - unclaimed
        - claimed
        - released
      description: >-
        Whether a wallet is presently the inbound wallet a live deposit address
        or virtual account receives into. A deposit address's or virtual
        account's destination wallet is a payout target and is never claimed, so
        it stays listed and can fund a withdrawal. A custodial wallet that is a
        live virtual account's `walletCrypto` destination is therefore not
        claimed, but a second virtual account or a deposit address on it is
        still refused, with `WalletIsVirtualAccountDestination` (virtual
        account) or `coinmeAddressInUseByVirtualAccount` (deposit address)
        naming that virtual account. `unclaimed`: no claim history. `claimed`: a
        live DA or VA currently receives into this wallet. The wallet keeps
        rendering by id, with its balance and transactions, and stays writable,
        but cannot fund a withdrawal and is omitted from the default `GET
        /wallets` page. `released`: a DA or VA claimed this wallet in the past
        and has since released it; any balance the wallet held while claimed is
        unaffected.
    WalletClaimant:
      type: object
      required:
        - type
        - id
      properties:
        type:
          type: string
          enum:
            - depositAddress
            - virtualAccount
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: '`da_...` or `va_...`, matching `type`.'
      description: >-
        What is claiming (or last claimed) the wallet. Always resolves,
        including for a released claim from a since-deleted deposit address or
        virtual account.
    WalletClaimedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletClaimed
        code:
          type: number
          enum:
            - 10357
        msg:
          type: string
          enum:
            - >-
              this wallet is claimed by a live deposit address or virtual
              account and cannot fund a withdrawal while that claim stands
        cause:
          type: string
    WalletCreateRequest:
      type: object
      required:
        - asset
        - chain
      properties:
        asset:
          type: string
          description: Asset the wallet will hold (e.g. `usdc`).
        chain:
          type: string
          description: Chain the wallet lives on.
      description: >-
        Request body for creating a wallet: the asset to hold and the chain it
        lives on.
      example:
        asset: usdc
        chain: ethereum
    WalletCryptoDestination:
      type: object
      required:
        - type
        - asset
        - network
      properties:
        type:
          type: string
          enum:
            - walletCrypto
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The wallet (`wlt_`); an older wallet keeps its original `wlt_<uuid>`
            id. Left out while a deposit's receiving wallet is not resolved yet.
        asset:
          type: string
          description: Lowercase asset.
        network:
          type: string
          description: Lowercase blockchain.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/WalletCryptoInstrumentDetails'
        payoutOrigin:
          $ref: '#/components/schemas/PayoutOrigin'
        companyDiscretionaryData:
          type: string
          description: >-
            Echo of the ACH companyDiscretionaryData supplied on the originating
            request. Null/absent on non-ACH destinations or when not supplied.
      title: OMS wallet
    WalletCryptoInstrument:
      type: object
      required:
        - type
        - asset
        - network
      properties:
        type:
          type: string
          enum:
            - walletCrypto
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The wallet (`wlt_`); an older wallet keeps its original `wlt_<uuid>`
            id. Left out while a deposit's receiving wallet is not resolved yet.
        asset:
          type: string
          description: Lowercase asset.
        network:
          type: string
          description: Lowercase blockchain.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/WalletCryptoInstrumentDetails'
      description: An OMS-custodied crypto wallet.
      title: OMS wallet
    WalletCryptoInstrumentDetails:
      type: object
      properties:
        address:
          type: string
          description: On-chain address.
      description: OMS crypto wallet details.
    WalletCryptoSideDetails:
      type: object
      required:
        - id
        - asset
        - network
      properties:
        id:
          type: string
          description: OMS wallet ID (wlt_ prefix).
        asset:
          type: string
          description: 'Crypto asset. One of: usdc, usdt.'
        network:
          allOf:
            - $ref: '#/components/schemas/CryptoNetwork'
          description: Network identifier.
    WalletCryptoSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - walletCrypto
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/WalletCryptoSideDetails'
        amount:
          $ref: '#/components/schemas/decimalString'
      description: Pull from / deliver to an OMS Multi-Chain Wallet owned by the customer.
      title: OMS wallet
    WalletCustomerMismatchErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletCustomerMismatch
        code:
          type: number
          enum:
            - 10273
        msg:
          type: string
          enum:
            - >-
              destination fiat wallet is not owned by the deposit address
              customer
        cause:
          type: string
    WalletCustomerNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
        - status
      properties:
        error:
          type: string
          enum:
            - CustomerNotFound
        code:
          type: number
          enum:
            - 10001
        msg:
          type: string
          enum:
            - customer not found
        cause:
          type: string
        status:
          type: number
          enum:
            - 404
      description: A customer could not be found within the wallet's project.
    WalletExternalBusinessOnlyErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletExternalBusinessOnly
        code:
          type: number
          enum:
            - 10305
        msg:
          type: string
          enum:
            - external wallet accounts are available to business customers only
        cause:
          type: string
    WalletExternalDestination:
      type: object
      required:
        - type
        - asset
        - network
      properties:
        type:
          type: string
          enum:
            - walletExternal
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          description: Lowercase asset.
        network:
          type: string
          description: Lowercase blockchain.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/WalletExternalInstrumentDetails'
        payoutOrigin:
          $ref: '#/components/schemas/PayoutOrigin'
        companyDiscretionaryData:
          type: string
          description: >-
            Echo of the ACH companyDiscretionaryData supplied on the originating
            request. Null/absent on non-ACH destinations or when not supplied.
      title: External wallet
    WalletExternalIDUnsupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletExternalIDUnsupported
        code:
          type: number
          enum:
            - 10143
        msg:
          type: string
          enum:
            - >-
              a walletExternal destination given by registered external-account
              id (ext_) is supported only on a custodial crypto-to-crypto or
              card-funded fiat-to-crypto route; this route cannot deliver to an
              external wallet
        cause:
          type: string
    WalletExternalInstrument:
      type: object
      required:
        - type
        - asset
        - network
      properties:
        type:
          type: string
          enum:
            - walletExternal
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The external account (`ext_`). Left out for a sender OMS has no
            record of.
        asset:
          type: string
          description: Lowercase asset.
        network:
          type: string
          description: Lowercase blockchain.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        details:
          $ref: '#/components/schemas/WalletExternalInstrumentDetails'
      description: A crypto wallet OMS does not custody.
      title: External wallet
    WalletExternalInstrumentDetails:
      type: object
      properties:
        address:
          type: string
          description: On-chain address.
        custodian:
          type: string
          description: 'Who custodies the wallet, in lowerCamelCase.'
        otherCustodian:
          type: string
          description: The custodian's name when `custodian` is `other`.
        networkFamily:
          $ref: '#/components/schemas/NetworkFamily'
      description: External wallet details.
    WalletExternalRegisteredSideDetails:
      type: object
      required:
        - id
        - asset
        - network
      properties:
        id:
          type: string
          description: Registered ExternalAccount ID (`ext_` prefix). Required.
        asset:
          type: string
          description: 'Crypto asset. One of: usdc, usdt.'
        network:
          allOf:
            - $ref: '#/components/schemas/CryptoNetwork'
          description: Network identifier.
    WalletExternalRegisteredSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - walletExternal
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/WalletExternalRegisteredSideDetails'
        amount:
          $ref: '#/components/schemas/decimalString'
      description: >-
        Deliver to a wallet held outside OMS, by registered ExternalAccount only
        (id-only; raw addresses are not accepted). Used by Virtual Account
        destinations; the raw-address `WalletExternalSideRequest` stays
        quote/transaction-only.
      title: External wallet (registered)
    WalletExternalSideDetails:
      type: object
      required:
        - asset
        - network
      properties:
        id:
          type: string
          description: ExternalAccount ID (`ext_` prefix). One of id/blockchainAddress.
        blockchainAddress:
          type: string
          description: >-
            Raw on-chain address (when not registered). One of
            id/blockchainAddress. For an EVM network the address must be
            all-lowercase, all-uppercase, or a valid EIP-55 checksummed form; an
            inconsistent mixed-case address is rejected as a likely casing typo,
            and the zero address is rejected. Solana/SUI are validated per their
            own network rules.
        asset:
          type: string
          description: 'Crypto asset. One of: usdc, usdt.'
        network:
          allOf:
            - $ref: '#/components/schemas/CryptoNetwork'
          description: Network identifier.
    WalletExternalSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - walletExternal
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/WalletExternalSideDetails'
        amount:
          $ref: '#/components/schemas/decimalString'
      description: >-
        Deliver to a wallet held outside OMS. Provide exactly one of `id` (a
        registered ExternalAccount, `ext_` prefix) or `blockchainAddress` (a raw
        on-chain address). Which form a route accepts depends on its corridor: a
        crypto or `card` source on a route that delivers to external wallets
        takes either; any other route refuses `id` with
        `WalletExternalIDUnsupported`, and a crypto source's `blockchainAddress`
        with `CryptoToCryptoExternalAddressUnsupported`.
      title: External wallet
    WalletFiatDestination:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - walletFiat
        id:
          type: string
          pattern: >-
            ^(wlt_fiat_|[a-z]+_)([0-9a-hjkmnp-tv-z]{26}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$
          description: >-
            The fiat wallet (`wlt_`; an older wallet keeps its original
            `wlt_<uuid>` id, and a `wlt_fiat_` id is also accepted on input).
            Left out on a book-transfer destination until its outbound leg
            exists.
        asset:
          type: string
          enum:
            - usd
          description: Fiat currency of the balance. Only `usd` today.
        network:
          type: string
          enum:
            - bookTransfer
            - intraBank
          description: >-
            On the destination of a virtual account or deposit address
            book-transfer credit: `intraBank`, or `bookTransfer` on a record
            created before the umbrella names were introduced.
        intraBankRail:
          allOf:
            - $ref: '#/components/schemas/IntraBankRail'
          description: Only when `network` is `intraBank`.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
        payoutOrigin:
          $ref: '#/components/schemas/PayoutOrigin'
        companyDiscretionaryData:
          type: string
          description: >-
            Echo of the ACH companyDiscretionaryData supplied on the originating
            request. Null/absent on non-ACH destinations or when not supplied.
      description: >-
        The deposited value held as a fiat balance in the customer's fiat wallet
        (only `usd` today). Credited by an internal book transfer at the partner
        bank, so the resolved instrument reads `network: bookTransfer`.
        Selectable as a Deposit Address or Virtual Account destination; a Quote
        destination cannot be `walletFiat`. The wallet must belong to the
        route's customer (422 `WalletCustomerMismatch`) and be `active` (422
        `WalletNotActive`).
      title: Fiat wallet
    WalletFiatDestinationRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - walletFiat
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/WalletFiatSideDetails'
      description: >-
        Hold the deposited value as a fiat balance in the customer's fiat wallet
        (only `usd` today). Credited by an internal book transfer at the partner
        bank — the resolved destination instrument reads `network:
        bookTransfer`. The wallet must belong to the route's customer (422
        `WalletCustomerMismatch`) and be `active` (422 `WalletNotActive`).
      title: Fiat wallet
    WalletFiatInstrument:
      type: object
      required:
        - type
        - asset
      properties:
        type:
          type: string
          enum:
            - walletFiat
        id:
          type: string
          pattern: >-
            ^(wlt_fiat_|[a-z]+_)([0-9a-hjkmnp-tv-z]{26}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$
          description: >-
            The fiat wallet (`wlt_`; an older wallet keeps its original
            `wlt_<uuid>` id, and a `wlt_fiat_` id is also accepted on input).
            Left out on a book-transfer destination until its outbound leg
            exists.
        asset:
          type: string
          enum:
            - usd
          description: Fiat currency of the balance. Only `usd` today.
        network:
          type: string
          enum:
            - bookTransfer
            - intraBank
          description: >-
            On the destination of a virtual account or deposit address
            book-transfer credit: `intraBank`, or `bookTransfer` on a record
            created before the umbrella names were introduced.
        intraBankRail:
          allOf:
            - $ref: '#/components/schemas/IntraBankRail'
          description: Only when `network` is `intraBank`.
        owner:
          $ref: '#/components/schemas/InstrumentOwner'
      description: >-
        A fiat balance wallet OMS holds for the customer at a partner bank. It
        has no details.
      title: Fiat wallet
    WalletFiatSideDetails:
      type: object
      required:
        - id
        - asset
      properties:
        id:
          type: string
          description: >-
            OMS fiat wallet ID (`wlt_` prefix; a `wlt_fiat_` id is also accepted
            on input).
        asset:
          type: string
          enum:
            - usd
          description: Fiat currency. Only `usd` today.
    WalletFiatSideRequest:
      type: object
      required:
        - type
        - details
      properties:
        type:
          type: string
          enum:
            - walletFiat
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/WalletFiatSideDetails'
        amount:
          $ref: '#/components/schemas/decimalString'
      description: >-
        Pull from / deliver to a fiat balance wallet owned by the customer. No
        `network` — the balance lives on an internal ledger.
      title: Fiat wallet
    WalletInvalidRequestBodyErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
        - status
      properties:
        error:
          type: string
          enum:
            - InvalidRequestBody
        code:
          type: number
          enum:
            - 10091
        msg:
          type: string
          enum:
            - invalid request body
        cause:
          type: string
        status:
          type: number
          enum:
            - 400
        details:
          type: object
          properties:
            field:
              type: string
          required:
            - field
      description: The wallet request body could not be decoded.
    WalletIsVirtualAccountDestinationErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletIsVirtualAccountDestination
        code:
          type: number
          enum:
            - 10372
        msg:
          type: string
          enum:
            - >-
              this custodial wallet is already the destination of another live
              virtual account
        cause:
          type: string
    WalletList:
      type: object
      properties:
        object:
          type: string
          description: Resource type discriminator.
        limit:
          type: integer
          format: int32
          description: >-
            The effective page size applied to this response, after clamping an
            out-of-range or unset requested `limit` into the supported bound.
        hasMore:
          type: boolean
          description: >-
            True when more rows exist beyond this page in the direction of
            travel (forward by default, backward when `endingBefore` was
            supplied).
        nextCursor:
          type: string
          description: >-
            Opaque cursor for the next page. Present when another page can be
            requested; pass it as `startingAfter`. `hasMore=false` signals no
            more pages forward.
        previousCursor:
          type: string
          description: >-
            Opaque cursor pointing at the first item in this page. Present when
            `data` is non-empty, except on a list documented as forward only.
            Pass as `endingBefore` to page backward; when this yields an empty
            response the client is at the start of the list.
        data:
          type: array
          items:
            $ref: '#/components/schemas/WalletResource'
          description: The page of results.
      description: Canonical paginated envelope for the top-level wallet list.
    WalletListHidden:
      type: string
      enum:
        - claimed
      description: >-
        Values `GET /wallets`' `includeHidden` param accepts. `claimed` widens
        the default page to include wallets a live deposit address or virtual
        account currently claims. Omitting the param leaves default listing
        behavior unchanged. Deleted wallets are never listed.
    WalletListOrderBy:
      type: string
      enum:
        - balance
    WalletListOrderDirection:
      type: string
      enum:
        - asc
        - desc
    WalletNotActiveErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletNotActive
        code:
          type: number
          enum:
            - 10274
        msg:
          type: string
          enum:
            - destination fiat wallet is not active
        cause:
          type: string
    WalletNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletNotFound
        code:
          type: number
          enum:
            - 10015
        msg:
          type: string
          enum:
            - fiat wallet not found
        cause:
          type: string
    WalletNotOwnedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletNotOwned
        code:
          type: number
          enum:
            - 10111
        msg:
          type: string
          enum:
            - destination wallet does not belong to this customer
        cause:
          type: string
    WalletOperation:
      type: object
      required:
        - operationId
        - object
        - customerId
        - status
        - pairs
        - createdAt
      properties:
        operationId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Operation ID (`op_` TypeID).
        object:
          type: string
          enum:
            - wallet.operation
          description: Resource type discriminator. Always "wallet.operation".
        customerId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The OMS customer the operation provisions wallets for (`cst_`
            prefix).
        status:
          $ref: '#/components/schemas/WalletOperationStatus'
        pairs:
          type: array
          items:
            $ref: '#/components/schemas/WalletOperationPairStatus'
        walletId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            The provisioned wallet's id (`wlt_` prefix), present once the
            requested pair has completed and the wallet record is visible.
        createdAt:
          type: string
          format: date-time
      description: >-
        The status resource a `202 Accepted` wallet create points at (its
        `Location` header). Project-scoped: an operation is only visible to the
        project that created it. Poll until `status` leaves `pending`; when the
        requested wallet is confirmed, `walletId` carries its id.
    WalletOperationPairState:
      type: string
      enum:
        - pending
        - complete
        - terminal
      description: >-
        Per-pair convergence state on a wallet-provisioning operation.
        `terminal` means the provider durably rejected the pair.
    WalletOperationPairStatus:
      type: object
      required:
        - asset
        - network
        - state
      properties:
        asset:
          type: string
          description: 'Crypto asset (canonical symbol, e.g. "usdc").'
        network:
          type: string
          description: 'Blockchain network (canonical name, e.g. "polygon").'
        state:
          $ref: '#/components/schemas/WalletOperationPairState'
      description: >-
        One asset/network pair being converged by a wallet-provisioning
        operation.
    WalletOperationStatus:
      type: string
      enum:
        - pending
        - complete
        - partial
        - terminal
      description: >-
        Aggregate status of a wallet-provisioning operation. `pending`: at least
        one pair is still converging and automation is active. `partial`: some
        pairs completed, at least one needs an operator. `terminal`: the
        provider durably rejected at least one pair. `complete`: every pair
        confirmed.
    WalletProviderConflictErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
        - status
      properties:
        error:
          type: string
          enum:
            - ProviderRequestFailed
        code:
          type: number
          enum:
            - 10375
        msg:
          type: string
          enum:
            - the provider could not complete the request
        cause:
          type: string
        status:
          type: number
          enum:
            - 409
      description: The provider rejected a conflicting wallet request.
    WalletProviderRateLimitErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
        - status
      properties:
        error:
          type: string
          enum:
            - ProviderRequestFailed
        code:
          type: number
          enum:
            - 10375
        msg:
          type: string
          enum:
            - the provider could not complete the request
        cause:
          type: string
        status:
          type: number
          enum:
            - 429
      description: The provider's wallet request limit was exceeded.
    WalletProviderRejectedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
        - status
      properties:
        error:
          type: string
          enum:
            - ProviderRequestFailed
        code:
          type: number
          enum:
            - 10375
        msg:
          type: string
          enum:
            - the provider could not complete the request
        cause:
          type: string
        status:
          type: number
          enum:
            - 422
      description: The provider rejected the wallet request.
    WalletProvisioningRejectedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletProvisioningRejected
        code:
          type: number
          enum:
            - 10152
        msg:
          type: string
          enum:
            - the custodial wallet provider rejected this wallet create
        cause:
          type: string
    WalletQuoteExpiredErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
        - status
      properties:
        error:
          type: string
          enum:
            - QuoteExpired
        code:
          type: number
          enum:
            - 10077
        msg:
          type: string
          enum:
            - quote has expired
        cause:
          type: string
        status:
          type: number
          enum:
            - 409
      description: The provider quote expired before the wallet request completed.
    WalletRequest:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletRequestCustodial'
        - $ref: '#/components/schemas/WalletRequestNoncustodial'
        - $ref: '#/components/schemas/WalletRequestFiat'
      discriminator:
        propertyName: type
        mapping:
          custodial: '#/components/schemas/WalletRequestCustodial'
          noncustodial: '#/components/schemas/WalletRequestNoncustodial'
          fiat: '#/components/schemas/WalletRequestFiat'
      description: >-
        Create a wallet for a customer. Pick a `type`; the variant-specific
        fields live in `details`. `fiat` and `custodial` are implemented today;
        `noncustodial` is accepted by the discriminator but rejected with 501.
    WalletRequestCustodial:
      type: object
      required:
        - customerId
        - type
        - details
      properties:
        customerId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Owning customer (`cst_` prefix).
        type:
          type: string
          enum:
            - custodial
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/WalletRequestCustodialDetails'
        label:
          type: string
          nullable: true
        metadata:
          type: object
          additionalProperties:
            type: string
      description: Create a custodial crypto wallet. Not yet implemented — returns 501.
      title: Custodial wallet
    WalletRequestCustodialDetails:
      type: object
      required:
        - network
        - asset
      properties:
        network:
          allOf:
            - $ref: '#/components/schemas/CryptoNetwork'
          description: Blockchain network the wallet operates on.
        asset:
          type: string
          description: Crypto asset the custodial wallet holds.
      description: Custodial crypto wallet create request details.
    WalletRequestFiat:
      type: object
      required:
        - customerId
        - type
        - details
      properties:
        customerId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Owning customer (`cst_` prefix).
        type:
          type: string
          enum:
            - fiat
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/WalletRequestFiatDetails'
        label:
          type: string
          nullable: true
        metadata:
          type: object
          additionalProperties:
            type: string
      description: >-
        Create a fiat balance wallet, held for the customer at Erebor Bank, N.A.
        It holds a single fiat currency — only `usd` today; any other asset is
        rejected with 422 `UnsupportedAsset`.
      title: Fiat wallet
      example:
        customerId: cst_vfa0nxw6zvyws9g237jrxn4y7k
        type: fiat
        details:
          asset: usd
    WalletRequestFiatDetails:
      type: object
      required:
        - asset
      properties:
        asset:
          type: string
          enum:
            - usd
          description: Fiat currency the wallet holds. Only `usd` today.
      description: Fiat wallet create request details — the fiat currency to hold.
    WalletRequestNoncustodial:
      type: object
      required:
        - customerId
        - type
        - details
      properties:
        customerId:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: Owning customer (`cst_` prefix).
        type:
          type: string
          enum:
            - noncustodial
          description: Type discriminator.
        details:
          $ref: '#/components/schemas/WalletRequestNoncustodialDetails'
        label:
          type: string
          nullable: true
        metadata:
          type: object
          additionalProperties:
            type: string
      description: Create a noncustodial crypto wallet. Not yet implemented — returns 501.
      title: Non-custodial wallet
    WalletRequestNoncustodialDetails:
      type: object
      required:
        - networkFamily
      properties:
        networkFamily:
          allOf:
            - $ref: '#/components/schemas/NetworkFamily'
          description: >-
            Network family the noncustodial wallet operates on (`evm` or
            `solana`).
      description: Noncustodial crypto wallet create request details.
    WalletResource:
      type: object
      oneOf:
        - $ref: '#/components/schemas/WalletResourceCrypto'
        - $ref: '#/components/schemas/WalletResourceFiat'
      discriminator:
        propertyName: type
        mapping:
          walletCrypto: '#/components/schemas/WalletResourceCrypto'
          walletFiat: '#/components/schemas/WalletResourceFiat'
      description: >-
        A wallet OMS manages for a customer. `type` discriminates the variant:
        `walletCrypto` holds one crypto asset on one network at the custody
        provider ("Coinme Inc." today) and carries `network` and `address`;
        `walletFiat` holds a single fiat currency balance (only `usd` today) on
        an internal ledger at "Erebor Bank, N.A." — no network and no on-chain
        address. There is no noncustodial variant in the response: a request for
        one is rejected with 501 `WalletTypeNotSupported`. Read `type` for logic
        rather than parsing the id. The create request names its variant `fiat`
        or `custodial`.
    WalletResourceBalance:
      type: object
      required:
        - asset
        - network
        - balance
        - estimatedValueUsd
      properties:
        asset:
          type: string
        network:
          type: string
          nullable: true
          description: 'Null for fiat balances — held on an internal ledger, not a network.'
        balance:
          $ref: '#/components/schemas/signedFixedDecimalString'
        estimatedValueUsd:
          $ref: '#/components/schemas/signedFixedDecimalString'
      description: 'One (asset, network) balance entry on a wallet.'
    WalletResourceCrypto:
      type: object
      required:
        - id
        - customer
        - status
        - asset
        - routing
        - provider
        - createdAt
        - updatedAt
        - type
        - network
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            Wallet ID (TypeID; `wlt_` for both crypto and fiat wallets; a
            `wlt_fiat_` id is also accepted on input).
        customer:
          allOf:
            - $ref: '#/components/schemas/CustomerRef'
          description: The customer that owns this record.
        status:
          allOf:
            - $ref: '#/components/schemas/WalletResourceStatus'
          description: Current wire status.
        asset:
          type: string
          description: >-
            The asset the wallet holds, lowercase: a crypto symbol (e.g. `usdc`)
            or a fiat currency (only `usd` today).
        routing:
          allOf:
            - $ref: '#/components/schemas/WalletRouting'
          description: >-
            Claim/routing state: whether a live deposit address or virtual
            account currently receives into this wallet, or has in the past.
            Always present.
        provider:
          type: string
          description: >-
            The legal entity holding this wallet's assets, derived from wallet
            type and asset: `walletCrypto` → "Coinme Inc."; `walletFiat` (usd) →
            "Erebor Bank, N.A.". New providers may be added, so treat the string
            as free-form rather than a fixed set.
        label:
          type: string
          description: The partner-supplied label. Absent when none is set.
        balances:
          type: array
          items:
            $ref: '#/components/schemas/WalletResourceBalance'
        metadata:
          type: object
          additionalProperties:
            type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        type:
          type: string
          enum:
            - walletCrypto
          description: Type discriminator.
        network:
          type: string
          description: >-
            Blockchain network the wallet operates on (canonical name, e.g.
            "polygon").
        address:
          type: string
          description: >-
            On-chain deposit address. Omitted when the provider has not reported
            one yet.
      description: >-
        The `walletCrypto` variant — one crypto asset on one network, held on
        the customer's behalf by the custody provider, currently "Coinme Inc.".
        `address` is the on-chain deposit address and is omitted until the
        provider reports one.
      title: Crypto wallet
    WalletResourceFiat:
      type: object
      required:
        - id
        - customer
        - status
        - asset
        - routing
        - provider
        - createdAt
        - updatedAt
        - type
      properties:
        id:
          allOf:
            - $ref: '#/components/schemas/typeId'
          description: >-
            Wallet ID (TypeID; `wlt_` for both crypto and fiat wallets; a
            `wlt_fiat_` id is also accepted on input).
        customer:
          allOf:
            - $ref: '#/components/schemas/CustomerRef'
          description: The customer that owns this record.
        status:
          allOf:
            - $ref: '#/components/schemas/WalletResourceStatus'
          description: Current wire status.
        asset:
          type: string
          description: >-
            The asset the wallet holds, lowercase: a crypto symbol (e.g. `usdc`)
            or a fiat currency (only `usd` today).
        routing:
          allOf:
            - $ref: '#/components/schemas/WalletRouting'
          description: >-
            Claim/routing state: whether a live deposit address or virtual
            account currently receives into this wallet, or has in the past.
            Always present.
        provider:
          type: string
          description: >-
            The legal entity holding this wallet's assets, derived from wallet
            type and asset: `walletCrypto` → "Coinme Inc."; `walletFiat` (usd) →
            "Erebor Bank, N.A.". New providers may be added, so treat the string
            as free-form rather than a fixed set.
        label:
          type: string
          description: The partner-supplied label. Absent when none is set.
        balances:
          type: array
          items:
            $ref: '#/components/schemas/WalletResourceBalance'
        metadata:
          type: object
          additionalProperties:
            type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        type:
          type: string
          enum:
            - walletFiat
          description: Type discriminator.
      description: >-
        The `walletFiat` variant — a single fiat currency balance (only `usd`
        today) held at a partner bank, currently "Erebor Bank, N.A.". An
        internal ledger balance: no network and no on-chain address.
      title: Fiat wallet
    WalletResourceNotFoundErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletResourceNotFound
        code:
          type: number
          enum:
            - 10373
        msg:
          type: string
          enum:
            - wallet not found
        cause:
          type: string
    WalletResourceStatus:
      type: string
      enum:
        - pending
        - active
        - frozen
        - suspended
        - closed
      description: >-
        `pending`: created, not yet open. `active`: usable. `frozen`: the money
        in it is held for a compliance review. `suspended`: disabled by ops.
        `closed`: permanently closed, never active again.
    WalletRouting:
      type: object
      required:
        - claimStatus
      properties:
        claimStatus:
          $ref: '#/components/schemas/WalletClaimStatus'
        claimedBy:
          allOf:
            - $ref: '#/components/schemas/WalletClaimant'
          description: Absent when `claimStatus` is `unclaimed`.
        claimedAt:
          type: string
          format: date-time
          description: Absent when `claimStatus` is `unclaimed`. Reset on re-claim.
        releasedAt:
          type: string
          format: date-time
          description: Present only when `claimStatus` is `released`. Cleared on re-claim.
      description: >-
        Read-only wallet routing/claim state. Always present, on both the
        `walletFiat` and `walletCrypto` wallet variants.
    WalletStatus:
      type: string
      enum:
        - active
        - suspended
        - frozen
        - closed
    WalletType:
      type: string
      enum:
        - internal
        - external
      description: >-
        Whether a wallet is internal (OMS-managed) or external (held outside
        OMS).
    WalletTypeNotSupportedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WalletTypeNotSupported
        code:
          type: number
          enum:
            - 10150
        msg:
          type: string
          enum:
            - wallet type is not supported
        cause:
          type: string
    WalletUnknownFieldErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
        - status
        - details
      properties:
        error:
          type: string
          enum:
            - UnknownField
        code:
          type: number
          enum:
            - 10092
        msg:
          type: string
          enum:
            - unknown field in request body
        cause:
          type: string
        status:
          type: number
          enum:
            - 400
        details:
          type: object
          properties:
            field:
              type: string
          required:
            - field
      description: The wallet update includes an unknown field.
    WalletUpdateRequest:
      type: object
      properties:
        label:
          type: string
          description: Optional display label. An empty string clears the label.
      description: >-
        Partial update for a wallet (fiat or custodial) — only `label` is
        mutable. Send an empty string to clear an existing label; omit the field
        to leave it unchanged.
    WalletVariant:
      type: string
      enum:
        - custodial
        - noncustodial
        - fiat
      description: Public wallet variants accepted by the top-level wallet list filter.
    WeeklyCountExceededErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WeeklyCountExceeded
        code:
          type: number
          enum:
            - 10225
        msg:
          type: string
          enum:
            - weekly transaction count limit reached
        cause:
          type: string
    WeeklyLimitExceededErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - WeeklyLimitExceeded
        code:
          type: number
          enum:
            - 10222
        msg:
          type: string
          enum:
            - weekly limit exceeded
        cause:
          type: string
    ZeroAddressNotAllowedErrorResponse:
      type: object
      required:
        - error
        - code
        - msg
      properties:
        error:
          type: string
          enum:
            - ZeroAddressNotAllowed
        code:
          type: number
          enum:
            - 10050
        msg:
          type: string
          enum:
            - blockchainAddress must not be the zero (burn) address
        cause:
          type: string
    companyDiscretionaryData:
      type: string
      maxLength: 20
      pattern: '^[A-Z0-9 &\-\.\$*\/#@%]*$'
      description: >-
        Optional field for the originator's internal use, carried verbatim in
        the NACHA batch header. Unlike `memo` it never reaches the beneficiary.
        Supported only on a `bankUs` destination whose `network` is `ach` or
        `achSameDay` — on any other rail, `wire` and `rtp` included, it is
        rejected with 422 `MemoNotSupported`. Uppercase NACHA character set
        (uppercase letters, digits, space and `&-.$/*#@%`), max 20 characters;
        anything else is rejected with 422. Omitted, `null` and whitespace-only
        all count as not supplied.
    decimalString:
      type: string
      description: >-
        Wire-safe decimal string for financial float values (USD amounts,
        percentages).
      x-go-type-import:
        path: github.com/shopspring/decimal
      x-go-type: decimal.Decimal
    fixedDecimalString:
      type: string
      description: Wire-safe decimal string that preserves trailing zeros on the wire.
      x-go-type-import:
        path: github.com/0xPolygon/bpn-lib/numeric
      x-go-type: numeric.FixedDecimalString
    paymentMemo:
      type: string
      maxLength: 140
      pattern: '^[A-Za-z0-9 /?:().,''+\-&=@_#%]*$'
      description: >-
        Customer-supplied payment memo carried to the beneficiary's bank in the
        unstructured remittance-information field.


        Both `pattern` and `maxLength` describe a NORMALIZED memo, not the
        rail's own rule: the server trims surrounding whitespace before
        validating, so a memo that only differs by leading or trailing spaces
        may be accepted even though a local check of the raw string rejects it.
        `pattern` covers every allowed character in a normalized memo and
        `maxLength` is the normalized-length bound. `maxLength` is the ISO 20022
        bound (140), which is what Fedwire, RTP and SWIFT accept; `pattern` is
        the union of the ISO 20022 set (letters, digits, space and `/?:().,'+-`)
        and the NACHA addenda set (uppercase only, no `/`, but `&=@_#%` allowed,
        capped at 80). The two sets overlap without either containing the other,
        so the union accepts characters no single rail does. The per-rail rule
        is enforced server-side and rejects anything outside it with 422.
      x-go-type: string
    signedFixedDecimalString:
      type: string
      description: >-
        Wire-safe decimal string for signed financial values that must ship with
        a fixed scale (trailing zeros preserved). It combines the two guarantees
        the OMS `Customer.totalBalance` fields need at once: the leading minus
        is part of the contract — a fiat balance may be negative after an ACH
        clawback, so consumers render the sign as-is and never clamp to zero —
        and the scale is preserved on the wire (e.g. `"25.00"`, `"-25.00"`,
        `"0.00"`), unlike `signedDecimalString`/`decimal.Decimal`, whose
        `.String()` trims trailing zeros (`"25.00"` → `"25"`). Same underlying
        `numeric.FixedDecimalString` Go type as `fixedDecimalString`; the
        builder is responsible for setting the scale (via `StringFixed`).
      x-go-type-import:
        path: github.com/0xPolygon/bpn-lib/numeric
      x-go-type: numeric.FixedDecimalString
    typeId:
      type: string
      pattern: >-
        ^[a-z]+_([0-9a-hjkmnp-tv-z]{26}|[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$
      description: 'Public TypeID, e.g. `txn_01h455vb4pex5vsknk084sn02q`.'
      x-go-type: string
    ErrorWebrpcEndpoint:
      type: object
      properties:
        error:
          type: string
          example: WebrpcEndpoint
        code:
          type: number
          example: 0
        msg:
          type: string
          example: endpoint error
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorWebrpcRequestFailed:
      type: object
      properties:
        error:
          type: string
          example: WebrpcRequestFailed
        code:
          type: number
          example: -1
        msg:
          type: string
          example: request failed
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorWebrpcBadRoute:
      type: object
      properties:
        error:
          type: string
          example: WebrpcBadRoute
        code:
          type: number
          example: -2
        msg:
          type: string
          example: bad route
        cause:
          type: string
        status:
          type: number
          example: 404
      required:
        - error
        - code
        - msg
        - status
    ErrorWebrpcBadMethod:
      type: object
      properties:
        error:
          type: string
          example: WebrpcBadMethod
        code:
          type: number
          example: -3
        msg:
          type: string
          example: bad method
        cause:
          type: string
        status:
          type: number
          example: 405
      required:
        - error
        - code
        - msg
        - status
    ErrorWebrpcBadRequest:
      type: object
      properties:
        error:
          type: string
          example: WebrpcBadRequest
        code:
          type: number
          example: -4
        msg:
          type: string
          example: bad request
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorWebrpcBadResponse:
      type: object
      properties:
        error:
          type: string
          example: WebrpcBadResponse
        code:
          type: number
          example: -5
        msg:
          type: string
          example: bad response
        cause:
          type: string
        status:
          type: number
          example: 500
      required:
        - error
        - code
        - msg
        - status
    ErrorWebrpcServerPanic:
      type: object
      properties:
        error:
          type: string
          example: WebrpcServerPanic
        code:
          type: number
          example: -6
        msg:
          type: string
          example: server panic
        cause:
          type: string
        status:
          type: number
          example: 500
      required:
        - error
        - code
        - msg
        - status
    ErrorWebrpcInternalError:
      type: object
      properties:
        error:
          type: string
          example: WebrpcInternalError
        code:
          type: number
          example: -7
        msg:
          type: string
          example: internal error
        cause:
          type: string
        status:
          type: number
          example: 500
      required:
        - error
        - code
        - msg
        - status
    ErrorWebrpcClientAborted:
      type: object
      properties:
        error:
          type: string
          example: WebrpcClientAborted
        code:
          type: number
          example: -8
        msg:
          type: string
          example: request aborted by client
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorWebrpcStreamLost:
      type: object
      properties:
        error:
          type: string
          example: WebrpcStreamLost
        code:
          type: number
          example: -9
        msg:
          type: string
          example: stream lost
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorAborted:
      type: object
      properties:
        error:
          type: string
          example: Aborted
        code:
          type: number
          example: 1005
        msg:
          type: string
          example: Request aborted
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorAccessKeyMismatch:
      type: object
      properties:
        error:
          type: string
          example: AccessKeyMismatch
        code:
          type: number
          example: 1102
        msg:
          type: string
          example: Access key mismatch
        cause:
          type: string
        status:
          type: number
          example: 409
      required:
        - error
        - code
        - msg
        - status
    ErrorAccessKeyNotFound:
      type: object
      properties:
        error:
          type: string
          example: AccessKeyNotFound
        code:
          type: number
          example: 1101
        msg:
          type: string
          example: Access key not found
        cause:
          type: string
        status:
          type: number
          example: 401
      required:
        - error
        - code
        - msg
        - status
    ErrorAtLeastOneKey:
      type: object
      properties:
        error:
          type: string
          example: AtLeastOneKey
        code:
          type: number
          example: 1302
        msg:
          type: string
          example: You need at least one Access Key
        cause:
          type: string
        status:
          type: number
          example: 403
      required:
        - error
        - code
        - msg
        - status
    ErrorGeoblocked:
      type: object
      properties:
        error:
          type: string
          example: Geoblocked
        code:
          type: number
          example: 1006
        msg:
          type: string
          example: Geoblocked region
        cause:
          type: string
        status:
          type: number
          example: 451
      required:
        - error
        - code
        - msg
        - status
    ErrorInvalidArgument:
      type: object
      properties:
        error:
          type: string
          example: InvalidArgument
        code:
          type: number
          example: 2001
        msg:
          type: string
          example: Invalid argument
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorInvalidOrigin:
      type: object
      properties:
        error:
          type: string
          example: InvalidOrigin
        code:
          type: number
          example: 1103
        msg:
          type: string
          example: Invalid origin for Access Key
        cause:
          type: string
        status:
          type: number
          example: 403
      required:
        - error
        - code
        - msg
        - status
    ErrorInvalidService:
      type: object
      properties:
        error:
          type: string
          example: InvalidService
        code:
          type: number
          example: 1104
        msg:
          type: string
          example: Service not enabled for Access key
        cause:
          type: string
        status:
          type: number
          example: 403
      required:
        - error
        - code
        - msg
        - status
    ErrorMaxAccessKeys:
      type: object
      properties:
        error:
          type: string
          example: MaxAccessKeys
        code:
          type: number
          example: 1301
        msg:
          type: string
          example: Access keys limit reached
        cause:
          type: string
        status:
          type: number
          example: 403
      required:
        - error
        - code
        - msg
        - status
    ErrorMetadataCallFailed:
      type: object
      properties:
        error:
          type: string
          example: MetadataCallFailed
        code:
          type: number
          example: 3003
        msg:
          type: string
          example: Metadata service call failed
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorMethodNotFound:
      type: object
      properties:
        error:
          type: string
          example: MethodNotFound
        code:
          type: number
          example: 1003
        msg:
          type: string
          example: Method not found
        cause:
          type: string
        status:
          type: number
          example: 404
      required:
        - error
        - code
        - msg
        - status
    ErrorNoDefaultKey:
      type: object
      properties:
        error:
          type: string
          example: NoDefaultKey
        code:
          type: number
          example: 1300
        msg:
          type: string
          example: No default access key found
        cause:
          type: string
        status:
          type: number
          example: 403
      required:
        - error
        - code
        - msg
        - status
    ErrorNotFound:
      type: object
      properties:
        error:
          type: string
          example: NotFound
        code:
          type: number
          example: 3000
        msg:
          type: string
          example: Resource not found
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorPermissionDenied:
      type: object
      properties:
        error:
          type: string
          example: PermissionDenied
        code:
          type: number
          example: 1001
        msg:
          type: string
          example: Permission denied
        cause:
          type: string
        status:
          type: number
          example: 403
      required:
        - error
        - code
        - msg
        - status
    ErrorProjectNotFound:
      type: object
      properties:
        error:
          type: string
          example: ProjectNotFound
        code:
          type: number
          example: 1100
        msg:
          type: string
          example: Project not found
        cause:
          type: string
        status:
          type: number
          example: 401
      required:
        - error
        - code
        - msg
        - status
    ErrorQueryFailed:
      type: object
      properties:
        error:
          type: string
          example: QueryFailed
        code:
          type: number
          example: 2003
        msg:
          type: string
          example: Query failed
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorQuotaExceeded:
      type: object
      properties:
        error:
          type: string
          example: QuotaExceeded
        code:
          type: number
          example: 1200
        msg:
          type: string
          example: Quota exceeded
        cause:
          type: string
        status:
          type: number
          example: 429
      required:
        - error
        - code
        - msg
        - status
    ErrorRateLimit:
      type: object
      properties:
        error:
          type: string
          example: RateLimit
        code:
          type: number
          example: 1201
        msg:
          type: string
          example: Rate limit exceeded
        cause:
          type: string
        status:
          type: number
          example: 429
      required:
        - error
        - code
        - msg
        - status
    ErrorRateLimited:
      type: object
      properties:
        error:
          type: string
          example: RateLimited
        code:
          type: number
          example: 1007
        msg:
          type: string
          example: Rate-limited. Please slow down.
        cause:
          type: string
        status:
          type: number
          example: 429
      required:
        - error
        - code
        - msg
        - status
    ErrorRequestConflict:
      type: object
      properties:
        error:
          type: string
          example: RequestConflict
        code:
          type: number
          example: 1004
        msg:
          type: string
          example: Conflict with target resource
        cause:
          type: string
        status:
          type: number
          example: 409
      required:
        - error
        - code
        - msg
        - status
    ErrorResourceExhausted:
      type: object
      properties:
        error:
          type: string
          example: ResourceExhausted
        code:
          type: number
          example: 2004
        msg:
          type: string
          example: Resource exhausted
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    ErrorSessionExpired:
      type: object
      properties:
        error:
          type: string
          example: SessionExpired
        code:
          type: number
          example: 1002
        msg:
          type: string
          example: Session expired
        cause:
          type: string
        status:
          type: number
          example: 403
      required:
        - error
        - code
        - msg
        - status
    ErrorTimeout:
      type: object
      properties:
        error:
          type: string
          example: Timeout
        code:
          type: number
          example: 1900
        msg:
          type: string
          example: Request timed out
        cause:
          type: string
        status:
          type: number
          example: 408
      required:
        - error
        - code
        - msg
        - status
    ErrorUnauthorized:
      type: object
      properties:
        error:
          type: string
          example: Unauthorized
        code:
          type: number
          example: 1000
        msg:
          type: string
          example: Unauthorized access
        cause:
          type: string
        status:
          type: number
          example: 401
      required:
        - error
        - code
        - msg
        - status
    ErrorUnauthorizedUser:
      type: object
      properties:
        error:
          type: string
          example: UnauthorizedUser
        code:
          type: number
          example: 1105
        msg:
          type: string
          example: Unauthorized user
        cause:
          type: string
        status:
          type: number
          example: 403
      required:
        - error
        - code
        - msg
        - status
    ErrorUnavailable:
      type: object
      properties:
        error:
          type: string
          example: Unavailable
        code:
          type: number
          example: 2002
        msg:
          type: string
          example: Unavailable resource
        cause:
          type: string
        status:
          type: number
          example: 400
      required:
        - error
        - code
        - msg
        - status
    Asset:
      type: object
      properties:
        id:
          type: number
        collectionId:
          type: number
        tokenId:
          type: string
        url:
          type: string
        metadataField:
          type: string
        filename:
          type: string
        filesize:
          type: number
        mimeType:
          type: string
        width:
          type: number
        height:
          type: number
        updatedAt:
          type: string
      required:
        - id
        - collectionId
        - metadataField
    ChainInfo:
      type: object
      properties:
        chainId:
          type: number
        chainName:
          type: string
      required:
        - chainId
        - chainName
    ContractInfo:
      type: object
      properties:
        chainId:
          type: number
        address:
          type: string
        source:
          type: string
        name:
          type: string
        type:
          type: string
        symbol:
          type: string
        decimals:
          type: number
        logoURI:
          type: string
        deployed:
          type: boolean
        bytecodeHash:
          type: string
        extensions:
          $ref: '#/components/schemas/ContractInfoExtensions'
        contentHash:
          type: number
        updatedAt:
          type: string
        queuedAt:
          type: string
        status:
          $ref: '#/components/schemas/ResourceStatus'
      required:
        - chainId
        - address
        - source
        - name
        - type
        - symbol
        - logoURI
        - deployed
        - bytecodeHash
        - extensions
        - contentHash
        - updatedAt
        - status
    ContractInfoExtensionBridgeInfo:
      type: object
      properties:
        tokenAddress:
          type: string
      required:
        - tokenAddress
    ContractInfoExtensionIndexingInfo:
      type: object
      properties:
        useOnChainBalance:
          type: boolean
      required:
        - useOnChainBalance
    ContractInfoExtensions:
      type: object
      properties:
        link:
          type: string
        description:
          type: string
        categories:
          description: '[]string'
          type: array
          items:
            type: string
        bridgeInfo:
          description: 'map<string,ContractInfoExtensionBridgeInfo>'
          type: object
          additionalProperties:
            $ref: '#/components/schemas/ContractInfoExtensionBridgeInfo'
        indexingInfo:
          $ref: '#/components/schemas/ContractInfoExtensionIndexingInfo'
        ogImage:
          type: string
        ogName:
          type: string
        originChainId:
          type: number
        originAddress:
          type: string
        blacklist:
          type: boolean
        verified:
          type: boolean
        verifiedBy:
          type: string
        featured:
          type: boolean
        featureIndex:
          type: number
    ContractType:
      description: Represented as uint8 on the server side
      type: string
      enum:
        - UNKNOWN
        - NATIVE
        - ERC20
        - ERC721
        - ERC1155
        - SEQUENCE_WALLET
        - ERC20_BRIDGE
        - ERC721_BRIDGE
        - ERC1155_BRIDGE
        - SEQ_MARKETPLACE
        - ERC6909
    ContractVerificationStatus:
      description: Represented as string on the server side
      type: string
      enum:
        - VERIFIED
        - UNVERIFIED
        - ALL
    GatewayNativeTokenBalance:
      type: object
      properties:
        chainId:
          type: number
        errorReason:
          type: string
        result:
          $ref: '#/components/schemas/NativeTokenBalance'
      required:
        - chainId
        - result
    GatewayNativeTokenBalances:
      type: object
      properties:
        chainId:
          type: number
        errorReason:
          type: string
        results:
          description: '[]NativeTokenBalance'
          type: array
          items:
            $ref: '#/components/schemas/NativeTokenBalance'
      required:
        - chainId
        - results
    GatewayPrice:
      type: object
      properties:
        chainID:
          type: number
        errorReason:
          type: string
        results:
          description: '[]Price'
          type: array
          items:
            $ref: '#/components/schemas/Price'
      required:
        - chainID
        - results
    GatewayTokenBalance:
      type: object
      properties:
        chainId:
          type: number
        errorReason:
          type: string
        results:
          description: '[]TokenBalance'
          type: array
          items:
            $ref: '#/components/schemas/TokenBalance'
      required:
        - chainId
        - results
    GatewayTokenPriceQuery:
      type: object
      properties:
        chainID:
          type: number
        queries:
          description: '[]TokenPriceQuery'
          type: array
          items:
            $ref: '#/components/schemas/TokenPriceQuery'
      required:
        - chainID
        - queries
    GatewayTransaction:
      type: object
      properties:
        chainId:
          type: number
        errorReason:
          type: string
        results:
          description: '[]Transaction'
          type: array
          items:
            $ref: '#/components/schemas/IndexerTransaction'
      required:
        - chainId
        - results
    MetadataOptions:
      type: object
      properties:
        verifiedOnly:
          type: boolean
        unverifiedOnly:
          type: boolean
        includeContracts:
          description: '[]string'
          type: array
          items:
            type: string
    NativeTokenBalance:
      type: object
      properties:
        accountAddress:
          type: string
        chainId:
          type: number
        name:
          type: string
        symbol:
          type: string
        balance:
          type: string
        balanceUSD:
          type: string
        priceUSD:
          type: string
        priceUpdatedAt:
          type: string
        errorReason:
          type: string
      required:
        - accountAddress
        - chainId
        - name
        - symbol
        - balance
        - balanceUSD
        - priceUSD
    NetworkType:
      description: Represented as uint8 on the server side
      type: string
      enum:
        - MAINNETS
        - TESTNETS
        - ALL
    Page:
      type: object
      properties:
        page:
          type: number
        column:
          type: string
        before:
          type: object
        after:
          type: object
        sort:
          description: '[]SortBy'
          type: array
          items:
            $ref: '#/components/schemas/SortBy'
        pageSize:
          type: number
        more:
          type: boolean
    Price:
      type: object
      properties:
        contractAddress:
          type: string
        tokenID:
          type: string
        priceUSD:
          type: string
        updatedAt:
          type: string
      required:
        - contractAddress
        - priceUSD
    ResourceStatus:
      description: Represented as uint32 on the server side
      type: string
      enum:
        - NOT_AVAILABLE
        - REFRESHING
        - AVAILABLE
    SortBy:
      type: object
      properties:
        column:
          type: string
        order:
          $ref: '#/components/schemas/SortOrder'
      required:
        - column
        - order
    SortOrder:
      description: Represented as uint32 on the server side
      type: string
      enum:
        - DESC
        - ASC
    TokenBalance:
      type: object
      properties:
        contractType:
          $ref: '#/components/schemas/ContractType'
        contractAddress:
          type: string
        accountAddress:
          type: string
        tokenID:
          type: string
        balance:
          type: string
        balanceUSD:
          type: string
        priceUSD:
          type: string
        priceUpdatedAt:
          type: string
        blockHash:
          type: string
        blockNumber:
          type: number
        chainId:
          type: number
        uniqueCollectibles:
          type: string
        isSummary:
          type: boolean
        contractInfo:
          $ref: '#/components/schemas/ContractInfo'
        tokenMetadata:
          $ref: '#/components/schemas/TokenMetadata'
      required:
        - contractType
        - contractAddress
        - accountAddress
        - balance
        - balanceUSD
        - priceUSD
        - blockHash
        - blockNumber
        - chainId
        - uniqueCollectibles
        - isSummary
    TokenBalancesByContractFilter:
      type: object
      properties:
        contractAddresses:
          description: '[]string'
          type: array
          items:
            type: string
        accountAddresses:
          description: '[]string'
          type: array
          items:
            type: string
        contractStatus:
          $ref: '#/components/schemas/ContractVerificationStatus'
        tokenIDs:
          description: '[]string'
          type: array
          items:
            type: string
      required:
        - contractAddresses
    TokenBalancesFilter:
      type: object
      properties:
        accountAddresses:
          description: '[]string'
          type: array
          items:
            type: string
        contractStatus:
          $ref: '#/components/schemas/ContractVerificationStatus'
        contractTypes:
          description: '[]string'
          type: array
          items:
            type: string
        contractWhitelist:
          description: '[]string'
          type: array
          items:
            type: string
        contractBlacklist:
          description: '[]string'
          type: array
          items:
            type: string
        omitNativeBalances:
          type: boolean
        omitPrices:
          type: boolean
        tokenIDs:
          description: '[]string'
          type: array
          items:
            type: string
      required:
        - accountAddresses
        - omitNativeBalances
    TokenMetadata:
      type: object
      properties:
        chainId:
          type: number
        contractAddress:
          type: string
        tokenId:
          type: string
        source:
          type: string
        name:
          type: string
        description:
          type: string
        image:
          type: string
        video:
          type: string
        audio:
          type: string
        properties:
          description: 'map<string,any>'
          type: object
          additionalProperties:
            type: object
        attributes:
          description: '[]map<string,any>'
          type: array
          items:
            type: object
            description: 'map<string,any>'
            additionalProperties:
              type: object
        imageData:
          type: string
        externalUrl:
          type: string
        backgroundColor:
          type: string
        animationUrl:
          type: string
        decimals:
          type: number
        updatedAt:
          type: string
        assets:
          description: '[]Asset'
          type: array
          items:
            $ref: '#/components/schemas/Asset'
        status:
          $ref: '#/components/schemas/ResourceStatus'
        queuedAt:
          type: string
        lastFetched:
          type: string
      required:
        - tokenId
        - source
        - name
        - attributes
        - status
    TokenPriceQuery:
      type: object
      properties:
        contractAddress:
          type: string
        tokenID:
          type: string
      required:
        - contractAddress
    IndexerTransaction:
      type: object
      properties:
        txnHash:
          type: string
        blockNumber:
          type: number
        blockHash:
          type: string
        chainId:
          type: number
        metaTxnID:
          type: string
        transfers:
          description: '[]TxnTransfer'
          type: array
          items:
            $ref: '#/components/schemas/TxnTransfer'
        timestamp:
          type: string
      required:
        - txnHash
        - blockNumber
        - blockHash
        - chainId
        - timestamp
    TransactionHistoryFilter:
      type: object
      properties:
        accountAddress:
          type: string
        contractAddress:
          type: string
        accountAddresses:
          description: '[]string'
          type: array
          items:
            type: string
        contractAddresses:
          description: '[]string'
          type: array
          items:
            type: string
        transactionHashes:
          description: '[]string'
          type: array
          items:
            type: string
        metaTransactionIDs:
          description: '[]string'
          type: array
          items:
            type: string
        fromBlock:
          type: number
        toBlock:
          type: number
        tokenID:
          type: string
        omitPrices:
          type: boolean
    TxnTransfer:
      type: object
      properties:
        transferType:
          $ref: '#/components/schemas/TxnTransferType'
        contractAddress:
          type: string
        contractType:
          $ref: '#/components/schemas/ContractType'
        from:
          type: string
        to:
          type: string
        tokenIds:
          description: '[]string'
          type: array
          items:
            type: string
        amounts:
          description: '[]string'
          type: array
          items:
            type: string
        logIndex:
          type: number
        amountsUSD:
          description: '[]string'
          type: array
          items:
            type: string
        pricesUSD:
          description: '[]string'
          type: array
          items:
            type: string
        contractInfo:
          $ref: '#/components/schemas/ContractInfo'
        tokenMetadata:
          description: 'map<string,TokenMetadata>'
          type: object
          additionalProperties:
            $ref: '#/components/schemas/TokenMetadata'
        txnIndex:
          type: number
      required:
        - transferType
        - contractAddress
        - contractType
        - from
        - to
        - amounts
        - logIndex
        - txnIndex
    TxnTransferType:
      description: Represented as uint32 on the server side
      type: string
      enum:
        - UNKNOWN
        - SEND
        - RECEIVE
    IndexerGateway_GetBalanceUpdates_Request:
      type: object
      properties:
        chainIds:
          description: '[]uint64'
          type: array
          items:
            type: number
        networks:
          description: '[]string'
          type: array
          items:
            type: string
        networkType:
          $ref: '#/components/schemas/NetworkType'
        contractAddress:
          type: string
        lastBlockNumber:
          type: number
        lastBlockHash:
          type: string
        page:
          $ref: '#/components/schemas/Page'
    IndexerGateway_GetChains_Request:
      type: object
      properties:
        networkType:
          $ref: '#/components/schemas/NetworkType'
    IndexerGateway_GetNativeTokenBalance_Request:
      type: object
      properties:
        chainIds:
          description: '[]uint64'
          type: array
          items:
            type: number
        networks:
          description: '[]string'
          type: array
          items:
            type: string
        networkType:
          $ref: '#/components/schemas/NetworkType'
        accountAddress:
          type: string
        omitPrices:
          type: boolean
    IndexerGateway_GetTokenBalances_Request:
      type: object
      properties:
        chainIds:
          description: '[]uint64'
          type: array
          items:
            type: number
        networks:
          description: '[]string'
          type: array
          items:
            type: string
        networkType:
          $ref: '#/components/schemas/NetworkType'
        accountAddress:
          type: string
        contractAddress:
          type: string
        tokenID:
          type: string
        includeMetadata:
          type: boolean
        metadataOptions:
          $ref: '#/components/schemas/MetadataOptions'
        includeCollectionTokens:
          type: boolean
        page:
          $ref: '#/components/schemas/Page'
    IndexerGateway_GetTokenBalancesByContract_Request:
      type: object
      properties:
        chainIds:
          description: '[]uint64'
          type: array
          items:
            type: number
        networks:
          description: '[]string'
          type: array
          items:
            type: string
        networkType:
          $ref: '#/components/schemas/NetworkType'
        filter:
          $ref: '#/components/schemas/TokenBalancesByContractFilter'
        omitMetadata:
          type: boolean
        page:
          $ref: '#/components/schemas/Page'
    IndexerGateway_GetTokenBalancesDetails_Request:
      type: object
      properties:
        chainIds:
          description: '[]uint64'
          type: array
          items:
            type: number
        networks:
          description: '[]string'
          type: array
          items:
            type: string
        networkType:
          $ref: '#/components/schemas/NetworkType'
        filter:
          $ref: '#/components/schemas/TokenBalancesFilter'
        omitMetadata:
          type: boolean
        page:
          $ref: '#/components/schemas/Page'
    IndexerGateway_GetTokenBalancesSummary_Request:
      type: object
      properties:
        chainIds:
          description: '[]uint64'
          type: array
          items:
            type: number
        networks:
          description: '[]string'
          type: array
          items:
            type: string
        networkType:
          $ref: '#/components/schemas/NetworkType'
        filter:
          $ref: '#/components/schemas/TokenBalancesFilter'
        omitMetadata:
          type: boolean
        page:
          $ref: '#/components/schemas/Page'
    IndexerGateway_GetTokenPrice_Request:
      type: object
      properties:
        q:
          $ref: '#/components/schemas/GatewayTokenPriceQuery'
    IndexerGateway_GetTokenPrices_Request:
      type: object
      properties:
        q:
          description: '[]GatewayTokenPriceQuery'
          type: array
          items:
            $ref: '#/components/schemas/GatewayTokenPriceQuery'
    IndexerGateway_GetTransactionHistory_Request:
      type: object
      properties:
        chainIds:
          description: '[]uint64'
          type: array
          items:
            type: number
        networks:
          description: '[]string'
          type: array
          items:
            type: string
        networkType:
          $ref: '#/components/schemas/NetworkType'
        filter:
          $ref: '#/components/schemas/TransactionHistoryFilter'
        includeMetadata:
          type: boolean
        metadataOptions:
          $ref: '#/components/schemas/MetadataOptions'
        page:
          $ref: '#/components/schemas/Page'
    IndexerGateway_GetBalanceUpdates_Response:
      type: object
      properties:
        page:
          $ref: '#/components/schemas/Page'
        balances:
          description: '[]GatewayTokenBalance'
          type: array
          items:
            $ref: '#/components/schemas/GatewayTokenBalance'
    IndexerGateway_GetChains_Response:
      type: object
      properties:
        chains:
          description: '[]ChainInfo'
          type: array
          items:
            $ref: '#/components/schemas/ChainInfo'
    IndexerGateway_GetNativeTokenBalance_Response:
      type: object
      properties:
        balances:
          description: '[]GatewayNativeTokenBalance'
          type: array
          items:
            $ref: '#/components/schemas/GatewayNativeTokenBalance'
    IndexerGateway_GetTokenBalances_Response:
      type: object
      properties:
        page:
          $ref: '#/components/schemas/Page'
        balances:
          description: '[]GatewayTokenBalance'
          type: array
          items:
            $ref: '#/components/schemas/GatewayTokenBalance'
    IndexerGateway_GetTokenBalancesByContract_Response:
      type: object
      properties:
        page:
          $ref: '#/components/schemas/Page'
        balances:
          description: '[]GatewayTokenBalance'
          type: array
          items:
            $ref: '#/components/schemas/GatewayTokenBalance'
    IndexerGateway_GetTokenBalancesDetails_Response:
      type: object
      properties:
        page:
          $ref: '#/components/schemas/Page'
        nativeBalances:
          description: '[]GatewayNativeTokenBalances'
          type: array
          items:
            $ref: '#/components/schemas/GatewayNativeTokenBalances'
        balances:
          description: '[]GatewayTokenBalance'
          type: array
          items:
            $ref: '#/components/schemas/GatewayTokenBalance'
    IndexerGateway_GetTokenBalancesSummary_Response:
      type: object
      properties:
        page:
          $ref: '#/components/schemas/Page'
        nativeBalances:
          description: '[]GatewayNativeTokenBalances'
          type: array
          items:
            $ref: '#/components/schemas/GatewayNativeTokenBalances'
        balances:
          description: '[]GatewayTokenBalance'
          type: array
          items:
            $ref: '#/components/schemas/GatewayTokenBalance'
    IndexerGateway_GetTokenPrice_Response:
      type: object
      properties:
        price:
          $ref: '#/components/schemas/GatewayPrice'
    IndexerGateway_GetTokenPrices_Response:
      type: object
      properties:
        prices:
          description: '[]GatewayPrice'
          type: array
          items:
            $ref: '#/components/schemas/GatewayPrice'
    IndexerGateway_GetTransactionHistory_Response:
      type: object
      properties:
        page:
          $ref: '#/components/schemas/Page'
        transactions:
          description: '[]GatewayTransaction'
          type: array
          items:
            $ref: '#/components/schemas/GatewayTransaction'
    SolanaIndexerTokenBalancesFilter:
      type: object
      properties:
        accountAddresses:
          description: '[]string'
          type: array
          items:
            type: string
        omitNativeBalances:
          type: boolean
        contractWhitelist:
          description: '[]string'
          type: array
          items:
            type: string
        contractBlacklist:
          description: '[]string'
          type: array
          items:
            type: string
      required:
        - accountAddresses
    Balance:
      type: object
      properties:
        network:
          type: string
        accountAddress:
          type: string
        assetType:
          type: string
        tokenProgram:
          type: string
        mintAddress:
          type: string
        name:
          type: string
        symbol:
          type: string
        decimals:
          type: number
        balance:
          type: string
        formattedBalance:
          type: string
        imageUrl:
          type: string
        metadataUri:
          type: string
        verificationStatus:
          type: string
        verificationSource:
          type: string
        priceUSD:
          type: string
        balanceUSD:
          type: string
      required:
        - network
        - accountAddress
        - assetType
        - name
        - symbol
        - decimals
        - balance
        - formattedBalance
        - verificationStatus
        - verificationSource
    NetworkError:
      type: object
      properties:
        network:
          type: string
        reason:
          type: string
      required:
        - network
        - reason
    SolanaIndexerGateway_GetTokenBalancesDetails_Request:
      type: object
      properties:
        networks:
          description: '[]string'
          type: array
          items:
            type: string
        filter:
          $ref: '#/components/schemas/SolanaIndexerTokenBalancesFilter'
        omitMetadata:
          type: boolean
    SolanaIndexerGateway_GetTokenBalancesDetails_Response:
      type: object
      properties:
        balances:
          description: '[]Balance'
          type: array
          items:
            $ref: '#/components/schemas/Balance'
        errors:
          description: '[]NetworkError'
          type: array
          items:
            $ref: '#/components/schemas/NetworkError'
    TronIndexerTokenBalancesFilter:
      type: object
      properties:
        accountAddresses:
          description: '[]string'
          type: array
          items:
            type: string
        omitNativeBalances:
          type: boolean
        contractWhitelist:
          description: '[]string'
          type: array
          items:
            type: string
        contractBlacklist:
          description: '[]string'
          type: array
          items:
            type: string
      required:
        - accountAddresses
    TronIndexerBalance:
      type: object
      properties:
        network:
          type: string
        accountAddress:
          type: string
        assetType:
          type: string
        contractAddress:
          type: string
        tokenStandard:
          type: string
        name:
          type: string
        symbol:
          type: string
        decimals:
          type: number
        balance:
          type: string
        formattedBalance:
          type: string
        imageUrl:
          type: string
        metadataUri:
          type: string
        verificationStatus:
          type: string
        verificationSource:
          type: string
        priceUSD:
          type: string
        balanceUSD:
          type: string
      required:
        - network
        - accountAddress
        - assetType
        - name
        - symbol
        - decimals
        - balance
        - formattedBalance
        - verificationStatus
        - verificationSource
    BalanceError:
      type: object
      properties:
        network:
          type: string
        accountAddress:
          type: string
        operation:
          type: string
        contractAddress:
          type: string
        code:
          type: string
        reason:
          type: string
      required:
        - network
        - accountAddress
        - operation
        - code
        - reason
    Coverage:
      type: object
      properties:
        network:
          type: string
        tokenSymbols:
          description: '[]string'
          type: array
          items:
            type: string
        nativeIncluded:
          type: boolean
      required:
        - network
        - tokenSymbols
        - nativeIncluded
    TronIndexerGateway_GetTokenBalancesDetails_Request:
      type: object
      properties:
        networks:
          description: '[]string'
          type: array
          items:
            type: string
        filter:
          $ref: '#/components/schemas/TronIndexerTokenBalancesFilter'
        omitMetadata:
          type: boolean
    TronIndexerGateway_GetTokenBalancesDetails_Response:
      type: object
      properties:
        balances:
          description: '[]Balance'
          type: array
          items:
            $ref: '#/components/schemas/TronIndexerBalance'
        errors:
          description: '[]BalanceError'
          type: array
          items:
            $ref: '#/components/schemas/BalanceError'
        coverage:
          $ref: '#/components/schemas/Coverage'
        coverages:
          description: '[]Coverage'
          type: array
          items:
            $ref: '#/components/schemas/Coverage'
  parameters:
    IdempotencyKey:
      name: Idempotency-Key
      in: header
      required: true
      schema:
        type: string
        maxLength: 256
      description: Client-supplied request key. Required on all non-auth POST requests.
      example: ord_123_attempt_1
    IdempotencyKeyHeader:
      name: Idempotency-Key
      in: header
      required: true
      description: >-
        Required on POST and PUT requests. Use a unique value per logical
        mutation attempt, for example a UUID.
      schema:
        type: string
    PaginationParams.endingBefore:
      name: endingBefore
      in: query
      required: false
      schema:
        type: string
    PaginationParams.limit:
      name: limit
      in: query
      required: false
      description: >-
        Page size, supported range 1-100. The default and maximum are
        per-resource (see each endpoint's description; most endpoints default to
        50) and are resolved at runtime from configuration. Values outside the
        range are clamped to the nearest bound rather than rejected. The range
        is published machine-readably via the `x-minimum`/`x-maximum` OpenAPI
        extensions below — deliberately NOT via `@minValue`/`@maxValue`, which
        emit JSON-Schema `minimum`/`maximum` and make the generated SDK (Zod)
        reject values the server accepts and clamps. See `PaginatedList.limit`
        for the effective value applied.
      schema:
        type: integer
        format: int32
      x-maximum: 100
      x-minimum: 1
    PaginationParams.startingAfter:
      name: startingAfter
      in: query
      required: false
      schema:
        type: string
  securitySchemes:
    PublishableKey:
      type: apiKey
      in: header
      name: Api-Key
    CustomerTokenAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Short-lived customer-bound token with the omsx-customer-token audience.
    PublishableKeyAuth:
      type: apiKey
      in: header
      name: Api-Key
    BearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: Token from POST /auth/token
