> ## Documentation Index
> Fetch the complete documentation index at: https://public-openfx.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Retrieve a payout address

> Retrieve a full `PayoutAddress`, including its `verifications[]` and the `status` derived from them.



## OpenAPI

````yaml api-reference/openapi-v3-payments.json GET /v3/payments/payout-addresses/{payoutAddressId}
openapi: 3.1.0
info:
  title: 'OpenFX v3: Payouts & Accounts API'
  version: 3.0.0
  contact:
    name: OpenFX Support
    email: support@openfx.com
    url: https://www.openfx.com
  license:
    name: Proprietary — © OpenFX. All rights reserved.
    url: https://www.openfx.com/terms-and-conditions
  description: >-
    One reference for paying out to your accounts on OpenFX v3. It covers the

    accounts you pay, the payout addresses they own, and the payouts you send
    them.

    An account carries its identity and a `status`, its standing with OpenFX as
    a whole.

    Each payout address holds the routable identifiers its country requires, and

    carries the acts the platform ran against it in `verifications[]`; its own
    `status`

    reports whether the address can back a payout. A payout is priced by a
    quote, created in

    `REQUIRES_CONFIRMATION`, confirmed, and then settled. See the

    [Payout flow](/v3/payouts) guide for the full payout state machine

    and the webhooks emitted at each step.


    **Core concepts.** [Authentication](/v3/authentication), for the token every
    request

    carries. [Idempotency keys](/v3/idempotency), for the header every write
    carries.

    [Metadata](/v3/metadata-and-tracing#withdrawal-metadata), for the object of
    your own key/value strings you attach when

    creating a record. [Pagination](/v3/pagination), for the cursors every list
    returns.

    [Identifiers](/v3/resource-ids), for the typed-prefix ids every resource
    carries.

    [Webhook delivery](/v3/webhooks/setup), for the signed deliveries and their
    retry window.

    [Rate limiting](/v3/rate-limiting), for the per-organization limit and the
    headers that report it.


    **Responses.** Reads and writes both return `{ data }`; lists return `{
    data, pagination }`.

    Every error returns `{ error }` with a stable `code` and a coarse `type`;
    branch on

    `error.code` or `error.type`, never on `error.message`. Every error `code`
    is

    registered under exactly one status; see `ErrorType`'s `CONFLICT` entry for
    the one

    exception.


    **Conventions.** Request bodies must be `application/json` (UTF-8), and
    unrecognized fields

    are rejected rather than silently dropped. An id belonging to another
    organization returns

    `404`, indistinguishable from one that never existed. An unknown route
    returns

    `404 ROUTE_NOT_FOUND`; a known route called with the wrong method returns

    `405 METHOD_NOT_ALLOWED` with an `Allow` header.


    **Forward compatibility.** The API evolves additively: new optional request
    fields, new

    response fields, new members on open enums, and new error codes can ship
    without a version

    bump. Keep a default branch on `error.code`/`error.type` and tolerate
    unrecognized enum

    values. Only removing or renaming a field, tightening a type, or changing a
    status mapping

    is a breaking change.
servers:
  - url: https://api.openfx.com
    description: Production gateway.
security:
  - bearerAuth: []
    requestSignature: []
tags:
  - name: Accounts
    description: >-
      The people and companies you send payouts to.


      An account is one identity, with one or more payout addresses they can be
      paid at.
  - name: Accounts webhooks
    description: >-
      Deliveries for an account's own lifecycle and its capabilities: creation,
      its

      `status` transitions, and each capability cell's request and settle
      events.


      `data` carries the account without its `identity` block, which is never
      delivered

      to a webhook endpoint; read it from GET /v3/common/accounts/{accountId}.


      See [Webhook authentication](/v3/webhooks/authentication) for the signing
      formula

      and how to verify a delivery.
  - name: Addresses
    description: >-
      The destinations an account can be paid at: bank accounts.


      A payout address is typed by its routing shape rather than by a region:
      `bankAccount`

      is discriminated on `routingFamily`, which selects the identifiers that
      route to it,

      an IBAN for `SEPA`, an account number and a BIC for `SWIFT`, and the
      Indian identifier set

      for `IN_LOCAL`. The response reports

      a derived `country` read off those identifiers, and `supportedRails`
      follows the

      routing family together with the identifiers supplied under it.


      Each address carries `verifications[]`, the acts the platform ran against
      it. A name

      match runs when the address is created wherever the scheme that pays it
      offers one,

      comparing the asserted `accountHolderName` with the name the receiving
      institution

      has registered; an account only SWIFT can reach has no such scheme, so its

      `verifications[]` stays empty. Its `status` is derived from those acts
      together

      with the platform's own setup, and says whether it can be paid right now.


      The record is immutable apart from archiving, so correcting anything on it
      means creating

      a replacement and archiving the old one.
  - name: Addresses webhooks
    description: >-
      Deliveries for a payout address's own lifecycle: creation, its `status`

      transitions, and each name-match verification's outcome.


      `data` carries the address without `bankAccount`, and each verification
      act

      without its `providedName` and `registeredName` strings; none of the three
      is

      ever delivered to a webhook endpoint. Read them from

      GET /v3/payments/payout-addresses/{payoutAddressId}.


      See [Webhook authentication](/v3/webhooks/authentication) for the signing
      formula

      and how to verify a delivery.
  - name: Payouts
    description: >-
      Payout quotes, payout creation, confirmation, and lifecycle.


      Every payout here is outbound: it debits one of your own financial
      accounts and credits

      the receiving account's payout address.


      A quote is an immutable, time-bounded FX price snapshot. Apply its id as
      `quoteId` on a

      payout to lock in its rate before it expires. A payout is created in

      `REQUIRES_CONFIRMATION` with no funds moved, carrying every entry in
      `confirmations[]` it

      will ever carry; POST .../confirm acknowledges them all atomically and
      moves funds.
  - name: Payouts webhooks
    description: >-
      Deliveries for a payout's own lifecycle: creation, then one per status
      transition

      from `REQUIRES_CONFIRMATION` through to a terminal state.


      `data` carries the payout with each name-bearing confirmation entry
      stripped of

      its `providedName` and `registeredName` strings, which are never delivered
      to a

      webhook endpoint; read them from GET /v3/payments/payouts/{payoutId}.


      See [Webhook authentication](/v3/webhooks/authentication) for the signing
      formula

      and how to verify a delivery.
  - name: Financial accounts
    description: >-
      The financial accounts your organization funds payouts from.


      A financial account is one of your own balances with OpenFX, held in a
      single currency.

      Every payout debits one, named by `financialAccountId`. This endpoint
      lists the financial

      accounts that can currently source a payout settling in a given
      `receiveCurrency`.
  - name: Changelog
  - name: Authentication
  - name: Idempotency keys
  - name: Metadata
  - name: Pagination
  - name: Identifiers
  - name: Webhook delivery
  - name: Rate limiting
  - name: Payout flow
  - name: EUR payout integration guide
  - name: INR payout integration guide
  - name: Working with capabilities
  - name: Capability requirements
  - name: Account, capability and payout address lifecycle
  - name: Request signing
  - name: Webhook handling
paths:
  /v3/payments/payout-addresses/{payoutAddressId}:
    get:
      tags:
        - Addresses
      summary: Retrieve a payout address
      description: >-
        Retrieve a full `PayoutAddress`, including its `verifications[]` and the
        `status` derived from them.
      operationId: getPayoutAddress
      parameters:
        - $ref: '#/components/parameters/XAppMode'
        - $ref: '#/components/parameters/XRequestId'
        - in: path
          name: payoutAddressId
          schema:
            type: string
            description: >-
              Payout address id (`pytadd_`). A legacy bare UUID (no prefix) is
              also accepted on this read endpoint for backward compatibility
              with v2 identifiers; any other malformed or unrecognized-prefix
              value is rejected as a validation error.
          required: true
          description: >-
            Payout address id (`pytadd_`). A legacy bare UUID (no prefix) is
            also accepted on this read endpoint for backward compatibility with
            v2 identifiers; any other malformed or unrecognized-prefix value is
            rejected as a validation error.
      responses:
        '200':
          description: The requested payout address.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/PayoutAddress'
                required:
                  - data
                additionalProperties: false
              examples:
                sepaIbanOnly:
                  summary: SEPA bank account, no BIC
                  value:
                    data:
                      object: payoutAddress
                      id: pytadd_PbDQ126YUAbkNrNX6XbGL
                      payoutAddressType: BANK_ACCOUNT
                      accountId: acc_BMY3UenpGBn8ZQ8hio4BgE
                      bankAccount:
                        routingFamily: SEPA
                        accountHolderName: Novalia Handels GmbH
                        accountNumber: DE89370400440532013000
                        country: DE
                      supportedCurrencies:
                        - EUR
                      supportedRails:
                        - SEPA
                      status: ACTIVE
                      verifications:
                        - kind: NAME_MATCH
                          mode: SEPA_VOP
                          result: MATCH
                          providedName: Novalia Handels GmbH
                          registeredName: Novalia Handels GmbH
                          createdAt: '2026-06-04T10:30:00.000Z'
                          verifiedAt: '2026-06-04T10:31:20.000Z'
                          expiresAt: null
                      archivedAt: null
                      createdAt: '2026-06-04T10:30:00.000Z'
                      updatedAt: '2026-06-04T10:31:20.000Z'
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-Request-Timestamp:
              $ref: '#/components/headers/XRequestTimestamp'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
        '400':
          description: >-
            A malformed path parameter fails as VALIDATION_PATH_FAILED. Every
            request is also checked for a well-formed gateway context:
            MISSING_REQUEST_CONTEXT / INVALID_ORGANIZATION.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                VALIDATION_PATH_FAILED:
                  value:
                    error:
                      code: VALIDATION_PATH_FAILED
                      type: VALIDATION_ERROR
                      message: >-
                        A path parameter does not match the id grammar its route
                        expects. Correct the id in the request path and
                        resubmit.
                      retryStrategy: FIX_AND_RESUBMIT
                      details:
                        issues:
                          - path: /payoutId
                            code: invalid_string
                            message: is not a well-formed payout id
                        firstIssuePath: /payoutId
                MISSING_REQUEST_CONTEXT:
                  value:
                    error:
                      code: MISSING_REQUEST_CONTEXT
                      type: VALIDATION_ERROR
                      message: >-
                        The organization, user, or idempotency context every
                        request carries was absent or unreadable. Send the
                        request through the documented gateway.
                      retryStrategy: FIX_AND_RESUBMIT
                      details: {}
                INVALID_ORGANIZATION:
                  value:
                    error:
                      code: INVALID_ORGANIZATION
                      type: VALIDATION_ERROR
                      message: >-
                        The organization identifier on the request is malformed.
                        Send the request through the documented gateway.
                      retryStrategy: FIX_AND_RESUBMIT
                      details: {}
                INVALID_APP_MODE:
                  value:
                    error:
                      code: INVALID_APP_MODE
                      type: VALIDATION_ERROR
                      message: >-
                        The x-app-mode header is invalid. When present, it must
                        be either 'LIVE' or 'SANDBOX'.
                      retryStrategy: FIX_AND_RESUBMIT
                      details:
                        received: PRODUCTION
                        allowed:
                          - LIVE
                          - SANDBOX
                validation_header_failed:
                  summary: VALIDATION_HEADER_FAILED
                  value:
                    error:
                      code: VALIDATION_HEADER_FAILED
                      type: VALIDATION_ERROR
                      message: >-
                        The X-Request-Id header is invalid. When present, it
                        must be 1-200 characters using only letters, digits,
                        '-', '_', and '.'.
                      retryStrategy: FIX_AND_RESUBMIT
                      details:
                        issues:
                          - path: X-Request-Id
                            code: invalid_format
                            message: >-
                              The X-Request-Id header is invalid. When present,
                              it must be 1-200 characters using only letters,
                              digits, '-', '_', and '.'.
                        firstIssuePath: X-Request-Id
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-Request-Timestamp:
              $ref: '#/components/headers/XRequestTimestamp'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
        '401':
          description: >-
            Authentication failed: the bearer token or the request signature did
            not verify.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                AUTH_TOKEN_MISSING:
                  value:
                    error:
                      code: AUTH_TOKEN_MISSING
                      type: AUTHENTICATION_ERROR
                      message: No Authorization header was present on the request.
                      retryStrategy: TERMINAL
                      details: {}
                AUTH_TOKEN_INVALID:
                  value:
                    error:
                      code: AUTH_TOKEN_INVALID
                      type: AUTHENTICATION_ERROR
                      message: >-
                        The bearer JWT or its request signature failed
                        verification, whether from a bad or missing signature or
                        a reused nonce.
                      retryStrategy: TERMINAL
                      details: {}
                AUTH_TOKEN_EXPIRED:
                  value:
                    error:
                      code: AUTH_TOKEN_EXPIRED
                      type: AUTHENTICATION_ERROR
                      message: The JWT's exp claim is already in the past.
                      retryStrategy: TERMINAL
                      details: {}
                AUTH_TOKEN_INVALID_CONFIG:
                  value:
                    error:
                      code: AUTH_TOKEN_INVALID_CONFIG
                      type: AUTHENTICATION_ERROR
                      message: >-
                        The JWT was minted with exp more than 60 seconds after
                        iat, or another claim outside the required shape.
                      retryStrategy: TERMINAL
                      details: {}
                AUTH_API_KEY_INVALID:
                  value:
                    error:
                      code: AUTH_API_KEY_INVALID
                      type: AUTHENTICATION_ERROR
                      message: >-
                        The API key behind the token has been revoked or no
                        longer exists.
                      retryStrategy: TERMINAL
                      details: {}
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-Request-Timestamp:
              $ref: '#/components/headers/XRequestTimestamp'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
        '404':
          description: >-
            No payout address with this id is visible to your organization:
            PAYOUT_ADDRESS_NOT_FOUND.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                PAYOUT_ADDRESS_NOT_FOUND:
                  value:
                    error:
                      code: PAYOUT_ADDRESS_NOT_FOUND
                      type: NOT_FOUND
                      message: No payout address with that id in this organization.
                      retryStrategy: TERMINAL
                      details: {}
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-Request-Timestamp:
              $ref: '#/components/headers/XRequestTimestamp'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
        '429':
          description: >-
            Rate limit exceeded. Wait `Retry-After` seconds before retrying, or
            compute the wait from `RateLimit-Reset` (also a duration in
            seconds).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                RATE_LIMIT_EXCEEDED:
                  value:
                    error:
                      code: RATE_LIMIT_EXCEEDED
                      type: RATE_LIMITED
                      message: Rate limit exceeded. Retry after the indicated wait.
                      retryStrategy: WAIT_THEN_RETRY_SAME_KEY
                      details: {}
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-Request-Timestamp:
              $ref: '#/components/headers/XRequestTimestamp'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
            Retry-After:
              $ref: '#/components/headers/RetryAfter'
        '500':
          description: An unexpected error occurred on our side.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                INTERNAL_ERROR:
                  value:
                    error:
                      code: INTERNAL_ERROR
                      type: INTERNAL_ERROR
                      message: >-
                        An unexpected error occurred. Check the state of the
                        resource before retrying writes; for reads, retry with
                        backoff. Contact the support desk if the failure
                        persists.
                      retryStrategy: CHECK_STATE_THEN_RETRY
                      details: {}
          headers:
            X-Trace-Id:
              $ref: '#/components/headers/XTraceId'
            X-Request-Timestamp:
              $ref: '#/components/headers/XRequestTimestamp'
            RateLimit-Limit:
              $ref: '#/components/headers/RateLimitLimit'
            RateLimit-Reset:
              $ref: '#/components/headers/RateLimitReset'
components:
  parameters:
    XAppMode:
      in: header
      name: X-App-Mode
      schema:
        default: SANDBOX
        example: SANDBOX
        description: >-
          Which environment this request runs against.


          An omitted header means `SANDBOX`. Send it explicitly on every call
          rather than relying

          on that default, so live money movement is never missed because a
          header was forgotten: a live API key that reaches a live instance
          without an explicit LIVE value is rejected with
          AUTH_API_KEY_SANDBOX_REQUIRED. When present, the value must be
          `SANDBOX` or `LIVE`, matched without regard to case. Any other value,
          including an empty one, returns `400` `INVALID_APP_MODE`;
          `details.received` echoes the value you sent.
        type: string
        enum:
          - SANDBOX
          - LIVE
      description: >-
        Which environment this request runs against.


        An omitted header means `SANDBOX`. Send it explicitly on every call
        rather than relying

        on that default, so live money movement is never missed because a header
        was forgotten: a live API key that reaches a live instance without an
        explicit LIVE value is rejected with AUTH_API_KEY_SANDBOX_REQUIRED. When
        present, the value must be `SANDBOX` or `LIVE`, matched without regard
        to case. Any other value, including an empty one, returns `400`
        `INVALID_APP_MODE`; `details.received` echoes the value you sent.
    XRequestId:
      in: header
      name: X-Request-Id
      schema:
        example: 9f2c1b7e-4d3a-4f81-9c2e-6b0a5d7e1f34
        description: >-
          Your own correlation id for this request, returned on the response
          exactly as you sent it.


          Optional. Where you send none the response omits it, and the
          `X-Trace-Id` response

          header is the handle to correlate on instead.
        type: string
      description: >-
        Your own correlation id for this request, returned on the response
        exactly as you sent it.


        Optional. Where you send none the response omits it, and the
        `X-Trace-Id` response

        header is the handle to correlate on instead.
  schemas:
    PayoutAddress:
      type: object
      properties:
        object:
          type: string
          const: payoutAddress
          description: >-
            The type of object represented, a fixed discriminator. Always
            `"payoutAddress"` for this resource, and identical across every
            object of the type.
          example: payoutAddress
        id:
          $ref: '#/components/schemas/PayoutAddressId'
          description: Payout address identifier.
          example: pytadd_PbDQ126YUAbkNrNX6XbGL
        supportedCurrencies:
          type: array
          items:
            $ref: '#/components/schemas/CurrencyCode'
          description: >-
            The currencies and tokens this destination can receive.


            New entries may be added additively, so tolerate an unrecognized
            value.
          example:
            - USD
        supportedRails:
          type: array
          items:
            $ref: '#/components/schemas/Rail'
          description: >-
            The rails this destination can be paid over, following
            `routingFamily` and the

            identifiers supplied with it.


            New rails may be added additively, so tolerate an unrecognized
            value.
          example:
            - SEPA
        status:
          $ref: '#/components/schemas/PayoutAddressStatus'
        verifications:
          type: array
          items:
            $ref: '#/components/schemas/Verification'
          description: >-
            What the platform has established about this destination.


            Holds the current act for each verification kind and mode, not a
            history: a repeat act

            replaces the entry it supersedes on the wire, while the full history
            is retained

            internally. At most one entry today: a name match, where a scheme
            runs one at setup, and

            it is the itemized input to `status`.


            A new verification kind would ship as a new variant, so tolerate an
            unrecognized `kind`.

            See `Verification`.
        archivedAt:
          anyOf:
            - $ref: '#/components/schemas/Timestamp'
            - type: 'null'
          description: >-
            When the client retired this payout address, or null while it is
            live.


            Set by POST /v3/payments/payout-addresses/{payoutAddressId}/archive
            and terminal once set: a repeat

            call leaves the timestamp unchanged. Archiving deletes nothing, so
            the address and every

            reference to it stay retrievable by id, but an archived address is
            hidden from

            `listPayoutAddresses` by default and cannot back new payouts.
          example: '2026-06-04T10:30:00.000Z'
        createdAt:
          $ref: '#/components/schemas/Timestamp'
          description: Creation timestamp.
          example: '2026-06-04T10:30:00.000Z'
        updatedAt:
          $ref: '#/components/schemas/Timestamp'
          description: Last-update timestamp.
          example: '2026-06-04T10:30:00.000Z'
        payoutAddressType:
          type: string
          const: BANK_ACCOUNT
        accountId:
          $ref: '#/components/schemas/AccountId'
          description: >-
            The account this payout address belongs to.


            Immutable once set, and an id rather than an inlined record: fetch

            GET /v3/common/accounts/{accountId} for the account's own identity
            data.
          example: acc_BMY3UenpGBn8ZQ8hio4BgE
        label:
          description: Human-friendly label. Cosmetic.
          example: Operating account
          type: string
        metadata:
          $ref: '#/components/schemas/Metadata'
        bankAccount:
          $ref: '#/components/schemas/BankAccount'
          description: Where this bank account is, and how a payout is routed to it.
      required:
        - object
        - id
        - supportedCurrencies
        - supportedRails
        - status
        - verifications
        - archivedAt
        - createdAt
        - updatedAt
        - payoutAddressType
        - accountId
        - bankAccount
      additionalProperties: false
      description: >-
        A registered destination an account can be paid at. Carries
        `bankAccount`, the routable

        identifiers of the destination.


        The record is immutable apart from archiving. There is no update
        operation, so correcting

        anything on it means creating a replacement and archiving this one.
    ErrorEnvelope:
      type: object
      description: >-
        The error body of every non-2xx response.


        All fields are always present. Every code and message here is OpenFX's
        own: a failed read

        collapses to `INTERNAL_ERROR`, and a failed write carries a domain code
        plus the affected

        resource id, so the client can GET the resource and decide whether to
        retry.
      required:
        - error
      additionalProperties: false
      properties:
        error:
          type: object
          description: The structured public error payload.
          required:
            - code
            - type
            - message
            - retryStrategy
            - details
          additionalProperties: false
          properties:
            code:
              $ref: '#/components/schemas/ErrorCode'
            type:
              $ref: '#/components/schemas/ErrorType'
            message:
              type: string
              description: >-
                Human-readable explanation. Not a stability contract, wording
                may change at any time; branch on `code`, never `message`.
              example: No account with that id in this organization.
            retryStrategy:
              $ref: '#/components/schemas/RetryStrategy'
            details:
              anyOf:
                - $ref: '#/components/schemas/ErrorDetailsACCOUNT_ARCHIVED'
                - $ref: '#/components/schemas/ErrorDetailsACCOUNT_HOLDER_MISMATCH'
                - $ref: '#/components/schemas/ErrorDetailsACCOUNT_NOT_ACTIVE'
                - $ref: '#/components/schemas/ErrorDetailsACCOUNT_NOT_FOUND'
                - $ref: >-
                    #/components/schemas/ErrorDetailsADDRESS_SERVES_NO_CAPABILITY
                - $ref: '#/components/schemas/ErrorDetailsAGREEMENTS_NOT_ACTIVE'
                - $ref: '#/components/schemas/ErrorDetailsAGREEMENTS_PENDING'
                - $ref: '#/components/schemas/ErrorDetailsAMOUNT_OUT_OF_RANGE'
                - $ref: '#/components/schemas/ErrorDetailsAUTH_API_KEY_INVALID'
                - $ref: '#/components/schemas/ErrorDetailsAUTH_API_KEY_LIVE_REQUIRED'
                - $ref: '#/components/schemas/ErrorDetailsAUTH_API_KEY_MISSING'
                - $ref: >-
                    #/components/schemas/ErrorDetailsAUTH_API_KEY_SANDBOX_REQUIRED
                - $ref: '#/components/schemas/ErrorDetailsAUTH_FORBIDDEN_IP'
                - $ref: '#/components/schemas/ErrorDetailsAUTH_INSUFFICIENT_SCOPE'
                - $ref: '#/components/schemas/ErrorDetailsAUTH_TOKEN_EXPIRED'
                - $ref: '#/components/schemas/ErrorDetailsAUTH_TOKEN_INVALID'
                - $ref: '#/components/schemas/ErrorDetailsAUTH_TOKEN_INVALID_CONFIG'
                - $ref: '#/components/schemas/ErrorDetailsAUTH_TOKEN_MISSING'
                - $ref: '#/components/schemas/ErrorDetailsBANK_ACCOUNT_NOT_FOUND'
                - $ref: '#/components/schemas/ErrorDetailsBENEFICIARY_DETAILS_MISSING'
                - $ref: '#/components/schemas/ErrorDetailsCAPABILITY_DUPLICATE'
                - $ref: '#/components/schemas/ErrorDetailsCAPABILITY_NOT_ACTIVE'
                - $ref: '#/components/schemas/ErrorDetailsCURRENCY_NOT_SUPPORTED'
                - $ref: '#/components/schemas/ErrorDetailsFEATURE_NOT_ENABLED'
                - $ref: >-
                    #/components/schemas/ErrorDetailsFINANCIAL_ACCOUNT_CURRENCY_MISMATCH
                - $ref: '#/components/schemas/ErrorDetailsFINANCIAL_ACCOUNT_NOT_FOUND'
                - $ref: '#/components/schemas/ErrorDetailsIDEMPOTENCY_IN_FLIGHT'
                - $ref: '#/components/schemas/ErrorDetailsIDEMPOTENCY_KEY_INVALID'
                - $ref: '#/components/schemas/ErrorDetailsIDEMPOTENCY_KEY_MISSING'
                - $ref: '#/components/schemas/ErrorDetailsIDEMPOTENCY_MISMATCH'
                - $ref: '#/components/schemas/ErrorDetailsIDEMPOTENCY_UNAVAILABLE'
                - $ref: '#/components/schemas/ErrorDetailsIDENTITY_REQUIREMENT_UNMET'
                - $ref: '#/components/schemas/ErrorDetailsINTERNAL_ERROR'
                - $ref: '#/components/schemas/ErrorDetailsINVALID_ORGANIZATION'
                - $ref: '#/components/schemas/ErrorDetailsKYC_REQUIRED'
                - $ref: '#/components/schemas/ErrorDetailsMETHOD_NOT_ALLOWED'
                - $ref: '#/components/schemas/ErrorDetailsMISSING_REQUEST_CONTEXT'
                - $ref: '#/components/schemas/ErrorDetailsPAYOUT_ADDRESS_ARCHIVED'
                - $ref: '#/components/schemas/ErrorDetailsPAYOUT_ADDRESS_CONFLICT'
                - $ref: >-
                    #/components/schemas/ErrorDetailsPAYOUT_ADDRESS_FIELD_MISSING
                - $ref: '#/components/schemas/ErrorDetailsPAYOUT_ADDRESS_NOT_FOUND'
                - $ref: '#/components/schemas/ErrorDetailsPAYOUT_ADDRESS_REJECTED'
                - $ref: >-
                    #/components/schemas/ErrorDetailsPAYOUT_ADDRESS_VERIFICATION_FAILED
                - $ref: >-
                    #/components/schemas/ErrorDetailsPAYOUT_CANCELLATION_NOT_ALLOWED
                - $ref: >-
                    #/components/schemas/ErrorDetailsPAYOUT_CONFIRMATION_NOT_ALLOWED
                - $ref: '#/components/schemas/ErrorDetailsPAYOUT_CURRENCY_NOT_ENABLED'
                - $ref: '#/components/schemas/ErrorDetailsPAYOUT_INSUFFICIENT_FUNDS'
                - $ref: '#/components/schemas/ErrorDetailsPAYOUT_NOT_ENABLED'
                - $ref: '#/components/schemas/ErrorDetailsPAYOUT_NOT_FOUND'
                - $ref: >-
                    #/components/schemas/ErrorDetailsPAYOUT_TEMPORARILY_UNAVAILABLE
                - $ref: '#/components/schemas/ErrorDetailsPURPOSE_INVALID'
                - $ref: '#/components/schemas/ErrorDetailsQUOTE_ALREADY_CONSUMED'
                - $ref: '#/components/schemas/ErrorDetailsQUOTE_EXPIRED'
                - $ref: '#/components/schemas/ErrorDetailsQUOTE_NOT_FOUND'
                - $ref: '#/components/schemas/ErrorDetailsQUOTE_RAIL_UNAVAILABLE'
                - $ref: '#/components/schemas/ErrorDetailsQUOTE_REJECTED'
                - $ref: >-
                    #/components/schemas/ErrorDetailsQUOTE_SEND_CURRENCY_UNAVAILABLE
                - $ref: >-
                    #/components/schemas/ErrorDetailsQUOTE_TEMPORARILY_UNAVAILABLE
                - $ref: '#/components/schemas/ErrorDetailsRATE_LIMIT_EXCEEDED'
                - $ref: '#/components/schemas/ErrorDetailsRECEIVER_MEMO_INVALID'
                - $ref: '#/components/schemas/ErrorDetailsROUTE_NOT_FOUND'
                - $ref: '#/components/schemas/ErrorDetailsSANDBOX_MODE_REQUIRED'
                - $ref: '#/components/schemas/ErrorDetailsINVALID_APP_MODE'
                - $ref: '#/components/schemas/ErrorDetailsSENDER_ACCOUNT_REQUIRED'
                - $ref: '#/components/schemas/ErrorDetailsSENDER_NOT_SUPPORTED'
                - $ref: '#/components/schemas/ErrorDetailsVALIDATION_BODY_FAILED'
                - $ref: '#/components/schemas/ErrorDetailsVALIDATION_PATH_FAILED'
                - $ref: '#/components/schemas/ErrorDetailsVALIDATION_QUERY_FAILED'
                - $ref: >-
                    #/components/schemas/ErrorDetailsVERIFICATION_EXECUTION_FAILED
                - $ref: '#/components/schemas/ErrorDetailsUNSUPPORTED_MEDIA_TYPE'
                - $ref: '#/components/schemas/ErrorDetailsVALIDATION_HEADER_FAILED'
                - $ref: >-
                    #/components/schemas/ErrorDetailsVALIDATION_PAYLOAD_TOO_LARGE
              description: >-
                Additional, code-specific context. `{}`-shaped
                (EmptyErrorDetails) when empty, never null, never omitted.
    PayoutAddressId:
      type: string
      pattern: ^pytadd_[1-9A-HJ-NP-Za-km-z]{21,22}$
      description: >-
        A typed-prefix Base58 identifier, matching
        `^pytadd_[1-9A-HJ-NP-Za-km-z]{21,22}$`: the 3 to 6

        letter lowercase type prefix `pytadd_` followed by the Base58 encoding
        of a UUID.


        See [Identifiers](/v3/resource-ids) for the prefix table, the case
        rules, and the three

        places a pattern is deliberately not enforced.
    CurrencyCode:
      type: string
      pattern: ^[A-Z0-9]{2,15}$
      description: >-
        Uppercase currency code, matching `^[A-Z0-9]{2,15}$`.


        ISO 4217 for fiat; the canonical ticker for stablecoins (`USDC`,
        `USDT`). Case-sensitive,

        so a code is written in the exact case its standard gives it.
    Rail:
      type: string
      enum:
        - SEPA
        - SWIFT
        - IMPS
        - NEFT
        - RTGS
        - SPEI
        - CO_ACH
        - BREB
        - AE_LOCAL
      x-enum-descriptions:
        SEPA: >-
          Euro-area credit transfer, EUR only. Selected by a roster check on the
          destination IBAN's country at creation, then a per-IBAN reachability
          check during setup; see `SepaBankAccount`.
        SWIFT: >-
          Correspondent banking for euro destinations the SEPA scheme does not
          reach, EUR only. Banks along the path may deduct their own charges
          from the amount in transit, so what the destination receives can fall
          short of `receiveAmount`. Where a destination is reachable both ways,
          SEPA carries the payout; see `SwiftBankAccount`.
        IMPS: India immediate retail transfer, INR. Available around the clock.
        NEFT: India deferred net settlement, INR. Settles in scheduled batches.
        RTGS: >-
          India real-time gross settlement, INR. High value, settled
          individually on receipt.
        SPEI: >-
          Mexico's interbank transfer system, MXN, settled individually in real
          time and routed by CLABE; see `MxLocalBankAccount`. A `receiverMemo`
          is at most 40 letters, digits and spaces, and a longer one or one
          carrying any other character is refused rather than truncated.
        CO_ACH: >-
          Colombian domestic bank transfer, COP, routed by bank code, account
          number and account type; see `CoLocalBankAccount`. The platform
          decides whether a payout settles same-day or in the next clearing
          batch, and the caller cannot choose. The `receiverMemo` rule is the
          one `SPEI` states.
        BREB: >-
          Colombia's instant transfer system, COP, routed by a key the account
          holder registered rather than by account number; see
          `CoBrebBankAccount`. Each payout is capped, so a `receiveAmount` above
          the cap is refused when the quote is priced. The `receiverMemo` rule
          is the one `SPEI` states.
        AE_LOCAL: >-
          The United Arab Emirates' domestic bank transfer, AED, routed by IBAN;
          see `AeLocalBankAccount`. A `receiverMemo` is at most 100 letters,
          digits and spaces, and a longer one or one carrying any other
          character is refused rather than truncated. A `receiveAmount` outside
          the AED per-payout limits is refused when the quote is priced.
      description: >-
        The scheme that physically moves the money, and the source of the
        settlement mechanics and

        the settlement identifiers reported back.


        Omit to auto-route, the platform picks a rail based on the destination
        country and the

        send and receive currencies, and reports the chosen rail back on the
        resulting Payout.


        A member of this list is a scheme OpenFX can route over, not a scheme
        available for a

        given destination: what a specific destination supports is
        `supportedRails` on the

        payout address.


        It also fixes the kind of trace reference reported back for the payout,
        which

        `SettlementTraceIdKey` names.
    PayoutAddressStatus:
      type: string
      enum:
        - PENDING
        - ACTIVE
        - REJECTED
        - REQUIRES_INFORMATION
      x-enum-descriptions:
        PENDING: >-
          Initial setup has not completed: not every setup act it waits on has
          returned. Cannot back a payout yet. A name match that resolves after
          creation, as on a `MX_LOCAL` account, is not waited on, so an address
          can leave this status while that check still reads `PENDING`.
        ACTIVE: >-
          May back a payout. A `CLOSE_MATCH` name result leaves an address here,
          since only a blocking result prevents payout.
        REJECTED: >-
          A setup act returned a blocking result or failed outright, and no
          cause is given beyond what `verifications[]` shows. Cannot back a
          payout while this stands, and the remedy is a replacement address
          rather than a correction, because the record is immutable.
        REQUIRES_INFORMATION: >-
          OpenFX has requested information for this address's setup. The request
          and its fulfillment travel through your operational channel with
          OpenFX, not through the API; the address cannot back a payout while it
          stands, and the status returns to `PENDING` once the information is
          provided.
      description: >-
        Whether the platform's setup of this payout address allows it to back a
        payout.


        It combines a rollup over the address's setup acts with an internal
        platform status. The

        setup acts are the verification acts itemized in `verifications[]`, plus
        further checks and

        setup the platform performs that the address does not itemize. A
        blocking or failed act

        drives `REJECTED`, and which verification results block is stated on
        `NameMatchResult`.


        `PENDING` means initial setup has not completed, never a re-check
        running against an

        already-`ACTIVE` address. Setup runs for the life of the address, so
        `ACTIVE` is not

        terminal: a later blocking or failed act moves the address to
        `REJECTED`, and an

        information request moves it to `REQUIRES_INFORMATION`, but neither
        returns it to

        `PENDING`.


        Orthogonal to `archivedAt`, which is the separate lifecycle axis:
        archiving is the client

        voluntarily retiring the address, REJECTED is an outcome the platform
        recorded.
      example: ACTIVE
    Verification:
      oneOf:
        - $ref: '#/components/schemas/NameMatchVerification'
      type: object
      discriminator:
        propertyName: kind
        mapping:
          NAME_MATCH: '#/components/schemas/NameMatchVerification'
    Timestamp:
      type: string
      format: date-time
      pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$
      description: UTC timestamp in RFC 3339 date-time form. Values end in Z.
      example: '2026-04-28T10:00:00.000Z'
    AccountId:
      type: string
      pattern: ^acc_[1-9A-HJ-NP-Za-km-z]{21,22}$
      description: >-
        A typed-prefix Base58 identifier, matching
        `^acc_[1-9A-HJ-NP-Za-km-z]{21,22}$`: the 3 to 6

        letter lowercase type prefix `acc_` followed by the Base58 encoding of a
        UUID.


        See [Identifiers](/v3/resource-ids) for the prefix table, the case
        rules, and the three

        places a pattern is deliberately not enforced.
    Metadata:
      type: object
      propertyNames:
        type: string
        pattern: ^[a-zA-Z0-9_]{1,40}$
      additionalProperties:
        type: string
        maxLength: 500
      maxProperties: 50
      description: >-
        Your own key/value pairs, kept on the record and returned with it.


        See [Metadata](/v3/metadata-and-tracing#withdrawal-metadata) for what
        belongs in a metadata object, the limits, and where it comes back.
        Metadata is visible in the OpenFX platform, API, and MCP server
        (including connected AI tools), so don't include sensitive or personal
        data.
      example:
        invoiceId: INV-2026-0412
        costCenter: AP_INTL
    BankAccount:
      oneOf:
        - $ref: '#/components/schemas/SepaBankAccount'
        - $ref: '#/components/schemas/SwiftBankAccount'
        - $ref: '#/components/schemas/InLocalBankAccount'
        - $ref: '#/components/schemas/MxLocalBankAccount'
        - $ref: '#/components/schemas/CoLocalBankAccount'
        - $ref: '#/components/schemas/CoBrebBankAccount'
        - $ref: '#/components/schemas/AeLocalBankAccount'
      title: Bank account routing
      description: >-
        The routable identifiers of a bank account, discriminated on
        `routingFamily`; exactly one

        variant is ever present.


        Extraneous or mismatched fields for the selected member are rejected
        outright, never

        silently dropped. A new supported rail family ships as a new member, so
        tolerate an

        unrecognized `routingFamily`.
      type: object
      discriminator:
        propertyName: routingFamily
        mapping:
          SEPA: '#/components/schemas/SepaBankAccount'
          SWIFT: '#/components/schemas/SwiftBankAccount'
          IN_LOCAL: '#/components/schemas/InLocalBankAccount'
          MX_LOCAL: '#/components/schemas/MxLocalBankAccount'
          CO_LOCAL: '#/components/schemas/CoLocalBankAccount'
          CO_BREB: '#/components/schemas/CoBrebBankAccount'
          AE_LOCAL: '#/components/schemas/AeLocalBankAccount'
    ErrorCode:
      type: string
      description: >-
        Stable, machine-readable error code. Format `<PRODUCT>_<ERROR>`. Once
        published, never renamed or removed without a major version bump.
      enum:
        - ACCOUNT_ARCHIVED
        - ACCOUNT_HOLDER_MISMATCH
        - ACCOUNT_NOT_ACTIVE
        - ACCOUNT_NOT_FOUND
        - ADDRESS_SERVES_NO_CAPABILITY
        - AGREEMENTS_NOT_ACTIVE
        - AGREEMENTS_PENDING
        - AMOUNT_OUT_OF_RANGE
        - AUTH_API_KEY_INVALID
        - AUTH_API_KEY_LIVE_REQUIRED
        - AUTH_API_KEY_MISSING
        - AUTH_API_KEY_SANDBOX_REQUIRED
        - AUTH_FORBIDDEN_IP
        - AUTH_INSUFFICIENT_SCOPE
        - AUTH_TOKEN_EXPIRED
        - AUTH_TOKEN_INVALID
        - AUTH_TOKEN_INVALID_CONFIG
        - AUTH_TOKEN_MISSING
        - BANK_ACCOUNT_NOT_FOUND
        - BENEFICIARY_DETAILS_MISSING
        - CAPABILITY_DUPLICATE
        - CAPABILITY_NOT_ACTIVE
        - CURRENCY_NOT_SUPPORTED
        - FEATURE_NOT_ENABLED
        - FINANCIAL_ACCOUNT_CURRENCY_MISMATCH
        - FINANCIAL_ACCOUNT_NOT_FOUND
        - IDEMPOTENCY_IN_FLIGHT
        - IDEMPOTENCY_KEY_INVALID
        - IDEMPOTENCY_KEY_MISSING
        - IDEMPOTENCY_MISMATCH
        - IDEMPOTENCY_UNAVAILABLE
        - IDENTITY_REQUIREMENT_UNMET
        - INTERNAL_ERROR
        - INVALID_ORGANIZATION
        - KYC_REQUIRED
        - METHOD_NOT_ALLOWED
        - MISSING_REQUEST_CONTEXT
        - PAYOUT_ADDRESS_ARCHIVED
        - PAYOUT_ADDRESS_CONFLICT
        - PAYOUT_ADDRESS_FIELD_MISSING
        - PAYOUT_ADDRESS_NOT_FOUND
        - PAYOUT_ADDRESS_REJECTED
        - PAYOUT_ADDRESS_VERIFICATION_FAILED
        - PAYOUT_CANCELLATION_NOT_ALLOWED
        - PAYOUT_CONFIRMATION_NOT_ALLOWED
        - PAYOUT_CURRENCY_NOT_ENABLED
        - PAYOUT_INSUFFICIENT_FUNDS
        - PAYOUT_NOT_ENABLED
        - PAYOUT_NOT_FOUND
        - PAYOUT_TEMPORARILY_UNAVAILABLE
        - PURPOSE_INVALID
        - QUOTE_ALREADY_CONSUMED
        - QUOTE_EXPIRED
        - QUOTE_NOT_FOUND
        - QUOTE_RAIL_UNAVAILABLE
        - QUOTE_REJECTED
        - QUOTE_SEND_CURRENCY_UNAVAILABLE
        - QUOTE_TEMPORARILY_UNAVAILABLE
        - RATE_LIMIT_EXCEEDED
        - RECEIVER_MEMO_INVALID
        - ROUTE_NOT_FOUND
        - SANDBOX_MODE_REQUIRED
        - INVALID_APP_MODE
        - SENDER_ACCOUNT_REQUIRED
        - SENDER_NOT_SUPPORTED
        - VALIDATION_BODY_FAILED
        - VALIDATION_PATH_FAILED
        - VALIDATION_QUERY_FAILED
        - VERIFICATION_EXECUTION_FAILED
        - VALIDATION_HEADER_FAILED
        - VALIDATION_PAYLOAD_TOO_LARGE
        - UNSUPPORTED_MEDIA_TYPE
    ErrorType:
      type: string
      enum:
        - VALIDATION_ERROR
        - AUTHENTICATION_ERROR
        - AUTHORIZATION_ERROR
        - NOT_FOUND
        - CONFLICT
        - RATE_LIMITED
        - INTERNAL_ERROR
      x-enum-descriptions:
        VALIDATION_ERROR: >-
          400 (schema/syntactic) or 422 (semantic/business-rule from the
          payload's values).
        AUTHENTICATION_ERROR: '401.'
        AUTHORIZATION_ERROR: 403 (scope/environment/product-access denial).
        NOT_FOUND: 404 (including cross-org access, never 403).
        CONFLICT: >-
          409 (state conflicts; exception: IDEMPOTENCY_MISMATCH is 422 but still
          `CONFLICT`).
        RATE_LIMITED: '429.'
        INTERNAL_ERROR: '500.'
      description: >-
        Closed `type` classifier, one of seven coarse buckets mapping to HTTP
        status.


        Clients branch on `code`/`type`, never `message`.


        Closed at any published point in time but non-exhaustive at runtime,
        keep a default branch

        falling back to `INTERNAL_ERROR`.
    RetryStrategy:
      type: string
      enum:
        - RETRY_SAME_KEY
        - WAIT_THEN_RETRY_SAME_KEY
        - FIX_AND_RESUBMIT
        - CHECK_STATE_THEN_RETRY
        - TERMINAL
      x-enum-descriptions:
        RETRY_SAME_KEY: Safe to retry immediately with the same Idempotency-Key.
        WAIT_THEN_RETRY_SAME_KEY: >-
          Retry the same key after a backoff: rate limiting and an in-flight
          conflict both land here.
        FIX_AND_RESUBMIT: Invalid request; correct the field(s) in `details` and resubmit.
        CHECK_STATE_THEN_RETRY: GET the resource first; safety depends on server-side state.
        TERMINAL: >-
          Do not retry. Neither a backoff nor a fresh Idempotency-Key changes
          the outcome.
      description: >-
        Closed, machine-actionable retry strategy on every error.


        Closed at any published point in time but non-exhaustive at runtime,
        keep a default branch.
    ErrorDetailsACCOUNT_ARCHIVED:
      type: object
      additionalProperties: false
      properties:
        accountId:
          type: string
          description: The archived account named by the request.
          example: acc_BMY3UenpGBn8ZQ8hio4BgE
      description: >-
        Structured context for `ACCOUNT_ARCHIVED`: The account named by the
        request is archived, a one-way state.
      required:
        - accountId
    ErrorDetailsACCOUNT_HOLDER_MISMATCH:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `ACCOUNT_HOLDER_MISMATCH`: The receiving-side
        account holder name check on the destination payout address returned a
        blocking result, or the account identifier is known bad.
    ErrorDetailsACCOUNT_NOT_ACTIVE:
      type: object
      additionalProperties: false
      properties:
        accountId:
          type: string
          description: The account named by the request.
          example: acc_BMY3UenpGBn8ZQ8hio4BgE
        status:
          type: string
          description: The account's current standing.
          example: REJECTED
      description: >-
        Structured context for `ACCOUNT_NOT_ACTIVE`: The account's standing with
        OpenFX is not ACTIVE.
      required:
        - accountId
        - status
    ErrorDetailsACCOUNT_NOT_FOUND:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `ACCOUNT_NOT_FOUND`: The account identifier is
        unknown or inaccessible to the caller.
    ErrorDetailsADDRESS_SERVES_NO_CAPABILITY:
      type: object
      additionalProperties: false
      properties:
        accountId:
          type: string
          description: The account the payout address would belong to.
          example: acc_BMY3UenpGBn8ZQ8hio4BgE
        required:
          type: object
          additionalProperties: false
          description: The capability coverage the address requires.
          properties:
            grant:
              type: string
              description: The capability grant the address requires.
              example: RECEIVE_PAYOUTS
            currency:
              type: string
              description: The currency the address receives in.
              example: INR
            repatriability:
              type: string
              description: >-
                The repatriability axis the address requires, for an INR
                address.
              example: NON_REPATRIABLE
          required:
            - grant
            - currency
            - repatriability
      description: >-
        Structured context for `ADDRESS_SERVES_NO_CAPABILITY`: The account the
        payout address would belong to holds no capability able to receive at
        it, in any status.
      required:
        - accountId
        - required
    ErrorDetailsAGREEMENTS_NOT_ACTIVE:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `AGREEMENTS_NOT_ACTIVE`: An agreement the
        organization needs exists but is not active, expired, or revoked.
    ErrorDetailsAGREEMENTS_PENDING:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `AGREEMENTS_PENDING`: An agreement the
        organization must accept before this payout can settle is still awaiting
        acceptance.
    ErrorDetailsAMOUNT_OUT_OF_RANGE:
      type: object
      additionalProperties: false
      properties:
        issues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          description: One entry per offending amount field.
        firstIssuePath:
          type: string
          description: The path of the first entry in issues.
          example: /receiveAmount
        amount:
          type: string
          description: The first issue's violating amount.
          example: '50.00'
        minimum:
          type: string
          description: The bound the amount crossed, where it is a floor.
          example: '100.00'
        maximum:
          type: string
          description: The bound the amount crossed, where it is a ceiling.
          example: '1000000.00'
        currency:
          type: string
          description: The currency of the amount and bound.
          example: INR
      description: >-
        Structured context for `AMOUNT_OUT_OF_RANGE`: The amount is outside the
        permitted range for payouts to this destination.
      required:
        - issues
    ErrorDetailsAUTH_API_KEY_INVALID:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `AUTH_API_KEY_INVALID`: The referenced API key
        does not exist or is inactive.
    ErrorDetailsAUTH_API_KEY_LIVE_REQUIRED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `AUTH_API_KEY_LIVE_REQUIRED`: Live traffic uses a
        Sandbox API key.
    ErrorDetailsAUTH_API_KEY_MISSING:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `AUTH_API_KEY_MISSING`: The bearer token does not
        reference an API key.
    ErrorDetailsAUTH_API_KEY_SANDBOX_REQUIRED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `AUTH_API_KEY_SANDBOX_REQUIRED`: Sandbox traffic
        uses a Live API key.
    ErrorDetailsAUTH_FORBIDDEN_IP:
      type: object
      additionalProperties: false
      properties:
        ip:
          type: string
          description: >-
            The caller's IP, echoed for confirmation. Omitted where production
            policy suppresses the offending IP.
          example: 203.0.113.42
      description: >-
        Structured context for `AUTH_FORBIDDEN_IP`: The source IP address is
        outside the API key allowlist.
    ErrorDetailsAUTH_INSUFFICIENT_SCOPE:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `AUTH_INSUFFICIENT_SCOPE`: The API key lacks a
        scope required by the operation.
    ErrorDetailsAUTH_TOKEN_EXPIRED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `AUTH_TOKEN_EXPIRED`: The bearer token expiry
        time is in the past.
    ErrorDetailsAUTH_TOKEN_INVALID:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `AUTH_TOKEN_INVALID`: The bearer token or request
        signature is malformed or fails verification.
    ErrorDetailsAUTH_TOKEN_INVALID_CONFIG:
      type: object
      additionalProperties: false
      properties:
        reason:
          type: string
          description: Stable reason for the invalid token configuration.
      description: >-
        Structured context for `AUTH_TOKEN_INVALID_CONFIG`: The bearer token
        claims or validity window violate the authentication contract.
    ErrorDetailsAUTH_TOKEN_MISSING:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `AUTH_TOKEN_MISSING`: The Authorization header is
        missing.
    ErrorDetailsBANK_ACCOUNT_NOT_FOUND:
      type: object
      additionalProperties: false
      properties:
        reason:
          type: string
          enum:
            - INVALID
            - NOT_FOUND
            - NOT_SUPPORTED
          description: Why no usable account was found at the submitted identifiers.
          example: NOT_FOUND
      description: >-
        Structured context for `BANK_ACCOUNT_NOT_FOUND`: No usable account
        exists at the submitted identifiers.
      required:
        - reason
    ErrorDetailsBENEFICIARY_DETAILS_MISSING:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `BENEFICIARY_DETAILS_MISSING`: A detail the
        receiving institution requires for this payout is missing from the
        destination payout address.
    ErrorDetailsCAPABILITY_DUPLICATE:
      type: object
      additionalProperties: false
      properties:
        duplicates:
          type: array
          items:
            type: string
          description: The capability ids already held or repeated in the request.
          example:
            - cap_R8mRkY9V6dXFFpFrff3mDw
      description: >-
        Structured context for `CAPABILITY_DUPLICATE`: The account already holds
        a cell for a requested capability, or the request names the same
        capability twice.
      required:
        - duplicates
    ErrorDetailsCAPABILITY_NOT_ACTIVE:
      type: object
      additionalProperties: false
      properties:
        accountId:
          type: string
          description: The account named for this activity.
          example: acc_BMY3UenpGBn8ZQ8hio4BgE
        required:
          type: object
          additionalProperties: false
          description: The capability coverage this request needs.
          properties:
            grant:
              type: string
              description: The capability grant required.
              example: RECEIVE_PAYOUTS
            currency:
              type: string
              description: The currency the required capability must cover.
              example: INR
            repatriability:
              type: string
              description: >-
                The repatriability axis the required capability must cover, for
                an INR destination.
              example: NON_REPATRIABLE
          required:
            - grant
            - currency
            - repatriability
        capabilityId:
          type:
            - string
            - 'null'
          description: The closest matching capability cell's id, null when none exists.
          example: cap_R8mRkY9V6dXFFpFrff3mDw
        status:
          type:
            - string
            - 'null'
          description: >-
            The closest matching capability cell's status, null when none
            exists.
          example: PENDING
      description: >-
        Structured context for `CAPABILITY_NOT_ACTIVE`: The account named for
        this activity holds no ACTIVE capability covering what the request
        needs.
      required:
        - accountId
        - required
        - capabilityId
        - status
    ErrorDetailsCURRENCY_NOT_SUPPORTED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `CURRENCY_NOT_SUPPORTED`: No rail can deliver the
        requested receiveCurrency to this destination country.
    ErrorDetailsFEATURE_NOT_ENABLED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `FEATURE_NOT_ENABLED`: The caller's organization
        is not enabled for this feature.
    ErrorDetailsFINANCIAL_ACCOUNT_CURRENCY_MISMATCH:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `FINANCIAL_ACCOUNT_CURRENCY_MISMATCH`: The
        currency of the named financial account is not the sendCurrency the
        request states.
    ErrorDetailsFINANCIAL_ACCOUNT_NOT_FOUND:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `FINANCIAL_ACCOUNT_NOT_FOUND`: The financial
        account identifier is unknown or inaccessible to the caller.
    ErrorDetailsIDEMPOTENCY_IN_FLIGHT:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `IDEMPOTENCY_IN_FLIGHT`: Another request with the
        same idempotency key is still processing.
    ErrorDetailsIDEMPOTENCY_KEY_INVALID:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `IDEMPOTENCY_KEY_INVALID`: The Idempotency-Key
        value does not match ^[a-zA-Z0-9_-]{1,255}$.
    ErrorDetailsIDEMPOTENCY_KEY_MISSING:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `IDEMPOTENCY_KEY_MISSING`: A write request omits
        the Idempotency-Key header.
    ErrorDetailsIDEMPOTENCY_MISMATCH:
      type: object
      additionalProperties: false
      properties:
        originalRequestHash:
          type: string
          description: >-
            Hash identifying the conflicting original request body; the upstream
            service owns this shape.
          example: >-
            sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08
      description: >-
        Structured context for `IDEMPOTENCY_MISMATCH`: An idempotency key is
        reused with a different request body.
      required:
        - originalRequestHash
    ErrorDetailsIDEMPOTENCY_UNAVAILABLE:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `IDEMPOTENCY_UNAVAILABLE`: The idempotency
        service is temporarily unreachable, so the request's Idempotency-Key
        could not be checked.
    ErrorDetailsIDENTITY_REQUIREMENT_UNMET:
      type: object
      additionalProperties: false
      properties:
        issues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          description: >-
            One entry per missing identity field, each path a JSON Pointer into
            the identity object.
        firstIssuePath:
          type: string
          description: The path of the first entry in issues.
          example: /identity/individual/nationality
      description: >-
        Structured context for `IDENTITY_REQUIREMENT_UNMET`: The request
        exercises a capability the account's supplied identity information does
        not support.
      required:
        - issues
    ErrorDetailsINTERNAL_ERROR:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `INTERNAL_ERROR`: An unclassified server-side
        failure occurs.
    ErrorDetailsINVALID_ORGANIZATION:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `INVALID_ORGANIZATION`: The organization
        identifier on the request is malformed.
    ErrorDetailsKYC_REQUIRED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `KYC_REQUIRED`: A know-your-customer check the
        receiving side requires has not cleared.
    ErrorDetailsMETHOD_NOT_ALLOWED:
      type: object
      additionalProperties: false
      properties:
        method:
          type: string
          description: The HTTP method that was used.
          example: PUT
        allowed:
          type: array
          items:
            type: string
          description: The HTTP methods the path supports.
          example:
            - GET
      description: >-
        Structured context for `METHOD_NOT_ALLOWED`: The HTTP method is not
        supported on the request path.
      required:
        - method
        - allowed
    ErrorDetailsMISSING_REQUEST_CONTEXT:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `MISSING_REQUEST_CONTEXT`: The organization,
        user, or idempotency context every request carries was absent or
        unreadable.
    ErrorDetailsPAYOUT_ADDRESS_ARCHIVED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `PAYOUT_ADDRESS_ARCHIVED`: The destination payout
        address is archived, a one-way retirement.
    ErrorDetailsPAYOUT_ADDRESS_CONFLICT:
      type: object
      additionalProperties: false
      properties:
        payoutAddressId:
          type: string
          description: The existing payout address backed by these bank details.
          example: pytadd_PbDQ126YUAbkNrNX6XbGL
        status:
          type: string
          description: The existing payout address's current standing.
          example: ACTIVE
      description: >-
        Structured context for `PAYOUT_ADDRESS_CONFLICT`: The bank details in
        the request already back a payout address on the same account.
      required:
        - payoutAddressId
        - status
    ErrorDetailsPAYOUT_ADDRESS_FIELD_MISSING:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `PAYOUT_ADDRESS_FIELD_MISSING`: A field required
        by the selected routingFamily is missing.
    ErrorDetailsPAYOUT_ADDRESS_NOT_FOUND:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `PAYOUT_ADDRESS_NOT_FOUND`: The payout address
        identifier is unknown or inaccessible to the caller.
    ErrorDetailsPAYOUT_ADDRESS_REJECTED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `PAYOUT_ADDRESS_REJECTED`: The destination payout
        address is REJECTED and cannot back a payout.
    ErrorDetailsPAYOUT_ADDRESS_VERIFICATION_FAILED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `PAYOUT_ADDRESS_VERIFICATION_FAILED`: A
        verification check on the destination payout address could not be
        completed.
    ErrorDetailsPAYOUT_CANCELLATION_NOT_ALLOWED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `PAYOUT_CANCELLATION_NOT_ALLOWED`: The payout
        isn't in REQUIRES_CONFIRMATION.
    ErrorDetailsPAYOUT_CONFIRMATION_NOT_ALLOWED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `PAYOUT_CONFIRMATION_NOT_ALLOWED`: The payout
        isn't in REQUIRES_CONFIRMATION.
    ErrorDetailsPAYOUT_CURRENCY_NOT_ENABLED:
      type: object
      additionalProperties: false
      properties:
        receiveCurrency:
          type: string
          description: The currency the organization is not enabled for.
          example: INR
      description: >-
        Structured context for `PAYOUT_CURRENCY_NOT_ENABLED`: The organization
        isn't enabled for payouts in the requested receiveCurrency.
      required:
        - receiveCurrency
    ErrorDetailsPAYOUT_INSUFFICIENT_FUNDS:
      type: object
      additionalProperties: false
      properties:
        financialAccountId:
          type: string
          description: The underfunded financial account.
          example: finacc_AmKC5dMVXUbiAW8VzKBfqz
      description: >-
        Structured context for `PAYOUT_INSUFFICIENT_FUNDS`: The financial
        account named by financialAccountId cannot cover this payout's debit.
      required:
        - financialAccountId
    ErrorDetailsPAYOUT_NOT_ENABLED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `PAYOUT_NOT_ENABLED`: The organization has no
        active provider configuration for this destination and receiveCurrency.
    ErrorDetailsPAYOUT_NOT_FOUND:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `PAYOUT_NOT_FOUND`: The payout identifier is
        unknown or inaccessible to the caller.
    ErrorDetailsPAYOUT_TEMPORARILY_UNAVAILABLE:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `PAYOUT_TEMPORARILY_UNAVAILABLE`: Payout
        processing is temporarily unavailable because of a provider outage or a
        platform pause.
    ErrorDetailsPURPOSE_INVALID:
      type: object
      additionalProperties: false
      properties:
        issues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          description: >-
            One entry naming `purpose`, with `code` `purpose_required` where it
            is missing and `purpose_not_supported` where the currency refuses
            the value given. Absent where the currency takes no purpose at all.
        firstIssuePath:
          type: string
          description: The path of the first entry in issues.
          example: /purpose
      description: >-
        Structured context for `PURPOSE_INVALID`: The payout's purpose is
        missing where its receiveCurrency requires one, refused for that
        receiveCurrency, or given where the receiveCurrency takes none.
    ErrorDetailsQUOTE_ALREADY_CONSUMED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `QUOTE_ALREADY_CONSUMED`: The quote is already
        bound to another payout.
    ErrorDetailsQUOTE_EXPIRED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: 'Structured context for `QUOTE_EXPIRED`: The applied quote has expired.'
    ErrorDetailsQUOTE_NOT_FOUND:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `QUOTE_NOT_FOUND`: The quote identifier is
        unknown or inaccessible to the caller.
    ErrorDetailsQUOTE_RAIL_UNAVAILABLE:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `QUOTE_RAIL_UNAVAILABLE`: No settlement rail
        serves the requested receiveCurrency to this payout address.
    ErrorDetailsQUOTE_REJECTED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: 'Structured context for `QUOTE_REJECTED`: Pricing declined the request.'
    ErrorDetailsQUOTE_SEND_CURRENCY_UNAVAILABLE:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `QUOTE_SEND_CURRENCY_UNAVAILABLE`: The
        sendCurrency of the named financial account cannot fund the requested
        receiveCurrency.
    ErrorDetailsQUOTE_TEMPORARILY_UNAVAILABLE:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `QUOTE_TEMPORARILY_UNAVAILABLE`: Quoting is
        temporarily halted for reasons independent of the request.
    ErrorDetailsRATE_LIMIT_EXCEEDED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `RATE_LIMIT_EXCEEDED`: The organization exceeds
        its request limit.
    ErrorDetailsRECEIVER_MEMO_INVALID:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `RECEIVER_MEMO_INVALID`: receiverMemo violates
        the character set or length the bound rail's own grammar allows.
    ErrorDetailsROUTE_NOT_FOUND:
      type: object
      additionalProperties: false
      properties:
        path:
          type: string
          description: The unmatched request path.
          example: /v3/payments/example
      description: >-
        Structured context for `ROUTE_NOT_FOUND`: The request path does not
        match a v3 route.
      required:
        - path
    ErrorDetailsSANDBOX_MODE_REQUIRED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `SANDBOX_MODE_REQUIRED`: A request reaches the
        Sandbox environment with an `X-App-Mode` other than `SANDBOX`, for
        example `LIVE`.
    ErrorDetailsINVALID_APP_MODE:
      type: object
      additionalProperties: false
      properties:
        received:
          type: string
          description: The `X-App-Mode` value the request sent.
          example: PRODUCTION
        allowed:
          type: array
          description: The values `X-App-Mode` accepts.
          minItems: 1
          maxItems: 2
          uniqueItems: true
          items:
            type: string
            enum:
              - LIVE
              - SANDBOX
            description: An accepted `X-App-Mode` value.
          example:
            - LIVE
            - SANDBOX
      required:
        - received
        - allowed
      description: >-
        Structured context for `INVALID_APP_MODE`: The `X-App-Mode` header is
        present with a value other than `LIVE` or `SANDBOX`. Matching ignores
        case, and an empty value is also rejected.
    ErrorDetailsSENDER_ACCOUNT_REQUIRED:
      type: object
      additionalProperties: false
      properties:
        issues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          description: One entry naming the missing sender field.
        firstIssuePath:
          type: string
          description: The path of the first entry in issues.
          example: /sender
      description: >-
        Structured context for `SENDER_ACCOUNT_REQUIRED`: The payout needs a
        sender account named on sender and none was supplied.
      required:
        - issues
    ErrorDetailsSENDER_NOT_SUPPORTED:
      type: object
      additionalProperties: false
      properties:
        issues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          description: One entry naming the sender field to remove.
        firstIssuePath:
          type: string
          description: The path of the first entry in issues.
          example: /sender
      description: >-
        Structured context for `SENDER_NOT_SUPPORTED`: The payout names a
        sender, and a payout in this receiveCurrency cannot carry one.
      required:
        - issues
    ErrorDetailsVALIDATION_BODY_FAILED:
      type: object
      additionalProperties: false
      properties:
        issues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          description: One entry per offending field.
        firstIssuePath:
          type: string
          description: The path of the first entry in issues.
          example: /identity/individual/lastName
      description: >-
        Structured context for `VALIDATION_BODY_FAILED`: The request body fails
        schema validation.
      required:
        - issues
    ErrorDetailsVALIDATION_PATH_FAILED:
      type: object
      additionalProperties: false
      properties:
        issues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          description: One entry per offending path parameter.
        firstIssuePath:
          type: string
          description: The path of the first entry in issues.
          example: /payoutId
      description: >-
        Structured context for `VALIDATION_PATH_FAILED`: One or more path
        parameters fail schema validation.
      required:
        - issues
    ErrorDetailsVALIDATION_QUERY_FAILED:
      type: object
      additionalProperties: false
      properties:
        issues:
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
          description: One entry per offending query parameter.
        firstIssuePath:
          type: string
          description: The path of the first entry in issues.
          example: /receiveCurrency
      description: >-
        Structured context for `VALIDATION_QUERY_FAILED`: One or more query
        parameters fail schema validation.
      required:
        - issues
    ErrorDetailsVERIFICATION_EXECUTION_FAILED:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `VERIFICATION_EXECUTION_FAILED`: The verification
        could not be performed because of a technical failure on the platform's
        or the scheme's side.
    ErrorDetailsUNSUPPORTED_MEDIA_TYPE:
      $ref: '#/components/schemas/EmptyErrorDetails'
      description: >-
        Structured context for `UNSUPPORTED_MEDIA_TYPE`: The request's
        Content-Type is not application/json.
    ErrorDetailsVALIDATION_HEADER_FAILED:
      type: object
      additionalProperties: false
      required:
        - issues
        - firstIssuePath
      properties:
        issues:
          type: array
          items:
            $ref: '#/components/schemas/HeaderValidationIssue'
          description: Header validation issues.
        firstIssuePath:
          type: string
          description: Name of the first invalid HTTP header.
          example: X-Request-Id
      description: Structured issues describing an invalid X-Request-Id header.
    ErrorDetailsVALIDATION_PAYLOAD_TOO_LARGE:
      type: object
      required:
        - reason
        - limitBytes
      properties:
        reason:
          type: string
          example: payload_too_large
          description: Machine-readable reason the request body exceeded the payload limit.
        receivedBytes:
          type: integer
          minimum: 0
          example: 9000
          description: >-
            Number of bytes declared in Content-Length, when the gateway has
            that value.
        limitBytes:
          type: integer
          const: 8192
          example: 8192
          description: Maximum request-body size in bytes.
      additionalProperties: false
      description: >-
        Structured context for a request body that exceeds the maximum payload
        size.
    NameMatchVerification:
      type: object
      properties:
        kind:
          type: string
          const: NAME_MATCH
        mode:
          $ref: '#/components/schemas/NameMatchMode'
        result:
          $ref: '#/components/schemas/NameMatchResult'
        providedName:
          type: string
          description: >-
            The name that was submitted for comparison, frozen as it stood when
            the act ran.


            On a payout address this is the `accountHolderName` supplied at
            create. On a payout it

            is the same string as it stood when that act ran: a fresh check at
            payout create, or the

            reused setup act.
          example: Nadia Holdings Pvt Ltd
        registeredName:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            The name the receiving institution holds, as it was returned.


            Null where the scheme returned no name, which every result other
            than `MATCH`,

            `CLOSE_MATCH` and `ACCOUNT_TYPE_MISMATCH` may do. Where it is
            present and differs, it

            is the exact string to use as `accountHolderName` on a replacement
            payout address.
          example: Nadia Holdings Private Limited
        createdAt:
          $ref: '#/components/schemas/Timestamp'
          description: When this act was started.
          example: '2026-06-04T10:30:00.000Z'
        verifiedAt:
          anyOf:
            - $ref: '#/components/schemas/Timestamp'
            - type: 'null'
          description: >-
            When this act resolved. Null while `result` is PENDING, never a
            placeholder value.
          example: '2026-06-04T10:35:12.000Z'
        expiresAt:
          anyOf:
            - $ref: '#/components/schemas/Timestamp'
            - type: 'null'
          description: >-
            When this result goes stale, or null when it does not expire.


            No mode this API supports populates it today, and a caller has no
            way to trigger a

            re-check.
          example: '2026-12-04T10:35:12.000Z'
      required:
        - kind
        - mode
        - result
        - providedName
        - registeredName
        - createdAt
        - verifiedAt
        - expiresAt
      additionalProperties: false
      title: Name match
      description: >-
        A name match: the account holder name the caller supplied, compared
        against the name the

        receiving institution holds.


        Always run when the payout address is created. At payout create the same
        comparison runs

        again only when regulation requires a fresh check; otherwise the
        address's existing

        verification is reused, and it reaches the caller as an entry in that
        payout's

        `confirmations[]` rather than as a verification.


        Both names are frozen on the act, so the record stays readable after the
        payout address it

        describes has been replaced.
    SepaBankAccount:
      type: object
      properties:
        routingFamily:
          type: string
          const: SEPA
          description: >-
            SEPA-reachable: the platform can pay this account over the SEPA
            scheme.
        accountHolderName:
          type: string
          description: >-
            The name the receiving institution holds for this account.


            Not the identity's name and not compared against it: a name match
            runs this string

            against the name the receiving institution holds for the account. An
            account registered as

            `N. Mehta` for `Nadia Mehta` is correct here. Inherited from the
            linked account's own

            `identity` where the create request omitted it.
          example: Nadia Holdings Pvt Ltd
        country:
          $ref: '#/components/schemas/CountryCode'
          description: Where the account is held, read from the IBAN prefix.
          example: DE
        accountNumber:
          type: string
          pattern: ^[A-Z]{2}[0-9]{2}[A-Z0-9]{11,30}$
          description: >-
            The IBAN, ISO 13616.


            Two country letters, two check digits, then up to 30 alphanumeric
            characters. The

            mod-97 checksum and the per-country length are checked too, so a
            well-formed IBAN

            failing either is rejected as a validation error.
          example: DE89370400440532013000
        bic:
          description: >-
            The bank's BIC, ISO 9362, where the account has one.


            Optional here. Supplying it also makes the account payable over
            SWIFT, which

            `supportedRails` reports.
          example: COBADEFFXXX
          type: string
          pattern: ^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$
      required:
        - routingFamily
        - accountHolderName
        - accountNumber
        - country
      additionalProperties: false
      title: SEPA bank account
      description: >-
        An account the platform can pay over SEPA.


        The IBAN's country must sit in the SEPA scheme roster, checked at
        creation and rejected as

        a validation error. A euro account the SEPA scheme does not reach, and
        one with no IBAN at

        all, belong on the SWIFT arm instead. Reachability of the specific IBAN
        is verified

        synchronously as the address is set up, and an unreachable account is
        rejected in that call

        rather than settling later through the address lifecycle.
    SwiftBankAccount:
      type: object
      properties:
        routingFamily:
          type: string
          const: SWIFT
          description: >-
            Correspondent banking: the platform can pay this account through the
            banks between it and us.
        accountHolderName:
          type: string
          maxLength: 140
          pattern: ^[A-Za-z0-9/\-?:().,'+ ]+$
          description: >-
            The name the receiving institution holds for this account, up to 140
            characters.


            Not the identity's name and not compared against it: an account
            registered as `N. Mehta`

            for `Nadia Mehta` is correct here. Inherited from the linked
            account's own `identity`

            where the create request omitted it.
          example: Novalia Handels GmbH
        accountNumber:
          type: string
          pattern: ^[A-Z0-9]{1,34}$
          description: >-
            The account number at the bank, an IBAN or the bank's own, up to 34
            characters.


            Uppercase and contiguous, whatever grouping it was supplied in.
          example: '8801234567'
        bic:
          type: string
          pattern: ^[A-Z]{6}[A-Z0-9]{2}([A-Z0-9]{3})?$
          description: >-
            The bank's BIC, ISO 9362.


            Eight or eleven characters. Its fifth and sixth name the bank's
            country, which must be one

            the platform can pay SWIFT into, checked when the address is
            created.
          example: PAVEGE22XXX
        accountHolderAddress:
          $ref: '#/components/schemas/AccountHolderAddress'
        country:
          $ref: '#/components/schemas/CountryCode'
          description: Where the account is held, read from the BIC's country characters.
          example: GE
      required:
        - routingFamily
        - accountHolderName
        - accountNumber
        - bic
        - accountHolderAddress
        - country
      additionalProperties: false
      title: SWIFT bank account
      description: >-
        A euro account the platform can pay by correspondent banking, for
        destinations the SEPA

        scheme does not reach.


        An IBAN whose country sits in the SEPA scheme roster is accepted here
        too, and an account

        that has one is paid over SEPA. Where it has none, the BIC's country
        must be one the platform

        can pay SWIFT into, and no name check runs against the account.
    InLocalBankAccount:
      type: object
      properties:
        routingFamily:
          type: string
          const: IN_LOCAL
          description: >-
            The Indian domestic bundle: IMPS, NEFT and RTGS, routed by IFSC and
            account number.
        accountHolderName:
          type: string
          description: >-
            The name the receiving institution holds for this account.


            Not the identity's name and not compared against it: a name match
            runs this string

            against the name the receiving institution holds for the account. An
            account registered as

            `N. Mehta` for `Nadia Mehta` is correct here. Inherited from the
            linked account's own

            `identity` where the create request omitted it.
          example: Nadia Holdings Pvt Ltd
        ifsc:
          type: string
          pattern: ^[A-Z]{4}0[A-Z0-9]{6}$
          description: >-
            The 11-character IFSC identifying the branch: four bank letters, a
            zero, then six branch characters.
          example: HDFC0001234
        accountNumber:
          type: string
          pattern: ^[0-9]{9,18}$
          description: The account number at that branch, 9 to 18 digits.
          example: '50100234567890'
        isNre:
          type: boolean
          description: >-
            Whether this is a repatriable NRE account, funded from abroad, with
            the balance freely

            repatriable, principal and interest both.


            False covers an NRO account (a non-resident's account for income
            arising in India, where

            repatriation is capped per financial year and needs tax
            certification) and an ordinary

            account held by an Indian resident alike, and is also what an
            omitted create request

            resolves to.
          example: false
        bankAccountType:
          x-enum-descriptions:
            SAVINGS: A personal deposit account.
            CURRENT: A business transaction account.
          description: |-
            Which kind of account this is at the institution.

            Optional, and defaults to `SAVINGS` when omitted.
          example: SAVINGS
          type: string
          enum:
            - SAVINGS
            - CURRENT
        country:
          $ref: '#/components/schemas/CountryCode'
          description: >-
            Where the account is held. Constant: this arm routes exclusively
            within India.
          example: IN
      required:
        - routingFamily
        - accountHolderName
        - ifsc
        - accountNumber
        - isNre
        - country
      additionalProperties: false
      title: Indian bank account
      description: |-
        An Indian account, routed by IFSC and account number.

        Derived rails: IMPS, NEFT and RTGS.
    MxLocalBankAccount:
      type: object
      properties:
        routingFamily:
          type: string
          const: MX_LOCAL
          description: 'The Mexican domestic system: SPEI, routed by CLABE.'
        accountHolderName:
          type: string
          description: >-
            The name the receiving institution holds for this account.


            Not the identity's name and not compared against it: a name match
            runs this string

            against the name the receiving institution holds for the account. An
            account registered as

            `N. Mehta` for `Nadia Mehta` is correct here. Inherited from the
            linked account's own

            `identity` where the create request omitted it.
          example: Nadia Holdings Pvt Ltd
        accountNumber:
          type: string
          pattern: ^[0-9]{18}$
          description: >-
            The CLABE, Mexico's 18-digit standardized account number.


            Three digits name the bank, three the city, eleven the account, and
            the last is a check

            digit computed from the other seventeen.
          example: '012180001234567899'
        country:
          $ref: '#/components/schemas/CountryCode'
          description: >-
            Where the account is held. Constant: this arm routes exclusively
            within Mexico.
          example: MX
      required:
        - routingFamily
        - accountHolderName
        - accountNumber
        - country
      additionalProperties: false
      title: Mexican bank account
      description: >-
        A Mexican account, routed by CLABE. Derived rail: SPEI, in MXN.


        The account holder is checked after creation, usually within minutes and
        only during Mexican

        banking hours. The address does not wait for that check: it can be
        `ACTIVE` while the check is

        still `PENDING`, and only a `NO_MATCH` result rejects it. The account
        holder sees

        your organization as the payer.
    CoLocalBankAccount:
      type: object
      properties:
        routingFamily:
          type: string
          const: CO_LOCAL
          description: >-
            The Colombian domestic bank transfer, routed by bank code, account
            number and account type.
        accountHolderName:
          type: string
          description: >-
            The name the receiving institution holds for this account.


            Not the identity's name and not compared against it. Inherited from
            the linked account's own

            `identity` where the create request omitted it.
          example: Camila Restrepo
        bankCode:
          type: string
          pattern: ^[0-9]{4}$
          description: The four-digit code of the bank holding the account.
          example: '1007'
        accountNumber:
          type: string
          pattern: ^[0-9]{4,20}$
          description: The account number at that bank, 4 to 20 digits.
          example: '24512345678'
        bankAccountType:
          type: string
          enum:
            - CHECKING
            - SAVINGS
            - ELECTRONIC_DEPOSIT
          x-enum-descriptions:
            CHECKING: >-
              A current account, cuenta corriente, which carries a checkbook and
              is the usual business account.
            SAVINGS: >-
              A savings account, cuenta de ahorros, the account most individuals
              hold.
            ELECTRONIC_DEPOSIT: >-
              A low-value electronic deposit account, depósito electrónico,
              opened through a phone rather than at a branch. Not every bank
              offers one.
          description: >-
            Which kind of account this is at the bank.


            Checked when the address is created against the kinds the bank named
            by `bankCode`

            accepts, and a kind it does not accept is rejected as a validation
            error.
          example: SAVINGS
        country:
          $ref: '#/components/schemas/CountryCode'
          description: >-
            Where the account is held. Constant: this arm routes exclusively
            within Colombia.
          example: CO
      required:
        - routingFamily
        - accountHolderName
        - bankCode
        - accountNumber
        - bankAccountType
        - country
      additionalProperties: false
      title: Colombian bank account
      description: >-
        A Colombian bank account, routed by bank code, account number and
        account type. Derived rail:

        CO_ACH, in COP.


        No name check runs against the account, so `verifications[]` stays
        empty. The account holder

        sees Pexto Colombia SAS as the payer, whoever the payout is for, and
        `receiverMemo` is the only

        other text that reaches them.
    CoBrebBankAccount:
      type: object
      properties:
        routingFamily:
          type: string
          const: CO_BREB
          description: >-
            Colombia's instant transfer system, Bre-B, routed by a key the
            account holder registered.
        accountHolderName:
          type: string
          description: >-
            The name the receiving institution holds for this account.


            Not the identity's name and not compared against it: a name match
            runs this string

            against the name the receiving institution holds for the account. An
            account registered as

            `N. Mehta` for `Nadia Mehta` is correct here. Inherited from the
            linked account's own

            `identity` where the create request omitted it.
          example: Nadia Holdings Pvt Ltd
        brebKey:
          type: string
          minLength: 1
          maxLength: 255
          pattern: ^\S+$
          description: >-
            The Bre-B key the account holder registered, written exactly as they
            gave it: a mobile

            number, an email address, an identity document number, or a handle
            with its leading

            `@`.


            The kind of key is not supplied and not needed. The key is looked up
            as the address is

            set up, and that lookup, not a format check, is what establishes the
            key reaches the

            named account holder.
          example: '@camilarestrepo'
        country:
          $ref: '#/components/schemas/CountryCode'
          description: >-
            Where the account is held. Constant: this arm routes exclusively
            within Colombia.
          example: CO
      required:
        - routingFamily
        - accountHolderName
        - brebKey
        - country
      additionalProperties: false
      title: Bre-B key
      description: >-
        A Colombian account reached through a Bre-B key rather than an account
        number. Derived rail:

        BREB, in COP.


        The key is looked up as the address is set up, and only a `NO_MATCH`
        result rejects the

        address: a lookup that cannot be completed leaves it payable. The
        account holder sees the payer

        as PXT followed by your organization's name.
    AeLocalBankAccount:
      type: object
      properties:
        routingFamily:
          type: string
          const: AE_LOCAL
          description: The UAE domestic bank transfer, routed by IBAN.
        accountHolderName:
          type: string
          description: >-
            The name the receiving institution holds for this account.


            Not the identity's name and not compared against it. Inherited from
            the linked account's own `identity` where the create request omitted
            it.
          example: Falcon Trading LLC
        accountNumber:
          type: string
          pattern: ^AE[0-9]{21}$
          description: >-
            The IBAN, ISO 13616, in electronic format.


            AE, two check digits, a three-digit bank code and a sixteen-digit
            account number.
          example: AE070331234567890123456
        country:
          $ref: '#/components/schemas/CountryCode'
          description: >-
            Where the account is held. Constant: this arm routes exclusively
            within the United Arab Emirates.
          example: AE
      required:
        - routingFamily
        - accountHolderName
        - accountNumber
        - country
      additionalProperties: false
      title: UAE bank account
      description: >-
        An account held in the United Arab Emirates, routed by IBAN. Derived
        rail: AE_LOCAL, in AED.


        The IBAN carries the bank, so no BIC, bank code or account type is
        taken. No name check runs against the account, so `verifications[]`
        stays empty. The account holder sees your organization as the payer,
        whoever the payout is for, and `receiverMemo` is the only other text
        that reaches them.
    EmptyErrorDetails:
      type: object
      description: Closed details object for errors that expose no additional context.
      additionalProperties: false
      maxProperties: 0
    ValidationIssue:
      type: object
      properties:
        path:
          type: string
          format: json-pointer
          description: >-
            JSON Pointer to the offending field, resolved against the request:
            the JSON body for body validation, the query parameters read as one
            object for query validation. An array element is addressed by its
            zero-based index (`/identity/individual/documents/0/type`). An empty
            string names the whole body, for a cross-field issue no single field
            owns.
          example: /identity/individual/nationality
        code:
          type: string
          description: >-
            Machine-readable issue kind, lowercase snake_case.


            An open, deliberately non-exhaustive set. The values worth knowing,
            an illustration

            rather than a catalog:


            - invalid_type: the value has the wrong JSON type, or a required
            leaf is absent; `expected` and `received` carry the type names, and
            an absent leaf reads received undefined.

            - invalid_string: the value fails the field's pattern; `expected`
            carries the pattern.

            - invalid_enum_value: the value is not a member of the field's enum;
            `expected` carries the members, pipe-separated.

            - unrecognized_keys: an object carries a key that is not part of the
            schema, rejected rather than silently dropped; `path` names the
            object holding the key and `message` names the keys, the one issue
            whose `path` is not a leaf.

            - custom: the value is well-formed but not accepted, the case for an
            externally governed space such as an ISO country or currency code;
            the `message` names the standard.

            - append_conflict: the identity leaf is already set, and identity is
            append-only.

            - amount_below_minimum / amount_exceeds_limit: the amount is outside
            the permitted range for the payout destination; `details` carries
            the violating amount and the single bound it crossed.

            - sepa_iban_required / sepa_iban_unreachable: the `SEPA` arm was
            given an account it cannot pay, either one with no IBAN at all or an
            IBAN whose country the SEPA scheme does not cover; register it on
            the `SWIFT` arm instead.

            - swift_country_unsupported: the `bic` names a bank in a country the
            platform cannot pay SWIFT into; `details` carries that country.

            - bank_account_type_not_accepted: the `bankAccountType` is not a
            kind of account the bank named by `bankCode` accepts; `expected`
            carries the kinds it does, pipe-separated.

            - date_of_incorporation_mismatch: `dateOfIncorporation` is not the
            date the Mexican RFC in `taxInformation` encodes; correct whichever
            is wrong.

            - account_holder_name_invalid: the `accountHolderName` a payout
            address would carry, supplied or inherited from the account, breaks
            the name rules of its `routingFamily`; `message` names the rule.
            Supply a name that keeps to them.

            - purpose_required: the payout's `receiveCurrency` requires a
            `purpose` and none was given.

            - purpose_not_supported: the payout's `receiveCurrency` refuses the
            `purpose` given; pick another.


            Values not listed here appear without notice, so keep a default
            branch and fall back to

            rendering `message`.
          example: invalid_type
        message:
          type: string
          description: >-
            Human-readable statement of the issue. Not a stability contract;
            branch on `code`.
          example: Required
        expected:
          description: >-
            What the field accepts, when stating it helps the fix: a type name
            or a pattern.
          example: string
          type: string
        received:
          description: What the request carried, when echoing it back is safe.
          example: number
          type: string
      required:
        - path
        - code
        - message
      additionalProperties: false
      description: A single field-level validation failure.
    HeaderValidationIssue:
      type: object
      additionalProperties: false
      required:
        - path
        - code
        - message
      properties:
        path:
          type: string
          description: Name of the rejected HTTP header.
          example: X-Request-Id
        code:
          type: string
          description: Machine-readable header validation issue code.
          example: invalid_format
        message:
          type: string
          description: Human-readable description of the header validation failure.
          example: The X-Request-Id header is invalid.
      description: A single header validation issue.
    NameMatchMode:
      type: string
      enum:
        - SEPA_VOP
        - IMPS_PENNY_DROP
        - SPEI_ACCOUNT_OWNERSHIP
        - BREB_KEY_LOOKUP
      x-enum-descriptions:
        SEPA_VOP: >-
          The SEPA Verification of Payee scheme. Always run when the payout
          address is created, and again at payout create because SEPA regulation
          requires a fresh check; the confirmation is that second act, not a
          reuse of the setup one.
        IMPS_PENNY_DROP: >-
          A penny drop over India's IMPS rail: a micro-deposit the receiving
          bank returns the registered account holder name for. On the name it
          resolves to `MATCH`, `NO_MATCH` or `ACCOUNT_TYPE_MISMATCH`, never a
          middle result; it can also come back `UNAVAILABLE` when the scheme or
          network does not answer, which says nothing about the name and does
          not block the payout. Always run when the payout address is created.
          India does not require a fresh check per payout, so the existing
          verification is reused as the confirmation.
        SPEI_ACCOUNT_OWNERSHIP: >-
          A check that the CLABE is held by the named account holder, run over
          Mexico's SPEI system. Started when the payout address is created and
          resolved later, usually within minutes and only during Mexican banking
          hours. The address does not wait for it, so a payout can be created
          while it reads `PENDING`, and the confirmation reuses it as it stands
          then. A later `NO_MATCH` still rejects the address.
        BREB_KEY_LOOKUP: >-
          A real-time lookup of the Bre-B key, comparing the holder it is
          registered to against the named account holder. Run once when the
          payout address is created; an `UNAVAILABLE` result leaves the address
          payable, and the confirmation reuses the setup act.
      description: >-
        The scheme under which a name match was performed. A name match always
        runs when the payout address is created. At payout create it runs again
        only when regulation requires a fresh check; otherwise the address's
        existing verification is reused.
      example: SEPA_VOP
    NameMatchResult:
      type: string
      enum:
        - PENDING
        - MATCH
        - CLOSE_MATCH
        - NO_MATCH
        - ACCOUNT_TYPE_MISMATCH
        - UNAVAILABLE
        - DEFERRED_TO_RECEIVING_FI
      x-enum-descriptions:
        PENDING: >-
          The check has not returned yet. Not blocking, and `verifiedAt` is null
          while it stands.
        MATCH: >-
          The two names agree exactly, which is what separates this from
          `CLOSE_MATCH`. Not blocking.
        CLOSE_MATCH: >-
          The names differ in a way consistent with the same holder, such as
          initials against a full given name, or a trading name against a
          registered one. Not blocking: a payout address carrying one stays
          payable, and a payout carrying one is sent.
        NO_MATCH: >-
          The names are not the same holder. Blocking on a payout address, which
          cannot back a payout while it stands. On a payout it blocks nothing by
          itself: it is the result the caller is shown before confirming, and
          confirming proceeds anyway.
        ACCOUNT_TYPE_MISMATCH: >-
          The name agrees, but the account kind does not: the `isNre` the payout
          address declared disagrees with what the receiving bank holds for the
          account. Blocking on a payout address exactly as `NO_MATCH` is, and
          the remedy is a replacement address declaring the kind the bank holds.
        UNAVAILABLE: >-
          The check could not be completed, because the scheme, the institution
          or the network did not answer. Not blocking, and says nothing about
          the name.
        DEFERRED_TO_RECEIVING_FI: >-
          The scheme returned no verdict and left the decision to the receiving
          institution at settlement. Not blocking here, and the payout may still
          be returned later.
      description: >-
        How the supplied account holder name compared against the name the
        receiving institution

        holds.


        On a payout address a `NO_MATCH` leaves the address unable to back a
        payout, and the

        remedy is a replacement address carrying the name the institution holds,
        which is what

        `registeredName` records. On a payout the result reaches the caller as a

        `Confirmation` entry before any funds move, and confirming accepts
        whatever it says.
      example: MATCH
    CountryCode:
      type: string
      pattern: ^[A-Z]{2}$
      description: >-
        ISO 3166-1 alpha-2 country code, matching `^[A-Z]{2}$`.


        Uppercase and case-sensitive: a lowercase code is rejected rather than
        normalized.
    AccountHolderAddress:
      type: object
      properties:
        country:
          $ref: '#/components/schemas/CountryCode'
          description: The country the address is in.
          example: DE
        city:
          type: string
          maxLength: 35
          pattern: ^[A-Za-z0-9/\-?:().,'+ ]+$
          description: Town or city.
          example: Berlin
        line1:
          description: Street name and number.
          example: Friedrichstrasse 100
          type: string
          maxLength: 70
          pattern: ^[A-Za-z0-9/\-?:().,'+ ]+$
        line2:
          description: A second street line, for a floor, a unit or a care-of name.
          example: Floor 3
          type: string
          maxLength: 70
          pattern: ^[A-Za-z0-9/\-?:().,'+ ]+$
        postalCode:
          description: Postal or ZIP code.
          example: '10117'
          type: string
          maxLength: 16
          pattern: ^[A-Za-z0-9/\-?:().,'+ ]+$
        state:
          description: >-
            State, province or region. No format is claimed, so write it as the
            country's own post would.
          example: Berlin
          type: string
          maxLength: 35
          pattern: ^[A-Za-z0-9/\-?:().,'+ ]+$
      required:
        - country
        - city
      additionalProperties: false
      title: Account holder address
      description: >-
        The postal address the account holder is at.


        Its town and country travel with the payment, so both are required.
        Letters, digits,

        space and the punctuation `/ - ? : ( ) . , ' +` are accepted, and any
        other character

        is rejected.
  headers:
    XTraceId:
      description: >-
        Server-generated OpenTelemetry trace id, present on every response and
        regenerated per attempt (including idempotency replays). Quote it to
        OpenFX support to locate a request.
      schema:
        type: string
      example: 1f9e4c2a7b3d4e5f6a7b8c9d0e1f2a3b
    XRequestTimestamp:
      description: >-
        RFC 3339 UTC timestamp, millisecond precision, of when the request
        reached the API.
      schema:
        $ref: '#/components/schemas/Timestamp'
      example: '2026-06-04T10:30:00.000Z'
    RateLimitLimit:
      description: >-
        Maximum requests allowed in the current window. See the Rate limiting
        page.
      schema:
        type: integer
      example: 300
    RateLimitReset:
      description: >-
        Seconds until the current rate-limit window resets (a duration, counted
        from the response time — not an absolute Unix timestamp).
      schema:
        type: integer
      example: 8
    RetryAfter:
      description: >-
        Seconds to wait before retrying. Present on `429 RATE_LIMIT_EXCEEDED`
        and `409 IDEMPOTENCY_IN_FLIGHT` responses only.
      schema:
        type: integer
      example: 10
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: >-
        ES256 JWT bearer token, minted fresh per request.


        See [Authentication](/v3/authentication) for the claims, including the
        nonce, the

        request signature, the two scopes, and which status means what.
    requestSignature:
      type: apiKey
      in: header
      name: X-Request-Signature
      description: >-
        Body-bound ES256 signature over the request, required alongside the
        bearer token on

        every call. Base64url of an IEEE P-1363 fixed 64-byte `r‖s` signature.


        See [Authentication](/v3/authentication) for the canonical string it
        signs, including

        the JWT nonce that binds it to the bearer token.

````