> ## 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 an account

> Retrieve a single account.



## OpenAPI

````yaml api-reference/openapi-v3-payments.json GET /v3/common/accounts/{accountId}
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/common/accounts/{accountId}:
    get:
      tags:
        - Accounts
      summary: Retrieve an account
      description: >-
        Retrieve a single account. Payout addresses are not embedded: fetch an
        account's destinations with `listPayoutAddresses` (`GET
        /v3/payments/payout-addresses?accountId=`), which is cursor-paginated
        and returns the full `PayoutAddress` shape.
      operationId: getAccount
      parameters:
        - $ref: '#/components/parameters/XAppMode'
        - $ref: '#/components/parameters/XRequestId'
        - in: path
          name: accountId
          schema:
            type: string
            description: >-
              Account id (`acc_`). 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: >-
            Account id (`acc_`). 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 account.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/Account'
                required:
                  - data
                additionalProperties: false
              examples:
                sepaOrganization:
                  summary: Organization account
                  value:
                    data:
                      object: account
                      id: acc_BMY3UenpGBn8ZQ8hio4BgE
                      status: ACTIVE
                      capabilities:
                        - object: accountCapability
                          id: cap_Ji86R1HUP9uUTtp9kdkqBw
                          status: ACTIVE
                          details:
                            grants:
                              - RECEIVE_PAYOUTS
                            currencies:
                              - EUR
                          hasActiveAddresses: true
                      identity:
                        identityType: ORGANIZATION
                        organization:
                          legalName: Novalia Handels GmbH
                          registeredAddress:
                            country: DE
                      archivedAt: null
                      createdAt: '2026-06-04T10:30:00.000Z'
                      updatedAt: '2026-06-04T10:30:00.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 account with this id is visible to your organization:
            ACCOUNT_NOT_FOUND.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorEnvelope'
              examples:
                ACCOUNT_NOT_FOUND:
                  value:
                    error:
                      code: ACCOUNT_NOT_FOUND
                      type: NOT_FOUND
                      message: No account 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:
    Account:
      type: object
      properties:
        object:
          type: string
          const: account
          description: >-
            The type of object represented, a fixed discriminator. Always
            `"account"` for this resource, and identical across every object of
            the type.
          example: account
        id:
          $ref: '#/components/schemas/AccountId'
          description: Account identifier.
          example: acc_BMY3UenpGBn8ZQ8hio4BgE
        status:
          $ref: '#/components/schemas/AccountStatus'
        archivedAt:
          anyOf:
            - $ref: '#/components/schemas/Timestamp'
            - type: 'null'
          description: >-
            When the client retired this account, or null while it is live.


            Terminal once set. An archived account is hidden from `listAccounts`
            by

            default, cannot receive new payouts, and cannot have new payout
            addresses created

            against it. Nothing is deleted: it stays retrievable by id.
          example: '2026-06-04T10:30:00.000Z'
        createdAt:
          $ref: '#/components/schemas/Timestamp'
          description: Creation timestamp.
          example: '2026-06-04T10:30:00.000Z'
        capabilities:
          type: array
          items:
            $ref: '#/components/schemas/AccountCapability'
          description: >-
            The capabilities this account holds, one entry per capability it has
            been set up for.


            Each entry carries the capability `id`, the `status` of its setup,
            and a `details` echo

            of what it covers. A capability starts `PENDING` and its setup
            starts at creation, so an

            entry can already be `ACTIVE` on the create response where its
            checks settle inside the call.

            A capability leaves service only by moving to `REJECTED`, and two
            capabilities may cover the

            same currency.
          example:
            - object: accountCapability
              id: cap_Ji86R1HUP9uUTtp9kdkqBw
              status: ACTIVE
              details:
                grants:
                  - RECEIVE_PAYOUTS
                currencies:
                  - EUR
              hasActiveAddresses: true
            - object: accountCapability
              id: cap_BTfPKkGd8ttTQjf3bxA22g
              status: PENDING
              details:
                grants:
                  - SEND_PAYOUTS_TO_THIRD_PARTIES
                currencies:
                  - INR
                repatriability:
                  - REPATRIABLE
              hasActiveAddresses: false
        identity:
          $ref: '#/components/schemas/Identity'
          description: >-
            Who the account is. What to supply for each capability is set out in
            [Working with capabilities](/v3/capabilities).
        label:
          description: >-
            Freeform label to help you identify the account. For a structured
            reference back to a

            record in your own system, use `metadata`.
          example: Novalia
          type: string
        metadata:
          $ref: '#/components/schemas/Metadata'
        updatedAt:
          $ref: '#/components/schemas/Timestamp'
          description: Update timestamp.
          example: '2026-06-04T10:30:00.000Z'
      required:
        - object
        - id
        - status
        - archivedAt
        - createdAt
        - capabilities
        - identity
        - updatedAt
      additionalProperties: false
      description: >-
        Someone you move money to or from: one identity, and the capabilities it
        is set up for. An account holds no money with OpenFX: it is a party, not
        a balance.
    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.
    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.
    AccountStatus:
      type: string
      enum:
        - PENDING
        - ACTIVE
        - REJECTED
        - REQUIRES_INFORMATION
      x-enum-descriptions:
        PENDING: >-
          OpenFX has not settled the account's standing yet, and nothing is
          asked of you. A payout cannot name the account, as `receiver` or as
          `sender`, until it is `ACTIVE`.
        ACTIVE: >-
          In good standing: the only status in which a payout can name the
          account, as `receiver` or as `sender`.
        REJECTED: >-
          OpenFX's judgment went against the account. While it stands, the
          account cannot be used, and the remedy is a replacement account: a
          rejection is a standing judgment on the entity that supplying more
          identity cannot reverse.
        REQUIRES_INFORMATION: >-
          OpenFX has asked for information about the account. The request and
          its fulfillment travel through your operational channel with OpenFX,
          not through the API; a payout is blocked exactly as under `PENDING`,
          and the status returns to `PENDING` once the information is provided.
      description: >-
        The account's standing with OpenFX as a whole.


        OpenFX's own judgment of the entity, moved by its risk and compliance
        decisions and by

        entity-level screening. It is not a rollup of the `capabilities`: each
        capability carries

        its own status for its own activity, and this value moves independently
        of all of them. An

        account starts at `PENDING` or `ACTIVE`.


        The member set is deliberately identical across `AccountStatus`,

        `CapabilityStatus` and `PayoutAddressStatus`. The transitions between
        the

        states, and what a payout requires of all three surfaces, are in

        [Account, capability and payout address
        lifecycle](/v3/account-model#the-shared-state-machine).
      example: ACTIVE
    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'
    AccountCapability:
      type: object
      properties:
        object:
          type: string
          const: accountCapability
          description: >-
            The type of object represented, a fixed discriminator. Always
            `"accountCapability"` for this resource, and identical across every
            object of the type.
          example: accountCapability
        id:
          $ref: '#/components/schemas/CapabilityId'
          description: The catalog capability this account holds.
          example: cap_Ji86R1HUP9uUTtp9kdkqBw
        status:
          $ref: '#/components/schemas/CapabilityStatus'
        details:
          $ref: '#/components/schemas/CapabilityDetails'
        hasActiveAddresses:
          type:
            - boolean
            - 'null'
          description: Indicates whether the capability serves any payout addresses.
          example: true
      required:
        - object
        - id
        - status
        - details
        - hasActiveAddresses
      additionalProperties: false
      title: Held capability
      description: >-
        A capability an account holds, and where its setup stands.


        `details` carries the capability's coverage so a client can decide what
        to surface, for

        instance offering to add a EUR payout address when the account holds a
        EUR-receiving

        capability.
    Identity:
      oneOf:
        - $ref: '#/components/schemas/Individual'
        - $ref: '#/components/schemas/Organization'
      description: >-
        The person or organization an account is, discriminated on
        `identityType`; exactly one variant is ever present.
      type: object
      discriminator:
        propertyName: identityType
        mapping:
          INDIVIDUAL: '#/components/schemas/Individual'
          ORGANIZATION: '#/components/schemas/Organization'
    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
    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.
    CapabilityId:
      type: string
      pattern: ^cap_[1-9A-HJ-NP-Za-km-z]{21,22}$
      description: >-
        A typed-prefix Base58 identifier, matching
        `^cap_[1-9A-HJ-NP-Za-km-z]{21,22}$`: the 3 to 6

        letter lowercase type prefix `cap_` 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.
    CapabilityStatus:
      type: string
      enum:
        - PENDING
        - ACTIVE
        - REJECTED
        - REQUIRES_INFORMATION
      x-enum-descriptions:
        PENDING: >-
          The setup this capability needs has not finished. It cannot back its
          activity yet.
        ACTIVE: Usable.
        REJECTED: >-
          A setup act was declined. While it stands, the capability cannot be
          used, and the remedy is to request a replacement capability; the
          account's identity and its other capabilities are unaffected.
        REQUIRES_INFORMATION: >-
          OpenFX has requested information for this capability's setup. The
          request and its fulfillment travel through your operational channel
          with OpenFX, not through the API; the capability cannot be used while
          it stands, and the status returns to `PENDING` once the information is
          provided.
      description: >-
        Whether a capability can currently back its activity on a payout.


        Derived from the setup the capability's regime requires, the identity
        checks first among

        them. What setup a given regime runs, and in what order, is not part of
        the API surface:

        the capability reports only the outcome.


        The transitions between these states, and what moves a capability
        between them, are in

        [Account, capability and payout address
        lifecycle](/v3/account-model#the-shared-state-machine).
      example: ACTIVE
    CapabilityDetails:
      type: object
      properties:
        grants:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/CapabilityGrant'
          description: >-
            What this capability lets the holding account do, at least one
            grant.


            A capability with several grants is one atomic application: one
            requirement set, one

            status, activated or refused as a unit. What an account may do
            overall is the union of

            `grants` across its `ACTIVE` capabilities.
          example:
            - RECEIVE_PAYOUTS
        currencies:
          description: >-
            The currencies this capability covers.


            Absent where the coverage is currency-independent; when present it
            holds at least one

            currency. Enumerated, never a wildcard, so tolerate a value you do
            not recognize.
          example:
            - EUR
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/CurrencyCode'
        repatriability:
          description: >-
            The repatriability categories this capability covers.


            Absent where the axis does not apply to the covered flows; when
            present it holds at

            least one category. The destination's own category is read off the
            payout address's

            `isNre`: true is covered by `REPATRIABLE`, false by
            `NON_REPATRIABLE`.
          example:
            - REPATRIABLE
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/Repatriability'
      required:
        - grants
      additionalProperties: false
      description: >-
        What a capability lets an account do, decomposed so a client can branch
        on coverage without reading the catalog: a derived, read-only view
        resolved from the catalog by capability id, so it always agrees with the
        id. See [Working with capabilities](/v3/capabilities) for how the axes
        combine and for its forward-compatibility handling.
      example:
        grants:
          - RECEIVE_PAYOUTS
        currencies:
          - EUR
    Individual:
      type: object
      properties:
        identityType:
          type: string
          const: INDIVIDUAL
        individual:
          $ref: '#/components/schemas/IndividualIdentity'
      required:
        - identityType
        - individual
      additionalProperties: false
      title: Individual
      description: A natural person as the account's identity.
    Organization:
      type: object
      properties:
        identityType:
          type: string
          const: ORGANIZATION
        organization:
          $ref: '#/components/schemas/OrganizationIdentity'
      required:
        - identityType
        - organization
      additionalProperties: false
      title: Organization
      description: A business or company as the account's identity.
    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.
    CapabilityGrant:
      type: string
      enum:
        - RECEIVE_PAYOUTS
        - SEND_PAYOUTS_TO_THIRD_PARTIES
      x-enum-descriptions:
        RECEIVE_PAYOUTS: >-
          The account may be named as a payout's `receiver` at payout addresses
          the capability's axes cover: the money lands with them, at their own
          bank account.
        SEND_PAYOUTS_TO_THIRD_PARTIES: >-
          The account may be named as a payout's `sender` where the destination
          payout address is held by a different account. Money never flows from
          them through this API: the funds move from the payout's
          `financialAccountId`, which is the payout's own concern, never the
          sender's.
      description: >-
        One thing a capability lets the holding account do in a money-movement
        flow.


        The set is append-only: a new member arrives as its product surface
        ships, and an existing

        member never changes meaning, so tolerate a member you do not recognize.
      example: RECEIVE_PAYOUTS
    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.
    Repatriability:
      type: string
      enum:
        - REPATRIABLE
        - NON_REPATRIABLE
      x-enum-descriptions:
        REPATRIABLE: >-
          Covers destinations declaring `isNre: true`: NRE accounts, funded from
          abroad, whose balance may move back out freely, principal and interest
          both.
        NON_REPATRIABLE: >-
          Covers destinations declaring `isNre: false`: an NRO account or an
          ordinary resident-held one, where moving the balance out again is
          restricted.
      description: |-
        A capital-control account category a capability's coverage is scoped to.

        The set is append-only, so tolerate a member you do not recognize.
      example: REPATRIABLE
    IndividualIdentity:
      type: object
      properties:
        firstName:
          description: Given names, in the order the person writes them.
          example: Nadia
          type: string
        lastName:
          type: string
          description: >-
            Family name. A person who goes by a single name puts the whole of it
            here, rather than repeating it or inventing a given name.
          example: Mehta
        dateOfBirth:
          $ref: '#/components/schemas/CalendarDate'
          description: The person's date of birth.
          example: '1990-03-14'
        nationality:
          $ref: '#/components/schemas/CountryCode'
          description: >-
            The country whose nationality the person holds. Single-valued, so a
            dual national is recorded under one of theirs.
          example: IN
        email:
          $ref: '#/components/schemas/EmailAddress'
          description: The person's own email address.
          example: nadia.mehta@novalia.example
        phoneNumber:
          $ref: '#/components/schemas/PhoneNumber'
          description: The person's own phone number.
          example: '+919876543210'
        residentialAddress:
          $ref: '#/components/schemas/Address'
          description: Where the person lives.
        taxInformation:
          description: >-
            The tax identifiers this person holds, one entry per issuing
            country. An Indian PAN belongs here: an entry whose `issuingCountry`
            is India and whose `taxIdNumber` carries the PAN itself.
          type: array
          items:
            $ref: '#/components/schemas/TaxInformation'
        documents:
          type: array
          items:
            $ref: '#/components/schemas/IndividualDocument'
      required:
        - lastName
      additionalProperties: false
      description: A natural person's identity information.
    OrganizationIdentity:
      type: object
      properties:
        legalName:
          type: string
          description: >-
            The organization's name exactly as the register it is incorporated
            in records it, suffix included.
          example: Novalia Handels GmbH
        doingBusinessAs:
          description: >-
            The trading name the organization is known by, where that differs
            from the legal name.
          example: Novalia
          type: string
        contactEmail:
          $ref: '#/components/schemas/EmailAddress'
          description: >-
            An address that reaches the organization. A channel into the
            company, not any one person's own address.
          example: treasury@novalia.example
        registrationNumber:
          description: >-
            The organization's number in the public register it is incorporated
            in. Which register that is follows from `registeredAddress`.
          example: HRB 123456
          type: string
        dateOfIncorporation:
          $ref: '#/components/schemas/CalendarDate'
          description: >-
            The date the organization was constituted. Separates same-named
            companies the way a date of birth separates people.
          example: '2014-09-01'
        legalStructure:
          $ref: '#/components/schemas/LegalStructure'
        taxInformation:
          description: >-
            The tax identifiers this organization holds, one entry per issuing
            country. A VAT number is one of these.
          type: array
          items:
            $ref: '#/components/schemas/TaxInformation'
        registeredAddress:
          $ref: '#/components/schemas/Address'
          description: >-
            The registered office: the address on file in the register the
            organization is incorporated in, and so the address that says which
            jurisdiction issued its registration number.
        principalPlaceOfBusiness:
          $ref: '#/components/schemas/Address'
          description: >-
            Where the organization operates from, where that differs from the
            registered office.
        documents:
          description: The documents this organization holds.
          type: array
          items:
            $ref: '#/components/schemas/OrganizationDocument'
        associations:
          description: >-
            The people and companies that own or control this organization, one
            entry each.
          type: array
          items:
            $ref: '#/components/schemas/Association'
        phoneNumber:
          $ref: '#/components/schemas/PhoneNumber'
          description: >-
            A phone number that reaches the organization. A line into the
            company, not any one person's own number.
          example: '+525512345678'
        website:
          description: The organization's public website, as an absolute http or https URL.
          example: https://novalia.example
          type: string
          maxLength: 2048
        industry:
          $ref: '#/components/schemas/Industry'
      required:
        - legalName
      additionalProperties: false
      description: >-
        An organization's identity.


        The register entry that establishes the organization exists, plus the
        people and companies

        behind it in `associations`.
    CalendarDate:
      type: string
      format: date
      pattern: >-
        ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))$
      description: >-
        A calendar date, `YYYY-MM-DD`.


        A date as a calendar writes it, not an instant: it carries no clock time
        and no zone, so it

        reads the same everywhere. Distinct from `Timestamp`, which is an
        absolute instant and whose

        field names end in `At`.
    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.
    EmailAddress:
      type: string
      maxLength: 255
      format: email
      pattern: >-
        ^(?!\.)(?!.*\.\.)([A-Za-z0-9_'+\-\.]*)[A-Za-z0-9_+-]@([A-Za-z0-9][A-Za-z0-9\-]*\.)+[A-Za-z]{2,}$
      description: >-
        An email address, at most 255 characters.


        Checked for a well-formed shape only. OpenFX never sends to it, so
        nothing here establishes

        that the mailbox exists or that anyone reads it.
    PhoneNumber:
      type: string
      pattern: ^\+[1-9]\d{1,14}$
      description: >-
        A phone number in E.164 form, matching `^\+[1-9]\d{1,14}$`.


        A leading `+`, then the country calling code, then the subscriber
        number, with no spaces,

        hyphens, parentheses or leading trunk zero. A number written in a
        national format is

        rejected rather than guessed at.
    Address:
      type: object
      properties:
        line1:
          description: Street name and number.
          example: Friedrichstraße 100
          type: string
        line2:
          description: A second street line, for a floor, a unit or a care-of name.
          example: Floor 3
          type: string
        city:
          description: City or locality.
          example: Berlin
          type: string
        state:
          description: >-
            State, province or region. No format is claimed, so write it as the
            country's own post would.
          example: Berlin
          type: string
        postalCode:
          description: Postal or ZIP code.
          example: '10117'
          type: string
        country:
          $ref: '#/components/schemas/CountryCode'
          description: The country the address is in.
          example: DE
      required:
        - country
      additionalProperties: false
      description: A postal address.
    TaxInformation:
      type: object
      properties:
        issuingCountry:
          $ref: '#/components/schemas/CountryCode'
          description: The country whose authority issued the identifier.
          example: IN
        taxIdNumber:
          type: string
          description: >-
            The identifier itself, as the issuing authority writes it,
            punctuation included.
          example: ABCDE1234F
      required:
        - issuingCountry
        - taxIdNumber
      additionalProperties: false
      description: A tax identifier and the country that issued it.
    IndividualDocument:
      type: object
      properties:
        type:
          $ref: '#/components/schemas/IndividualDocumentType'
        issuingCountry:
          $ref: '#/components/schemas/CountryCode'
          description: The country the document was issued in.
          example: IN
      required:
        - type
        - issuingCountry
      additionalProperties: false
      description: >-
        A document the identity holds.


        A record that the document exists, not the file itself: there is no
        upload surface.
    LegalStructure:
      type: string
      enum:
        - PUBLIC_LISTED_COMPANY
        - PRIVATE_LIMITED
        - SOLE_TRADER
        - NON_PROFIT
        - GENERAL_PARTNERSHIP
        - LIMITED_PARTNERSHIP
      x-enum-descriptions:
        PUBLIC_LISTED_COMPANY: >-
          Shares trade on a public exchange, so ownership is dispersed and
          already disclosed through the exchange.
        PRIVATE_LIMITED: >-
          Limited liability with privately held shares, so ownership is visible
          only in what the organization declares.
        SOLE_TRADER: >-
          No legal personality separate from the one person trading, so there is
          no ownership to apportion and no board to appoint.
        NON_PROFIT: >-
          Constituted so that nobody holds a distributable stake, with control
          in the hands of trustees or a board rather than owners.
        GENERAL_PARTNERSHIP: >-
          Partners share control and each carries unlimited liability for the
          whole.
        LIMITED_PARTNERSHIP: >-
          At least one partner's liability is capped, and a capped partner
          conventionally takes no part in running the business.
      description: |-
        The form an organization is constituted in.

        A trust is not yet representable here.
      example: PRIVATE_LIMITED
    OrganizationDocument:
      type: object
      properties:
        type:
          $ref: '#/components/schemas/OrganizationDocumentType'
        issuingCountry:
          $ref: '#/components/schemas/CountryCode'
          description: The country the document was issued in.
          example: IN
      required:
        - type
        - issuingCountry
      additionalProperties: false
      description: >-
        A document the identity holds.


        A record that the document exists, not the file itself: there is no
        upload surface.
    Association:
      oneOf:
        - $ref: '#/components/schemas/IndividualAssociation'
        - $ref: '#/components/schemas/OrganizationAssociation'
      description: >-
        A person or company that owns or controls an organization, discriminated
        on

        `identityType`; exactly one variant is ever present.


        A new variant may ship additively, so tolerate an unrecognized
        `identityType`.
      type: object
      discriminator:
        propertyName: identityType
        mapping:
          INDIVIDUAL: '#/components/schemas/IndividualAssociation'
          ORGANIZATION: '#/components/schemas/OrganizationAssociation'
    Industry:
      type: string
      enum:
        - AGRICULTURE
        - ENERGY_AND_MINING
        - MANUFACTURING
        - CONSTRUCTION_AND_REAL_ESTATE
        - WHOLESALE_AND_IMPORT_EXPORT
        - RETAIL
        - MARKETPLACE
        - LOGISTICS_AND_TRANSPORTATION
        - TRAVEL_AND_HOSPITALITY
        - SOFTWARE_AND_TECHNOLOGY
        - TELECOMMUNICATIONS
        - PAYMENT_SERVICES
        - BANKING_AND_LENDING
        - INVESTMENT_SERVICES
        - INSURANCE
        - DIGITAL_ASSETS
        - PROFESSIONAL_SERVICES
        - STAFFING_AND_PAYROLL
        - EDUCATION
        - HEALTHCARE
        - MEDIA_AND_ENTERTAINMENT
        - GAMING_AND_GAMBLING
        - OTHER
      x-enum-descriptions:
        AGRICULTURE: >-
          Growing, raising or harvesting, fishing and forestry included, before
          any processing.
        ENERGY_AND_MINING: >-
          Extracting resources or generating power: mining, oil and gas, and
          electricity supply.
        MANUFACTURING: >-
          Making goods, food processing included, whoever the organization then
          sells them to.
        CONSTRUCTION_AND_REAL_ESTATE: Building, and owning, letting or brokering property.
        WHOLESALE_AND_IMPORT_EXPORT: >-
          Selling goods in bulk to other businesses, within one country or
          across borders. Commodity trading belongs here.
        RETAIL: >-
          Selling goods to consumers through the organization's own stores or
          site. A platform selling other merchants' goods is `MARKETPLACE`
          instead.
        MARKETPLACE: >-
          Running a platform on which other merchants or workers sell to buyers,
          and paying them out as sellers.
        LOGISTICS_AND_TRANSPORTATION: 'Moving goods or people: freight, shipping, couriers and warehousing.'
        TRAVEL_AND_HOSPITALITY: Accommodation, food service, travel agencies and tour operators.
        SOFTWARE_AND_TECHNOLOGY: >-
          Building or selling software, hosting or IT services, where the
          product is not itself a financial service.
        TELECOMMUNICATIONS: 'Carrying voice or data: carriers and internet access.'
        PAYMENT_SERVICES: >-
          Moving money on behalf of others, as a payment institution, money
          transmitter or payment facilitator, without taking deposits.
        BANKING_AND_LENDING: >-
          Taking deposits or extending credit. A payments business that does
          neither is `PAYMENT_SERVICES`.
        INVESTMENT_SERVICES: >-
          Managing, trading or advising on investments for others, brokerage
          included.
        INSURANCE: Underwriting or brokering insurance.
        DIGITAL_ASSETS: >-
          Issuing, exchanging or holding cryptoassets or stablecoins on behalf
          of others.
        PROFESSIONAL_SERVICES: >-
          Legal, accounting, consulting, marketing and similar services billed
          by the engagement.
        STAFFING_AND_PAYROLL: >-
          Placing or paying workers on behalf of other businesses,
          employer-of-record and contractor-payment platforms included.
        EDUCATION: Schools, universities and training, online or in person.
        HEALTHCARE: Care, pharmaceuticals and medical devices.
        MEDIA_AND_ENTERTAINMENT: >-
          Publishing, broadcasting, streaming, advertising and live events.
          Games and betting are `GAMING_AND_GAMBLING` instead.
        GAMING_AND_GAMBLING: Video games, betting and lotteries.
        OTHER: A sector no other member describes.
      description: >-
        The business sector an organization operates in, named by its main
        activity.


        One value, so an organization active in several sectors names the one
        most of its revenue

        comes from. The set is append-only, so tolerate a member you do not
        recognize.
      example: MARKETPLACE
    IndividualDocumentType:
      type: string
      enum:
        - PASSPORT
        - NATIONAL_ID
        - DRIVERS_LICENSE
        - SSN
        - RESIDENCE_PERMIT
      x-enum-descriptions:
        PASSPORT: >-
          Issued for international travel, so its number is the one that appears
          alongside names on international sanctions lists.
        NATIONAL_ID: >-
          Issued by a person's own country for domestic identification, and held
          by residents who may never hold a passport.
        DRIVERS_LICENSE: >-
          A driving entitlement that carries a photo, accepted as proof of
          identity where a person holds neither a passport nor a national id.
        SSN: >-
          A United States Social Security number, recorded here rather than in
          `taxInformation`. It carries no photo, and its `issuingCountry` is US.
        RESIDENCE_PERMIT: >-
          Issued by a country to a foreign national living there, such as
          Colombia's cédula de extranjería. `issuingCountry` is the country of
          residence, not the holder's nationality.
      description: The kind of document a person holds.
      example: PASSPORT
    OrganizationDocumentType:
      type: string
      enum:
        - REGISTRATION_DOCUMENT
        - CONSTITUTIONAL_DOCUMENT
        - PROOF_OF_OWNERSHIP
        - PROOF_OF_ADDRESS
        - PROOF_OF_TAX_INFORMATION
      x-enum-descriptions:
        REGISTRATION_DOCUMENT: >-
          The organization's entry in the public register it is incorporated in,
          which is what `registrationNumber` is taken from.
        CONSTITUTIONAL_DOCUMENT: >-
          The founding document, for a form that has no register entry to point
          at: a partnership deed or a trust instrument rather than a
          certificate.
        PROOF_OF_OWNERSHIP: >-
          Evidence of who ultimately owns or controls the organization, backing
          what `associations` declares.
        PROOF_OF_ADDRESS: >-
          Evidence that the organization is at the address it gives, a utility
          bill or a lease rather than anything a register issued.
        PROOF_OF_TAX_INFORMATION: >-
          Evidence of a tax registration, backing an entry in `taxInformation`.
          A VAT registration certificate is one of these.
      description: |-
        The kind of document an organization holds.

        Each member evidences something the organization block already asserts.
      example: REGISTRATION_DOCUMENT
    IndividualAssociation:
      type: object
      properties:
        identityType:
          type: string
          const: INDIVIDUAL
        role:
          $ref: '#/components/schemas/IndividualAssociationType'
        individual:
          $ref: '#/components/schemas/IndividualIdentity'
          description: Who this person is.
        ownershipPercent:
          description: >-
            The share of the organization this identity holds, as a percentage.
            Control without shareholding leaves no share to state.
          example: 40
          type: number
          minimum: 0
          maximum: 100
      required:
        - identityType
        - role
        - individual
      additionalProperties: false
      title: Individual association
      description: >-
        A natural person who owns or controls the organization, in the capacity
        `role` names.
    OrganizationAssociation:
      type: object
      properties:
        identityType:
          type: string
          const: ORGANIZATION
        role:
          $ref: '#/components/schemas/OrganizationAssociationType'
        organization:
          $ref: '#/components/schemas/OrganizationIdentity'
        ownershipPercent:
          description: >-
            The share of the organization this identity holds, as a percentage.
            Control without shareholding leaves no share to state.
          example: 40
          type: number
          minimum: 0
          maximum: 100
      required:
        - identityType
        - role
        - organization
      additionalProperties: false
      title: Organization association
      description: >-
        A company that owns or controls the organization, in the capacity `role`
        names.
    IndividualAssociationType:
      type: string
      enum:
        - UBO_THROUGH_OWNERSHIP
        - UBO_THROUGH_CONTROL
        - DIRECTOR
        - SIGNATORY
        - AUTHORIZED_REPRESENTATIVE
      x-enum-descriptions:
        UBO_THROUGH_OWNERSHIP: >-
          A beneficial owner by shareholding, so their stake is a percentage of
          the organization.
        UBO_THROUGH_CONTROL: >-
          A beneficial owner by control instead, through voting rights or the
          power to appoint the board, so no percentage describes them.
        DIRECTOR: Appointed to the board. A management position, which implies no stake.
        SIGNATORY: >-
          Authorized to commit the organization on one specific mandate, a
          single bank account for instance, and nothing wider.
        AUTHORIZED_REPRESENTATIVE: >-
          Authorized to represent and sign for the organization generally,
          rather than on one mandate.
      description: How a natural person is associated with an organization.
      example: UBO_THROUGH_OWNERSHIP
    OrganizationAssociationType:
      type: string
      enum:
        - ULTIMATE_PARENT_COMPANY
      x-enum-descriptions:
        ULTIMATE_PARENT_COMPANY: >-
          Sits at the top of the ownership chain, so nothing owns it in turn and
          the chain of declared parents ends there.
      description: How an organization is associated with another organization.
      example: ULTIMATE_PARENT_COMPANY
  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.

````