openapi: 3.1.0
info:
  title: Element Pay Partner API
  description: |
    Provider-neutral fiat ↔ crypto ramps for partners. Discover corridors, create a binding quote, accept it, and receive webhooks. African local fiat (mobile money and bank) is auto-routed by corridor.

    ## Agent / integrator notes

    - Canonical machine-readable contract: `openapi.yaml` (this document) and `openapi.json`.
    - Human/agent quickstart: `docs/agents.md` - local fiat <-> USDC/USDT: `docs/integration-fiat-stablecoin.md` - gaps: `docs/KNOWN_GAPS.md`.
    - All partner routes are under `/partner/*` relative to the server base URL.
    - Settlement source of truth: webhooks (see `webhooks` section); poll `GET /partner/orders/{order_id}` as backup.
  version: 1.0.0
paths:
  /partner/rates/indicative:
    get:
      tags:
      - partner
      summary: Indicative corridor fiat vs USD rates
      description: Returns **indicative** `buy` / `sell` rates for comma-separated ISO fiat codes (corridor **fiat vs USD**
        tickers).
      operationId: partner_indicative_rates_partner_rates_indicative_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: fiat
        in: query
        required: true
        schema:
          type: string
          description: Comma-separated ISO 4217 codes (e.g. `NGN,KES,GHS`).
          examples:
          - NGN,KES,GHS
          title: Fiat
        description: Comma-separated ISO 4217 codes (e.g. `NGN,KES,GHS`).
      responses:
        '200':
          description: Indicative fiat vs USD rates (non-binding)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
              example:
                status: success
                message: Indicative rates (non-binding)
                data:
                  requested:
                  - KES
                  - NGN
                  - UGX
                  fetched_at: '2026-07-07T10:00:00Z'
                  rates:
                  - currency: KES
                    buy: 131.5
                    sell: 128.0
                  - currency: NGN
                    buy: 1580.0
                    sell: 1550.0
              examples:
                kes_ngn_ugx:
                  summary: East Africa tickers
                  value:
                    status: success
                    message: Indicative rates (non-binding)
                    data:
                      requested:
                      - KES
                      - NGN
                      - UGX
                      fetched_at: '2026-07-07T10:00:00Z'
                      rates:
                      - currency: KES
                        buy: 131.5
                        sell: 128.0
                      - currency: NGN
                        buy: 1580.0
                        sell: 1550.0
        '400':
          description: Invalid `fiat` query parameter
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Invalid fiat code 'XX'; use three-letter ISO 4217 codes (e.g. NGN,KES).
                data:
                  field: fiat
              examples:
                invalid_fiat_code:
                  summary: Unrecognized ISO code
                  value:
                    status: error
                    message: Invalid fiat code 'XX'; use three-letter ISO 4217 codes (e.g. NGN,KES).
                    data:
                      field: fiat
        '422':
          description: Missing required query parameters
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Query parameter `fiat` is required (e.g. fiat=NGN,KES,GHS).
                data:
                  field: fiat
              examples:
                missing_fiat:
                  summary: fiat query param omitted
                  value:
                    status: error
                    message: Query parameter `fiat` is required (e.g. fiat=NGN,KES,GHS).
                    data:
                      field: fiat
        '502':
          description: Upstream discovery temporarily unavailable
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Quote request failed
                data:
                  upstream_http_status: 502
              examples:
                upstream_unavailable:
                  summary: Discovery upstream error
                  value:
                    status: error
                    message: Quote request failed
                    data:
                      upstream_http_status: 502
      x-mint:
        content: |-
          Returns **indicative** `buy` / `sell` rates for comma-separated ISO fiat codes (corridor **fiat vs USD** tickers).

          <Warning>
          These rates are **not** binding.

          - Corridor checkout pricing: [`POST /partner/orders/quote`](/partner/orders/quote)
          - Ledger **cross-currency** convert: use [`conversions/preview`](/customers/conversions) for the binding pair rate — do not treat these tickers as the convert price
          </Warning>

          Response `data` includes `requested`, `rates`, and `fetched_at`.

          **Auth:** `X-API-Key` header.
  /partner/corridors:
    get:
      tags:
      - partner
      summary: Supported partner corridors (African markets and international bank)
      description: Indicative catalog for partner checkout UI.
      operationId: partner_corridors_partner_corridors_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: country
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Filter African markets by ISO country.
          title: Country
        description: Filter African markets by ISO country.
      - name: currency
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Filter by fiat currency (e.g. KES, EUR).
          title: Currency
        description: Filter by fiat currency (e.g. KES, EUR).
      - name: order_type
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Filter by order type: OnRamp (buy) or OffRamp (sell).'
          examples:
          - OnRamp
          - OffRamp
          title: Order Type
        description: 'Filter by order type: OnRamp (buy) or OffRamp (sell).'
      responses:
        '200':
          description: Supported corridors (indicative)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
              example:
                status: success
                message: Partner corridors (indicative)
                data:
                  african_markets:
                  - country: KE
                    currency: KES
                    onramp: true
                    offramp: true
                  international_bank:
                    currencies:
                    - currency: EUR
                      onramp: true
                      offramp: false
                    - currency: USD
                      onramp: true
                      offramp: false
              examples:
                corridors_ke:
                  summary: Filter KE
                  value:
                    status: success
                    message: Partner corridors (indicative)
                    data:
                      african_markets:
                      - country: KE
                        currency: KES
                        onramp: true
                        offramp: true
                      international_bank:
                        currencies:
                        - currency: EUR
                          onramp: true
                          offramp: false
                        - currency: USD
                          onramp: true
                          offramp: false
        '400':
          description: Bad request (missing corridor parameters or rail resolution failed)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Provide country for African corridors (e.g. KE) or currency for international bank (EUR/USD).
                data: null
        '422':
          description: Validation error (corridor not supported or invalid parameters)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Corridor not supported on this environment.
                data:
                  currency: EUR
                  country: FR
        '502':
          description: Upstream discovery temporarily unavailable
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Quote request failed
                data:
                  upstream_http_status: 502
              examples:
                upstream_unavailable:
                  summary: Discovery upstream error
                  value:
                    status: error
                    message: Quote request failed
                    data:
                      upstream_http_status: 502
      x-mint:
        content: |-
          Indicative catalog for partner checkout UI.

          ### African markets (`african_markets`)
          Local fiat corridors: **country**, **currency**, and **onramp** / **offramp** flags.

          Optional filters: `country`, `currency`, `order_type` (`OnRamp` | `OffRamp`).

          ### International bank (`international_bank`)
          EUR/USD bank transfer **payin** — **currency only** (do not pass ISO country).

          <Note>
          Binding eligibility is confirmed at [`POST /partner/orders/quote`](/partner/orders/quote).
          </Note>
  /partner/catalog:
    get:
      tags:
      - partner
      summary: Checkout catalog (corridors, methods, and providers)
      description: |-
        Single indicative catalog for partner checkout: per-country onramp/offramp, `mobile_money` and `bank` buckets with live provider lists, optional `rails` for international payout markets, and `international_bank` for EUR/USD payin.
      operationId: partner_catalog_partner_catalog_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: country
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Filter by ISO country (e.g. KE).
          title: Country
        description: Filter by ISO country (e.g. KE).
      - name: currency
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Filter by fiat currency (e.g. KES, EUR).
          title: Currency
        description: Filter by fiat currency (e.g. KES, EUR).
      - name: order_type
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: 'Filter by order type: OnRamp (buy) or OffRamp (sell).'
          examples:
          - OnRamp
          - OffRamp
          title: Order Type
        description: 'Filter by order type: OnRamp (buy) or OffRamp (sell).'
      responses:
        '200':
          description: Checkout catalog (corridors, methods, providers)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
              example:
                status: success
                message: Supported corridors and payment methods
                data:
                  disclaimer: 'Indicative catalog. Binding eligibility and price: POST /api/v1/partner/orders/quote.'
                  onramp:
                    countries:
                      KE:
                        country_code: KE
                        country_name: Kenya
                        currency: KES
                        enabled: true
                        payment_methods:
                          mobile_money:
                            enabled: true
                            label: Mobile Money
                            quote_type: mobile_money
                            providers:
                            - code: M PESA
                              name: Mobile Wallet (M-PESA)
                              enabled: true
                              id: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
                              min_amount: 150
                              max_amount: 250000
                              currency: KES
                          bank:
                            enabled: true
                            label: Bank Transfer
                            quote_type: bank
                            providers:
                            - code: NATIONAL_BANK_OF_KENYA
                              name: NATIONAL BANK OF KENYA
                              enabled: true
                              id: 30f11b2e-0905-4c09-ba5f-d05aa4e4a11c
                              min_amount: 300
                              max_amount: 99999999
                              currency: KES
              examples:
                ke_onramp_catalog:
                  summary: KE OnRamp catalog slice
                  value:
                    status: success
                    message: Supported corridors and payment methods
                    data:
                      disclaimer: 'Indicative catalog. Binding eligibility and price: POST /api/v1/partner/orders/quote.'
                      onramp:
                        countries:
                          KE:
                            country_code: KE
                            country_name: Kenya
                            currency: KES
                            enabled: true
                            payment_methods:
                              mobile_money:
                                enabled: true
                                label: Mobile Money
                                quote_type: mobile_money
                                providers:
                                - code: M PESA
                                  name: Mobile Wallet (M-PESA)
                                  enabled: true
                                  id: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
                                  min_amount: 150
                                  max_amount: 250000
                                  currency: KES
                              bank:
                                enabled: true
                                label: Bank Transfer
                                quote_type: bank
                                providers: []
        '400':
          description: Bad request (missing corridor parameters or rail resolution failed)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Provide country for African corridors (e.g. KE) or currency for international bank (EUR/USD).
                data: null
        '422':
          description: Validation error (corridor not supported or invalid parameters)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Corridor not supported on this environment.
                data:
                  currency: EUR
                  country: FR
        '502':
          description: Upstream discovery temporarily unavailable
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Quote request failed
                data:
                  upstream_http_status: 502
              examples:
                upstream_unavailable:
                  summary: Discovery upstream error
                  value:
                    status: error
                    message: Quote request failed
                    data:
                      upstream_http_status: 502
      x-mint:
        content: |-
          Single indicative catalog for partner checkout: per-country onramp/offramp, `mobile_money` and `bank` buckets with live provider lists, optional `rails` for international payout markets, and `international_bank` for EUR/USD payin.

          ### Provider IDs
          `providers[].id` is the opaque institution UUID to send as `payment_method.network_id` on quote. Bank rows may also use [`GET /partner/banks`](/partner/banks).

          Each provider includes `min_amount`, `max_amount`, and `currency` for checkout validation.

          <Warning>
          **OnRamp and OffRamp provider lists can differ** for the same country — filter with `order_type`.
          </Warning>

          Optional filters: `country`, `currency`, `order_type`. Omit filters for the full tree.

          <Note>
          Binding eligibility: [`POST /partner/orders/quote`](/partner/orders/quote).
          </Note>
  /partner/payment-methods:
    get:
      tags:
      - partner
      summary: Payment method types for a corridor
      description: Indicative payment methods for one corridor.
      operationId: partner_payment_methods_partner_payment_methods_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: country
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: ISO country (required for African corridors, e.g. KE).
          title: Country
        description: ISO country (required for African corridors, e.g. KE).
      - name: currency
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Optional for African (validated against catalog). Required for international_bank (EUR/USD).
          title: Currency
        description: Optional for African (validated against catalog). Required for international_bank (EUR/USD).
      - name: order_type
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: OnRamp or OffRamp; omit for both onramp and offramp buckets.
          examples:
          - OnRamp
          - OffRamp
          title: Order Type
        description: OnRamp or OffRamp; omit for both onramp and offramp buckets.
      responses:
        '200':
          description: Payment methods for the requested corridor
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
              example:
                status: success
                message: Partner payment methods (indicative)
                data:
                  context:
                    country: KE
                    currency: KES
                  onramp:
                  - type: mobile_money
                    status: active
                    networks:
                    - id: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
                      name: Safaricom M-PESA
                      min_amount: 100
                      max_amount: 250000
                      currency: KES
                  - type: bank
                    status: active
                    networks: []
                  offramp:
                  - type: mobile_money
                    status: active
                    networks: []
                  - type: bank
                    status: active
                    networks: []
        '400':
          description: Bad request (missing corridor parameters or rail resolution failed)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Provide country for African corridors (e.g. KE) or currency for international bank (EUR/USD).
                data: null
        '422':
          description: Validation error (corridor not supported or invalid parameters)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Corridor not supported on this environment.
                data:
                  currency: EUR
                  country: FR
        '502':
          description: Upstream discovery temporarily unavailable
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Quote request failed
                data:
                  upstream_http_status: 502
              examples:
                upstream_unavailable:
                  summary: Discovery upstream error
                  value:
                    status: error
                    message: Quote request failed
                    data:
                      upstream_http_status: 502
      x-mint:
        content: |-
          Indicative payment methods for one corridor.

          ### African corridors
          - **`country`** — required
          - **`currency`** — optional; must match the catalog when sent; response `context` always includes both
          - **`order_type`** — `OnRamp` or `OffRamp`; omit to get both `onramp` and `offramp` buckets

          ### International bank
          - **`currency`** = EUR or USD (required)
          - Do **not** pass `country`
          - EUR/USD onramp returns `bank`
          - Offramp uses international bank when configured

          ### International bank payout markets
          Example: FR + EUR offramp — pass `country` + `currency`. Returns rails such as `BankSepa` and `BankSwift` with `type` set to the international bank `PaymentMethodType`.

          ### Local fiat (African)
          `mobile_money` and `bank` rows include a **`networks[]`** list (`id`, `name`, `min_amount`, `max_amount`, `currency`) for client-side amount gating.

          <Note>
          Binding check: [`POST /partner/orders/quote`](/partner/orders/quote).
          </Note>
  /partner/order-requirements:
    get:
      tags:
      - partner
      summary: Indicative order field requirements for a corridor
      description: Returns partner-neutral **field name** hints before [`POST /partner/orders/quote`](/partner/orders/quote).
      operationId: partner_order_requirements_partner_order_requirements_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: country
        in: query
        required: true
        schema:
          type: string
          minLength: 2
          maxLength: 2
          description: ISO country code.
          title: Country
        description: ISO country code.
      - name: currency
        in: query
        required: true
        schema:
          type: string
          minLength: 3
          maxLength: 3
          description: Fiat currency code.
          title: Currency
        description: Fiat currency code.
      - name: order_type
        in: query
        required: true
        schema:
          type: string
          description: OnRamp or OffRamp.
          examples:
          - OffRamp
          title: Order Type
        description: OnRamp or OffRamp.
      - name: customer_type
        in: query
        required: false
        schema:
          type: string
          description: retail or institution — affects required customer fields on local fiat rail corridors.
          default: retail
          title: Customer Type
        description: retail or institution — affects required customer fields on local fiat rail corridors.
      - name: payment_method_type
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: |-
            Narrows payment_method requirements: mobile_money | bank (rail) or international bank PaymentMethodType from payment-methods (e.g. BankLocal).
          title: Payment Method Type
        description: |-
          Narrows payment_method requirements: mobile_money | bank (rail) or international bank PaymentMethodType from payment-methods (e.g. BankLocal).
      responses:
        '200':
          description: Indicative field requirements before quote
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
              example:
                status: success
                message: Partner order requirements (indicative)
                data:
                  context:
                    country: KE
                    currency: KES
                    order_type: OnRamp
                    payment_method_type: mobile_money
                  customer:
                  - name
                  - phone
                  - dob
                  - id_number
                  - id_type
                  payment_method:
                  - type
                  - phone_number
                  - network_id
                  order:
                  - wallet_address
                  - local_amount
                  - asset
              examples:
                ke_momo_onramp:
                  summary: KE momo OnRamp
                  value:
                    status: success
                    message: Partner order requirements (indicative)
                    data:
                      context:
                        country: KE
                        currency: KES
                        order_type: OnRamp
                        payment_method_type: mobile_money
                      customer:
                      - name
                      - phone
                      - dob
                      - id_number
                      - id_type
                      payment_method:
                      - type
                      - phone_number
                      - network_id
                      order:
                      - wallet_address
                      - local_amount
                      - asset
        '400':
          description: Bad request (missing corridor parameters or rail resolution failed)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Provide country for African corridors (e.g. KE) or currency for international bank (EUR/USD).
                data: null
        '422':
          description: Validation error (corridor not supported or invalid parameters)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Corridor not supported on this environment.
                data:
                  currency: EUR
                  country: FR
        '502':
          description: Upstream discovery temporarily unavailable
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Quote request failed
                data:
                  upstream_http_status: 502
              examples:
                upstream_unavailable:
                  summary: Discovery upstream error
                  value:
                    status: error
                    message: Quote request failed
                    data:
                      upstream_http_status: 502
      x-mint:
        content: |-
          Returns partner-neutral **field name** hints before [`POST /partner/orders/quote`](/partner/orders/quote).

          Call after [`GET /partner/corridors`](/partner/corridors) and [`GET /partner/payment-methods`](/partner/payment-methods).

          ### Query
          `country`, `currency`, `order_type` (`OnRamp` or `OffRamp`).

          When several payout rails exist, list them with [`GET /partner/payment-methods`](/partner/payment-methods) first, then pass `payment_method_type` (e.g. `BankSepa`) on this call. Single-rail international bank corridors (e.g. GH) may omit it.

          ### Rails
          - **`mobile_money`** or **`bank`** — both require `network_id` on quote (from catalog `providers[].id` or [`GET /partner/banks`](/partner/banks) for bank)
          - Optional **`customer_type`** (`retail` or `institution`) on local fiat corridors

          This endpoint does **not** return JSON Schema, bank lists, fees, or provider labels. Bank lists and dynamic form schemas are separate partner endpoints (see [Quickstart](/quickstart)).

          <Note>
          Binding check: [`POST /partner/orders/quote`](/partner/orders/quote).
          </Note>
  /partner/banks:
    get:
      tags:
      - partner
      summary: Indicative bank/network options for a rail
      description: Lists bank/network institution options for a rail chosen via [`GET /partner/payment-methods`](/partner/payment-methods).
      operationId: partner_banks_partner_banks_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: country
        in: query
        required: true
        schema:
          type: string
          minLength: 2
          maxLength: 2
          description: ISO country code.
          title: Country
        description: ISO country code.
      - name: currency
        in: query
        required: true
        schema:
          type: string
          minLength: 3
          maxLength: 3
          description: Fiat currency code.
          title: Currency
        description: Fiat currency code.
      - name: order_type
        in: query
        required: true
        schema:
          type: string
          description: OnRamp or OffRamp.
          examples:
          - OffRamp
          title: Order Type
        description: OnRamp or OffRamp.
      - name: payment_method_type
        in: query
        required: true
        schema:
          type: string
          description: |-
            Rail id from ``GET /payment-methods``: rail uses ``mobile_money`` or ``bank``; international bank uses ``PaymentMethodType`` values like ``BankSepa``.
          title: Payment Method Type
        description: |-
          Rail id from ``GET /payment-methods``: rail uses ``mobile_money`` or ``bank``; international bank uses ``PaymentMethodType`` values like ``BankSepa``.
      responses:
        '200':
          description: Bank institution options for bank rail
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
              example:
                status: success
                message: Partner bank/network options (indicative)
                data:
                  disclaimer: 'Indicative. Binding check: POST /api/v1/partner/orders/quote.'
                  context:
                    country: NG
                    currency: NGN
                    order_type: OnRamp
                    payment_method_type: bank
                  supported: true
                  message: Active bank networks for this corridor.
                  banks:
                  - id: 5f1af11b-305f-4420-8fce-65ed2725a409
                    name: Access Bank
              examples:
                ng_bank_onramp:
                  summary: NG bank OnRamp banks
                  value:
                    status: success
                    message: Partner bank/network options (indicative)
                    data:
                      disclaimer: 'Indicative. Binding check: POST /api/v1/partner/orders/quote.'
                      context:
                        country: NG
                        currency: NGN
                        order_type: OnRamp
                        payment_method_type: bank
                      supported: true
                      message: Active bank networks for this corridor.
                      banks:
                      - id: 5f1af11b-305f-4420-8fce-65ed2725a409
                        name: Access Bank
        '400':
          description: Bad request (missing corridor parameters or rail resolution failed)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Provide country for African corridors (e.g. KE) or currency for international bank (EUR/USD).
                data: null
        '422':
          description: Validation error (corridor not supported or invalid parameters)
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Corridor not supported on this environment.
                data:
                  currency: EUR
                  country: FR
        '502':
          description: Upstream discovery temporarily unavailable
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      country:
                        type: string
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Quote request failed
                data:
                  upstream_http_status: 502
              examples:
                upstream_unavailable:
                  summary: Discovery upstream error
                  value:
                    status: error
                    message: Quote request failed
                    data:
                      upstream_http_status: 502
      x-mint:
        content: |-
          Lists bank/network institution options for a rail chosen via [`GET /partner/payment-methods`](/partner/payment-methods).

          ### Query
          `country`, `currency`, `order_type` (`OnRamp` | `OffRamp`), and `payment_method_type`.

          ### Rails
          - **`bank`** (local fiat) — active networks only; use returned `banks[].id` as `payment_method.network_id` on quote
          - **`mobile_money`** — returns **422**; use [`GET /partner/catalog`](/partner/catalog) `providers[].id` for momo `network_id`
          - International bank types (e.g. `BankSepa`, `BankSwift`) — best-effort enum options from upstream form schema
  /partner/orders/quote:
    post:
      tags:
      - partner
      summary: Create a partner order quote
      description: Create a binding quote for a fiat ↔ crypto order.
      operationId: partner_order_quote_partner_orders_quote_post
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerOrderQuoteRequestTryIt'
            examples:
              ke_onramp_vault_customer_id:
                summary: KE OnRamp — vault customer_id (recommended)
                description: |-
                  Use an approved pcus_* from the customer vault. Discover network_id from GET /partner/catalog?country=KE&order_type=OnRamp.
                value:
                  order_type: OnRamp
                  currency: KES
                  country: KE
                  local_amount: 800
                  customer_id: pcus_a1b2c3d4e5f6
                  asset:
                    token: '0x833589fcd6edb6e08f4c7c32d4f71b54bdA02913'
                    currency: USDC
                    network: BASE
                  payment_method:
                    type: mobile_money
                    phone_number: '+2541111111111'
                    network_id: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
                  wallet_address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
              ke_offramp_vault_customer_id:
                summary: KE OffRamp — vault customer_id
                description: Customer sends USDC; receives KES by mobile money.
                value:
                  order_type: OffRamp
                  currency: KES
                  country: KE
                  crypto_amount: 20
                  customer_id: pcus_a1b2c3d4e5f6
                  asset:
                    token: '0xc2132d05d31c914a87c6611c10748aeb04b58e8f'
                    currency: USDT
                    network: POLYGON
                  payment_method:
                    type: mobile_money
                    phone_number: '+2541111111111'
                    network_id: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
                  refund_address: '0x3333333333333333333333333333333333333333'
              ke_onramp_inline_sandbox:
                summary: KE OnRamp — inline customer
                description: Inline customer object (no customer_id). Sandbox success MSISDN +2541111111111.
                value:
                  order_type: OnRamp
                  currency: KES
                  country: KE
                  local_amount: 800
                  asset:
                    token: '0x833589fcd6edb6e08f4c7c32d4f71b54bdA02913'
                    currency: USDC
                    network: BASE
                  customer:
                    uid: sandbox-ke-onramp-success-001
                    type: user
                    name: Successful Jane Customer
                    country: KE
                    phone: '+2541111111111'
                    address: Nairobi
                    dob: 02/01/1997
                    email: jane@example.com
                    id_number: A1234567
                    id_type: passport
                  payment_method:
                    type: mobile_money
                    phone_number: '+2541111111111'
                    network_id: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
                  wallet_address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
            example:
              order_type: OnRamp
              currency: KES
              country: KE
              local_amount: 800
              customer_id: pcus_a1b2c3d4e5f6
              asset:
                token: '0x833589fcd6edb6e08f4c7c32d4f71b54bdA02913'
                currency: USDC
                network: BASE
              payment_method:
                type: mobile_money
                phone_number: '+2541111111111'
                network_id: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
              wallet_address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
        required: true
      responses:
        '200':
          description: Partner order quote created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Partner order quote created
                data:
                  quote_id: yc_receive_580e04c2-a136-5cca-be54-b49fcf80970c
                  rail: local_fiat
                  status: process
                  order_type: OnRamp
                  route:
                    family: ramp_provider
                    rail: local_fiat
                    direction: payin
                    mode: auto
                    reason: Auto-routed for KE KES OnRamp.
                  expires_at: '2026-05-16T08:13:40.322Z'
                  amounts:
                    rate: 131.69
                    rate_currency: KES
                    user_pays:
                      amount: 800
                      currency: KES
                    user_receives:
                      amount: 5.94999132
                      currency: USDC
                      network: BASE
                    fees:
                      network_fee_usd: 0
                      network_fee_local: 0
                      service_fee_usd: 0.12
                      service_fee_local: 16
                      partner_fee_usd: 0
                      partner_fee_local: 0
                  instructions:
                    available_after_accept: true
                    note: Accept this quote to create the local order and receive final payment instructions.
                  audit:
                    rail: local_fiat
                    provider_quote_id: 580e04c2-a136-5cca-be54-b49fcf80970c
                    direction: payin
                    token_symbol: BASE_USDC
                    crypto_currency: USDC
                    crypto_network: BASE
        '400':
          description: Unsupported provider or rail resolution failed
          content:
            application/json:
              example:
                status: error
                message: elementpay partner order routing is not enabled yet
                data:
                  route:
                    family: native
                    direction: payin
                    mode: override
                    reason: 'Provider override requested: rail.'
                    rail: native
        '422':
          description: Validation error
          content:
            application/json:
              example:
                status: error
                message: Missing requirements for selected route
                data:
                  missing_fields:
                  - wallet_address
                  - recipient or customer
                  - source or payment_method
                  route:
                    family: ramp_provider
                    direction: payin
                    mode: auto
                    reason: Selected rail for KE KES OnRamp.
                    rail: local_fiat
        '502':
          description: Provider rejected request or upstream unavailable
          content:
            application/json:
              examples:
                local_fiat_ng_sandbox_500:
                  summary: local fiat rail sandbox upstream 500
                  value:
                    status: error
                    message: Quote request failed
                    data: null
              example:
                status: error
                message: Quote request failed
                data: null
      security:
      - APIKeyHeader: []
      x-mint:
        content: |-
          Create a binding quote for a fiat ↔ crypto order.

          <Steps>
            <Step title="Create quote">
              `POST` with corridor, customer, and payment method details.
            </Step>
            <Step title="Show pricing">
              Display returned amounts and **payment instructions** to the user (OnRamp).
            </Step>
            <Step title="Accept">
              [`POST /partner/orders/{quote_id}/accept`](/partner/orders/{quote_id}/accept) when the user confirms.
            </Step>
          </Steps>

          ### Customer identity
          Use **one** of:

          - **`customer_id`** (`pcus_*` from an **approved** [customer vault](/customers/quickstart) case) — recommended for new integrations
          - **Inline `customer`** — still supported; pick **KE OnRamp — inline customer** in Try it or fill the `customer` object

          Do not send both. Corridor-specific inline shapes: [Sandbox test payloads](/sandbox/test-payloads).

          <Note>
          Try it omits legacy top-level fields (`provider`, `channel_id`, `destination`, `rail`, …). Omit `provider` on live calls too — Element Pay auto-routes by corridor.
          </Note>

          ### Discovery before quote
          - [`GET /partner/catalog`](/partner/catalog) or [`GET /partner/payment-methods`](/partner/payment-methods) → rails for the corridor
          - [`GET /partner/catalog?order_type=OnRamp`](/partner/catalog) or `OffRamp` → `providers[].id` for momo/bank
          - [`GET /partner/order-requirements`](/partner/order-requirements) → exact field names (`network_id` required for momo/bank)
          - [`GET /partner/banks`](/partner/banks) → bank institution UUIDs where applicable

          ### Payment method by rail
          **`mobile_money`**
          - `payment_method.type=mobile_money`
          - `payment_method.phone_number` (E.164)
          - `payment_method.network_id` (UUID from catalog `providers[].id`)

          **`bank`**
          - `payment_method.type=bank`
          - `account_number`, `account_name`
          - `payment_method.network_id` (from [`GET /partner/banks`](/partner/banks) or catalog)

          ### Quote IDs
          - OnRamp: `yc_receive_<id>`
          - OffRamp: `yc_send_<id>`

          The quote expires at `data.expires_at`.
        playground:
          expand: false
  /partner/orders/{order_id}:
    get:
      tags:
      - partner
      summary: Get a partner order
      description: |-
        Returns the current status of an order created via ``POST /partner/orders/{quote_id}/accept``. Scoped to the authenticated API key. Use webhooks as the primary source of truth; this endpoint is a backup for polling when delivery is delayed.
      operationId: partner_order_get_partner_orders__order_id__get
      security:
      - APIKeyHeader: []
      parameters:
      - name: order_id
        in: path
        required: true
        schema:
          type: string
          description: Order id returned by quote accept (e.g. `rail-{preview_id}`).
          title: Order Id
        description: Order id returned by quote accept (e.g. `rail-{preview_id}`).
      responses:
        '200':
          description: Partner order snapshot
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Partner order
                data:
                  order:
                    order_id: YC-580e04c2-a136-5cca-be54-b49fcf80970c
                    quote_id: yc_receive_580e04c2-a136-5cca-be54-b49fcf80970c
                    status: processing
                    order_type: OnRamp
                    amount_fiat: 800
                    amount_crypto: 5.94999
                    currency: KES
                    token: BASE_USDC
                    wallet_address: '0x4F07419E6bfCCF8D256E8ef803Cc2653dfbB9558'
                    exchange_rate: 131.69
                    created_at: '2026-07-07T10:00:00.000000Z'
                    updated_at: '2026-07-07T10:00:15.000000Z'
                    route: null
        '404':
          description: Order not found or not accessible with this API key
          content:
            application/json:
              examples:
                not_found:
                  summary: Unknown order
                  value:
                    status: error
                    message: Order not found
              example:
                status: error
                message: Order not found
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Missing requirements for selected route
                data:
                  field: order_type
  /partner/orders/{quote_id}/accept:
    post:
      tags:
      - partner
      summary: Accept a partner order quote
      description: Accept a previously created quote and create the local order.
      operationId: partner_order_accept_partner_orders__quote_id__accept_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: quote_id
        in: path
        required: true
        schema:
          type: string
          description: Quote id returned by `/partner/orders/quote`.
          title: Quote Id
        description: Quote id returned by `/partner/orders/quote`.
      requestBody:
        content:
          application/json:
            schema:
              anyOf:
              - $ref: '#/components/schemas/PartnerOrderAcceptRequest'
              - type: 'null'
              title: Body
            examples:
              empty:
                summary: Accept quote
                description: Most callers can send an empty object; provider is inferred from quote_id.
                value: {}
              provider_assertion:
                summary: Accept quote with provider assertion
                value:
                  rail: local_fiat
      responses:
        '200':
          description: Partner order quote accepted
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Partner order quote accepted
                data:
                  quote_id: yc_receive_580e04c2-a136-5cca-be54-b49fcf80970c
                  status: processing
                  order:
                    order_id: YC-580e04c2-a136-5cca-be54-b49fcf80970c
                    status: processing
                    order_type: OnRamp
                    amount_fiat: 800
                    amount_crypto: 5.94999
                    currency: KES
                    token: BASE_USDC
                    wallet_address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
                    exchange_rate: 131.69
                    psp_transaction_id: 580e04c2-a136-5cca-be54-b49fcf80970c
                  accepted:
                    payment_instructions:
                      type: momo
                      source:
                        accountNumber: '+2541111111111'
                        networkName: Mobile Wallet (M-PESA)
                  webhooks:
                    events:
                    - order.processing
                    - order.settled
                    - order.failed
                    - order.refunded
                    delivery: ElementPay will notify the webhook_url configured on the API key.
                  rail: local_fiat
        '400':
          description: Invalid quote id or provider mismatch
          content:
            application/json:
              example:
                status: error
                message: Unsupported quote_id. Expected `yc_receive_<preview_id>` or `yc_send_<preview_id>`.
        '409':
          description: Provider quote is not acceptable
          content:
            application/json:
              examples:
                not_accepted_or_terminal:
                  summary: local fiat rail preview cannot be synced as accepted
                  value:
                    status: error
                    message: Quote request failed
                    data: null
              example:
                status: error
                message: Quote request failed
                data: null
        '502':
          description: Provider accept/lookup failed
          content:
            application/json:
              examples:
                accept_failed:
                  summary: local fiat rail accept failed upstream
                  value:
                    status: error
                    message: Quote request failed
                    data: null
              example:
                status: error
                message: Quote request failed
                data: null
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Missing requirements for selected route
                data:
                  field: order_type
      x-mint:
        content: |-
          Accept a previously created quote and create the local order.

          Send the same customer and payment method payload shape used at quote time (see [Test payloads](/sandbox/test-payloads)).

          OnRamp: final payment instructions are returned after accept when applicable.
  /partner/customers/requirements:
    get:
      tags:
      - partner-customers
      summary: Customer KYC package requirements
      description: Return the **full KYC package** for a customer type before create/submit.
      operationId: partner_customer_requirements_partner_customers_requirements_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: type
        in: query
        required: false
        schema:
          type: string
          description: individual or business
          default: individual
          title: Type
          enum:
          - individual
          - business
        description: individual or business
        example: individual
      - name: country
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Optional ISO country (e.g. US) for corridor-conditioned fields like tax_id
          title: Country
        description: Optional ISO country (e.g. US) for corridor-conditioned fields like tax_id
        example: US
      responses:
        '200':
          description: Required profile fields and document categories for the requested customer type.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerCustomerRequirementsSuccessResponse'
              example:
                status: success
                message: Customer requirements
                data:
                  type: individual
                  required_fields:
                  - first_name
                  - last_name
                  - email
                  - date_of_birth
                  - country_of_residence
                  - gender
                  - phone
                  - address
                  - id_number
                  - id_type
                  required_documents:
                  - key: identity
                    description: Government photo ID (passport, license, national ID)
                  - key: address
                    description: Proof of address (last 3 months)
                  optional_fields:
                  - middle_name
                  - liveness_check_id
                  - proof_of_address_type
                  - additional_id_number
                  - additional_id_type
                  conditional_fields:
                  - field: additional_id_type
                    when: country_of_residence == NG
                    required: true
                    description: Nigeria BVN type (use bvn)
                    example: bvn
                  - field: additional_id_number
                    when: country_of_residence == NG
                    required: true
                    description: Nigeria BVN number (11 digits)
                    example: '12345678901'
                  products:
                    deposit_account:
                      notes: deposit_account.status ready means KYC approved and partner may open deposit accounts — no automatic
                        account open.
                  notes: |-
                    Full individual package is required before submit. profile.address must include line1, city, and country. profile.id_number and profile.id_type are required. Nigeria residents must also include profile.additional_id_type (bvn) and profile.additional_id_number.
              examples:
                individual:
                  summary: Individual package
                  value:
                    status: success
                    message: Customer requirements
                    data:
                      type: individual
                      required_fields:
                      - first_name
                      - last_name
                      - email
                      - date_of_birth
                      - country_of_residence
                      - gender
                      - phone
                      - address
                      - id_number
                      - id_type
                      required_documents:
                      - key: identity
                        description: Government photo ID (passport, license, national ID)
                      - key: address
                        description: Proof of address (last 3 months)
                      optional_fields:
                      - middle_name
                      - liveness_check_id
                      - proof_of_address_type
                      - additional_id_number
                      - additional_id_type
                      conditional_fields:
                      - field: additional_id_type
                        when: country_of_residence == NG
                        required: true
                        description: Nigeria BVN type (use bvn)
                        example: bvn
                      - field: additional_id_number
                        when: country_of_residence == NG
                        required: true
                        description: Nigeria BVN number (11 digits)
                        example: '12345678901'
                      products:
                        deposit_account:
                          notes: deposit_account.status ready means KYC approved and partner may open deposit accounts — no
                            automatic account open.
                      notes: |-
                        Full individual package is required before submit. profile.address must include line1, city, and country. profile.id_number and profile.id_type are required. Nigeria residents must also include profile.additional_id_type (bvn) and profile.additional_id_number.
                business_us:
                  summary: Business package (US)
                  description: Pass `type=business&country=US` to hard-require tax_id.
                  value:
                    status: success
                    message: Customer requirements
                    data:
                      type: business
                      required_fields:
                      - legal_name
                      - email
                      - phone
                      - website
                      - business_type
                      - country_of_incorporation
                      - registered_address
                      - industry
                      - registration_number
                      - description
                      - incorporation_meta
                      - monthly_payments_count
                      - monthly_transaction_value
                      - max_transfer_amount
                      - annual_turnover
                      - customer_types
                      - funding_source
                      - officers
                      - tax_id
                      required_documents:
                      - key: certificate_of_incorporation
                        description: Business registration document
                      - key: memorandum_of_association
                        description: Memorandum / articles document
                      - key: proof_of_address
                        description: Business proof of address (last 3 months)
                      - key: identity
                        description: Officer government photo ID
                      - key: address
                        description: Officer proof of address (last 3 months)
                      optional_fields:
                      - liveness_check_id
                      - sales_channel
                      - operating_address
                      conditional_fields:
                      - field: tax_id
                        when: country_of_incorporation == US
                        required: true
                        description: US EIN (9 digits)
                        example: '123456789'
                      products:
                        deposit_account:
                          notes: After status approved and deposit_account becomes ready, partner may open deposit accounts
                            via account APIs.
                      notes: Full business package is required before submit. US-incorporated businesses must include profile.tax_id
                        (EIN).
        '422':
          description: Query validation error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: type
        '400':
          description: Invalid customer type query parameter
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Invalid customer type
                data:
                  field: type
                  allowed:
                  - business
                  - individual
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
      x-mint:
        content: |-
          Return the **full KYC package** for a customer type before create/submit.

          ### Query
          - **`type`** — `individual` (default) or `business`
          - **`country`** — optional ISO code; sharpens corridor-specific conditional fields (e.g. NG BVN, US EIN)

          Response `data` lists `required_fields`, `required_documents`, `optional_fields`, and `conditional_fields`. For **business**, nested officer fields are under **`field_shapes.officers`** (not top-level `required_fields`). Use this to build `profile` on [`POST /partner/customers`](/partner/customers) and document uploads.

          <Note>
          This is **not** the same as [`GET /partner/order-requirements`](/partner/order-requirements) (quote field hints per corridor).
          </Note>
  /partner/customers:
    post:
      tags:
      - partner-customers
      summary: Create a customer vault case
      description: 'Create an **incomplete** vault case (`status: incomplete`). Idempotent on `partner_customer_ref`.'
      operationId: partner_customer_create_partner_customers_post
      security:
      - APIKeyHeader: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerCustomerCreateRequestTryIt'
            examples:
              individual:
                summary: Individual — retail KYC
                description: Includes id_number and id_type. Upload identity + address documents, then submit when GET missing[]
                  is empty.
                value:
                  partner_customer_ref: partner-cust-001
                  type: individual
                  profile:
                    first_name: Jane
                    last_name: Doe
                    email: jane@example.com
                    date_of_birth: '1990-01-15'
                    country_of_residence: GB
                    phone: '+447700900123'
                    gender: f
                    id_number: A1234567
                    id_type: passport
                    address:
                      line1: 1 Example Street
                      city: London
                      country: GB
                      postal_code: E1 6AN
              business:
                summary: Business — KYB with officer
                description: |-
                  Each profile.officers[] entry needs person fields, identity_document (type, number, issuing_country), and address. US: include tax_id.
                value:
                  partner_customer_ref: partner-biz-001
                  type: business
                  profile:
                    legal_name: Acme Payments Ltd
                    email: ops@acme.example
                    phone: '+14155550100'
                    website: https://acme.example
                    business_type: llc
                    country_of_incorporation: US
                    tax_id: '123456789'
                    registration_number: REG-001
                    industry: Payment services
                    description: B2B payments for SMEs
                    registered_address:
                      line1: 100 Market Street
                      city: San Francisco
                      state: CA
                      country: US
                      postal_code: '94105'
                    incorporation_meta:
                      year: 2020
                      month: 6
                      country: US
                      state: CA
                    monthly_payments_count: 100
                    monthly_transaction_value: 250000
                    max_transfer_amount: 50000
                    annual_turnover: 2000000
                    customer_types:
                    - b2b
                    funding_source: equity
                    officers:
                    - role: director
                      first_name: Ada
                      last_name: Lovelace
                      date_of_birth: '1990-01-15'
                      email: ada@acme.example
                      nationality: US
                      identity_document:
                        type: passport
                        number: A1234567
                        issuing_country: US
                      address:
                        line1: 200 Officer Lane
                        city: San Francisco
                        state: CA
                        country: US
                        postal_code: '94105'
            example:
              partner_customer_ref: partner-cust-001
              type: individual
              profile:
                first_name: Jane
                last_name: Doe
                email: jane@example.com
                date_of_birth: '1990-01-15'
                country_of_residence: GB
                phone: '+447700900123'
                gender: f
                id_number: A1234567
                id_type: passport
                address:
                  line1: 1 Example Street
                  city: London
                  country: GB
                  postal_code: E1 6AN
      responses:
        '201':
          description: New incomplete vault case (or existing row on idempotent ref hit).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerCustomerVaultSuccessResponse'
              example:
                status: success
                message: Customer created
                data:
                  id: pcus_a1b2c3d4e5f6
                  partner_customer_ref: cust-ke-001
                  type: individual
                  status: incomplete
                  profile:
                    first_name: Jane
                    last_name: Doe
                    email: jane@example.com
                    date_of_birth: '1990-01-15'
                    country_of_residence: GB
                    phone: '+447700900123'
                    gender: f
                    address:
                      line1: 1 Example Street
                      city: London
                      country: GB
                      postal_code: E1 6AN
                  documents: []
                  products:
                    deposit_account:
                      status: none
                  missing:
                  - profile.id_number
                  - profile.id_type
                  - document.identity
                  - document.address
                  created_at: '2026-08-01T11:55:00+00:00'
                  updated_at: '2026-08-01T11:55:00+00:00'
                  submitted_at: null
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
      x-mint:
        content: |-
          Create an **incomplete** vault case (`status: incomplete`). Idempotent on `partner_customer_ref`.

          ### Try it
          Pick **Individual** or **Business** in the request body picker — each tab shows the expected `profile` shape. While incomplete, **`GET /partner/customers/{customer_id}`** returns **`missing[]`** with indexed paths (e.g. `profile.officers[0].identity_document.number`).

          Full walkthrough: [Customer KYC quickstart](/customers/quickstart).
        playground:
          expand: false
    get:
      tags:
      - partner-customers
      summary: List customers for this partner tenant
      description: |-
        List tenant-scoped customers. Pass ``partner_customer_ref`` to resolve your stable ref to at most one customer (full row, same shape as GET by ``pcus_*``). Unknown ref returns an empty ``customers`` array.
      operationId: partner_customer_list_partner_customers_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: status
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Optional status filter (e.g. incomplete, pending_review)
          title: Status
        description: Optional status filter (e.g. incomplete, pending_review)
      - name: partner_customer_ref
        in: query
        required: false
        schema:
          anyOf:
          - type: string
          - type: 'null'
          description: Filter to a single customer by your partner_customer_ref
          title: Partner Customer Ref
          example: partner-cust-001
        description: Filter to a single customer by your partner_customer_ref
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          maximum: 100
          minimum: 1
          default: 50
          title: Limit
      responses:
        '200':
          description: |-
            Customer list or ref lookup result. With ``partner_customer_ref``: zero or one full vault row. Without it: up to ``limit`` summary rows (newest first). ``limit`` is ignored when ``partner_customer_ref`` is set.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerCustomerListSuccessResponse'
              example:
                status: success
                message: Customers
                data:
                  customers:
                  - id: pcus_a1b2c3d4e5f6
                    partner_customer_ref: partner-cust-001
                    type: individual
                    status: approved
                    profile:
                      first_name: Jane
                      last_name: Doe
                      email: jane@example.com
                      date_of_birth: '1990-01-15'
                      country_of_residence: GB
                      phone: '+447700900123'
                      gender: f
                      id_type: passport
                      id_number: A1234567
                      address:
                        line1: 1 Example Street
                        city: London
                        country: GB
                        postal_code: E1 6AN
                    documents:
                    - id: pdoc_a1b2c3d4e5f6
                      category: identity
                      content_type: application/pdf
                      created_at: '2026-08-01T12:00:00+00:00'
                    - id: pdoc_b2c3d4e5f6a7
                      category: address
                      content_type: application/pdf
                      created_at: '2026-08-01T12:01:00+00:00'
                    products:
                      deposit_account:
                        status: ready
                    created_at: '2026-08-01T11:55:00+00:00'
                    updated_at: '2026-08-01T12:05:00+00:00'
                    submitted_at: '2026-08-01T12:02:00+00:00'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
  /partner/customers/{customer_id}:
    get:
      tags:
      - partner-customers
      summary: Get a customer vault case
      description: Get one tenant-owned customer including document metadata and missing[].
      operationId: partner_customer_get_partner_customers__customer_id__get
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned on create
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_a1b2c3d4e5f6
        description: Public customer id returned on create
        example: pcus_a1b2c3d4e5f6
      responses:
        '200':
          description: One tenant-owned customer including document metadata and missing[].
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerCustomerVaultSuccessResponse'
              example:
                status: success
                message: Customer
                data:
                  id: pcus_a1b2c3d4e5f6
                  partner_customer_ref: partner-cust-001
                  type: individual
                  status: approved
                  profile:
                    first_name: Jane
                    last_name: Doe
                    email: jane@example.com
                    date_of_birth: '1990-01-15'
                    country_of_residence: GB
                    phone: '+447700900123'
                    gender: f
                    id_type: passport
                    id_number: A1234567
                    address:
                      line1: 1 Example Street
                      city: London
                      country: GB
                      postal_code: E1 6AN
                  documents:
                  - id: pdoc_a1b2c3d4e5f6
                    category: identity
                    content_type: application/pdf
                    created_at: '2026-08-01T12:00:00+00:00'
                  - id: pdoc_b2c3d4e5f6a7
                    category: address
                    content_type: application/pdf
                    created_at: '2026-08-01T12:01:00+00:00'
                  products:
                    deposit_account:
                      status: ready
                  created_at: '2026-08-01T11:55:00+00:00'
                  updated_at: '2026-08-01T12:05:00+00:00'
                  submitted_at: '2026-08-01T12:02:00+00:00'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '404':
          description: Customer not found for this API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Customer not found
                data: null
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
    patch:
      tags:
      - partner-customers
      summary: Update a draft or correct a failed deposit-KYC profile
      description: |-
        Merge profile fields on a draft. A correction after failed deposit-account KYC invalidates prior approval and returns the customer to ``incomplete`` for resubmission and re-review.
      operationId: partner_customer_patch_partner_customers__customer_id__patch
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned on create
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_a1b2c3d4e5f6
        description: Public customer id returned on create
        example: pcus_a1b2c3d4e5f6
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerCustomerProfilePatchRequest'
            examples:
              default:
                summary: Example
                value:
                  profile:
                    first_name: Jane
                    last_name: Doe
                    email: jane@example.com
                    date_of_birth: '1990-01-15'
                    country_of_residence: GB
                    phone: '+447700900123'
                    gender: f
                    address:
                      line1: 1 Example Street
                      city: London
                      country: GB
                      postal_code: E1 6AN
            example:
              profile:
                first_name: Jane
                last_name: Doe
                email: jane@example.com
                date_of_birth: '1990-01-15'
                country_of_residence: GB
                phone: '+447700900123'
                gender: f
                address:
                  line1: 1 Example Street
                  city: London
                  country: GB
                  postal_code: E1 6AN
      responses:
        '200':
          description: Updated draft customer (may include missing[] while incomplete).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerCustomerVaultSuccessResponse'
              example:
                status: success
                message: Customer updated
                data:
                  id: pcus_a1b2c3d4e5f6
                  partner_customer_ref: cust-ke-001
                  type: individual
                  status: incomplete
                  profile:
                    first_name: Jane
                    last_name: Doe
                    email: jane@example.com
                    date_of_birth: '1990-01-15'
                    country_of_residence: GB
                    phone: '+447700900123'
                    gender: f
                    address:
                      line1: 1 Example Street
                      city: London
                      country: GB
                      postal_code: E1 6AN
                  documents: []
                  products:
                    deposit_account:
                      status: none
                  missing:
                  - profile.id_number
                  - profile.id_type
                  - document.identity
                  - document.address
                  created_at: '2026-08-01T11:55:00+00:00'
                  updated_at: '2026-08-01T11:55:00+00:00'
                  submitted_at: null
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
  /partner/customers/{customer_id}/documents:
    post:
      tags:
      - partner-customers
      summary: Upload a customer document
      description: |-
        Upload a base64 document into the vault (off-host store + DB metadata). A correction after failed deposit-account KYC invalidates prior approval and returns the customer to ``incomplete`` for resubmission and re-review.
      operationId: partner_customer_upload_document_partner_customers__customer_id__documents_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned on create
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_a1b2c3d4e5f6
        description: Public customer id returned on create
        example: pcus_a1b2c3d4e5f6
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerCustomerDocumentUploadRequest'
            examples:
              default:
                summary: Identity document
                value:
                  category: identity
                  content_base64: |-
                    JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFI+PmVuZG9iagoyIDAgb2JqCjw8L1R5cGUvUGFnZXMvQ291bnQgMC9LaWRzW10+PmVuZG9iagp4cmVmCjAgMwowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMDA2OCAwMDAwMCBuIAp0cmFpbGVyCjw8L1NpemUgMy9Sb290IDEgMCBSPj4Kc3RhcnR4cmVmCjEyMQolJUVPRgo=
                  content_type: application/pdf
                  file_name: passport.pdf
            example:
              category: identity
              content_base64: |-
                JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFI+PmVuZG9iagoyIDAgb2JqCjw8L1R5cGUvUGFnZXMvQ291bnQgMC9LaWRzW10+PmVuZG9iagp4cmVmCjAgMwowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMDA2OCAwMDAwMCBuIAp0cmFpbGVyCjw8L1NpemUgMy9Sb290IDEgMCBSPj4Kc3RhcnR4cmVmCjEyMQolJUVPRgo=
              content_type: application/pdf
              file_name: passport.pdf
      responses:
        '201':
          description: Document stored; returns metadata and updated customer row.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerCustomerDocumentUploadSuccessResponse'
              example:
                status: success
                message: Document uploaded
                data:
                  document:
                    id: pdoc_a1b2c3d4e5f6
                    category: identity
                    content_type: application/pdf
                    created_at: '2026-08-01T12:00:00+00:00'
                  customer:
                    id: pcus_a1b2c3d4e5f6
                    partner_customer_ref: cust-ke-001
                    type: individual
                    status: incomplete
                    profile:
                      first_name: Jane
                      last_name: Doe
                      email: jane@example.com
                      date_of_birth: '1990-01-15'
                      country_of_residence: GB
                      phone: '+447700900123'
                      gender: f
                      address:
                        line1: 1 Example Street
                        city: London
                        country: GB
                        postal_code: E1 6AN
                    documents:
                    - id: pdoc_a1b2c3d4e5f6
                      category: identity
                      content_type: application/pdf
                      created_at: '2026-08-01T12:00:00+00:00'
                    products:
                      deposit_account:
                        status: none
                    missing:
                    - profile.id_number
                    - profile.id_type
                    - document.address
                    created_at: '2026-08-01T11:55:00+00:00'
                    updated_at: '2026-08-01T11:55:00+00:00'
                    submitted_at: null
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
  /partner/customers/{customer_id}/submit:
    post:
      tags:
      - partner-customers
      summary: Submit customer package for review
      description: Submit an incomplete package → pending_review, or 422 with missing[].
      operationId: partner_customer_submit_partner_customers__customer_id__submit_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned on create
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_a1b2c3d4e5f6
        description: Public customer id returned on create
        example: pcus_a1b2c3d4e5f6
      responses:
        '200':
          description: Package submitted for review (or current row if already submitted).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerCustomerVaultSuccessResponse'
              example:
                status: success
                message: Customer submitted
                data:
                  id: pcus_a1b2c3d4e5f6
                  partner_customer_ref: partner-cust-001
                  type: individual
                  status: pending_review
                  profile:
                    first_name: Jane
                    last_name: Doe
                    email: jane@example.com
                    date_of_birth: '1990-01-15'
                    country_of_residence: GB
                    phone: '+447700900123'
                    gender: f
                    id_type: passport
                    id_number: A1234567
                    address:
                      line1: 1 Example Street
                      city: London
                      country: GB
                      postal_code: E1 6AN
                  documents:
                  - id: pdoc_a1b2c3d4e5f6
                    category: identity
                    content_type: application/pdf
                    created_at: '2026-08-01T12:00:00+00:00'
                  - id: pdoc_b2c3d4e5f6a7
                    category: address
                    content_type: application/pdf
                    created_at: '2026-08-01T12:01:00+00:00'
                  products:
                    deposit_account:
                      status: none
                  created_at: '2026-08-01T11:55:00+00:00'
                  updated_at: '2026-08-01T12:02:00+00:00'
                  submitted_at: '2026-08-01T12:02:00+00:00'
        '422':
          description: Package incomplete — missing profile fields or documents
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Customer package is incomplete
                data:
                  code: package_incomplete
                  missing:
                  - profile.id_number
                  - profile.id_type
                  - document.identity
                  - document.address
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
  /partner/customers/{customer_id}/revoke:
    post:
      tags:
      - partner-customers
      summary: Revoke a customer (partner offboarding)
      description: |-
        Partner offboard: transition customer to `suspended`. Idempotent when already `suspended` or `rejected`. Optional `reason` is audit-only and not returned in responses. Emits `customer.revoked` webhook on transition.
      operationId: partner_customer_revoke_partner_customers__customer_id__revoke_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned on create
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_a1b2c3d4e5f6
        description: Public customer id returned on create
        example: pcus_a1b2c3d4e5f6
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerCustomerRevokeRequest'
            example:
              reason: account_closed
      responses:
        '200':
          description: Customer revoked or already offboarded
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                - data
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
                    required:
                    - id
                    - status
                    - partner_customer_ref
                    - updated_at
                    properties:
                      id:
                        type: string
                        example: pcus_a1b2c3d4e5f6
                      status:
                        type: string
                        enum:
                        - suspended
                        - rejected
                      partner_customer_ref:
                        type: string
                      updated_at:
                        type: string
                        format: date-time
              example:
                status: success
                message: Customer revoked
                data:
                  id: pcus_a1b2c3d4e5f6
                  status: suspended
                  partner_customer_ref: partner-cust-001
                  updated_at: '2026-08-31T08:00:00+00:00'
        '409':
          description: Concurrent status change during revoke — retry the request
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Customer cannot be revoked
                data:
                  status: approved
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: reason
  /partner/customers/{customer_id}/deposit-account/retry:
    post:
      tags:
      - partner-customers
      summary: Retry deposit account provisioning after a failed attempt
      description: |-
        Re-queue an unchanged KYC/KYB attempt after a transient failure. Only valid when the customer is EP-approved and ``deposit_account.status`` is ``failed``. Profile/document corrections invalidate approval; after a correction, complete the package and submit it for EP review again.
      operationId: partner_customer_deposit_account_retry_partner_customers__customer_id__deposit_account_retry_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned on create
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_a1b2c3d4e5f6
        description: Public customer id returned on create
        example: pcus_a1b2c3d4e5f6
      responses:
        '200':
          description: Failed deposit-account attempt re-queued (unchanged KYC/KYB only).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerCustomerVaultSuccessResponse'
              example:
                status: success
                message: Deposit account provisioning retried
                data:
                  id: pcus_a1b2c3d4e5f6
                  partner_customer_ref: partner-cust-001
                  type: individual
                  status: approved
                  profile:
                    first_name: Jane
                    last_name: Doe
                    email: jane@example.com
                    date_of_birth: '1990-01-15'
                    country_of_residence: GB
                    phone: '+447700900123'
                    gender: f
                    id_type: passport
                    id_number: A1234567
                    address:
                      line1: 1 Example Street
                      city: London
                      country: GB
                      postal_code: E1 6AN
                  documents:
                  - id: pdoc_a1b2c3d4e5f6
                    category: identity
                    content_type: application/pdf
                    created_at: '2026-08-01T12:00:00+00:00'
                  - id: pdoc_b2c3d4e5f6a7
                    category: address
                    content_type: application/pdf
                    created_at: '2026-08-01T12:01:00+00:00'
                  products:
                    deposit_account:
                      status: provisioning
                  created_at: '2026-08-01T11:55:00+00:00'
                  updated_at: '2026-08-01T12:05:00+00:00'
                  submitted_at: '2026-08-01T12:02:00+00:00'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '409':
          description: Customer not approved or deposit account not in failed state
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Deposit account provisioning is not in a failed state
                data:
                  deposit_account_status: ready
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
  /partner/customers/{customer_id}/accounts:
    post:
      tags:
      - partner-customer-accounts
      summary: Open an account for a ready customer
      description: Open one idempotent fiat or stablecoin rail. Same rail tuple returns the existing account.
      operationId: partner_customer_open_account
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        description: Public customer id returned by POST /partner/customers
        schema:
          type: string
          example: pcus_a1b2c3d4e5f6
        example: pcus_a1b2c3d4e5f6
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerCustomerAccountOpenRequest'
            example:
              asset_type: fiat
              currency: EUR
            examples:
              fiat_eur:
                summary: Fiat EUR
                value:
                  asset_type: fiat
                  currency: EUR
              usdc_base:
                summary: USDC on Base
                value:
                  asset_type: stablecoin
                  currency: USDC
                  network: Base
      responses:
        '201':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
              example:
                status: success
                message: Account opened
                data:
                  id: 18
                  customer_id: pcus_a1b2c3d4e5f6
                  asset_type: fiat
                  currency: EUR
                  network: null
                  status: active
                  display_name: EUR
                  account_number: DE89370400440532013000
                  bank_name: Example Bank
                  swift_bic: COBADEFFXXX
                  balance:
                    available: '250.00'
                    currency: EUR
                  created_at: '2026-08-01T12:00:00+00:00'
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
              example:
                status: success
                message: Account already exists
                data:
                  id: 18
                  customer_id: pcus_a1b2c3d4e5f6
                  asset_type: fiat
                  currency: EUR
                  network: null
                  status: active
                  display_name: EUR
                  account_number: DE89370400440532013000
                  bank_name: Example Bank
                  swift_bic: COBADEFFXXX
                  balance:
                    available: '250.00'
                    currency: EUR
                  created_at: '2026-08-01T12:00:00+00:00'
        '409':
          description: Deposit account is not ready
          content:
            application/json:
              schema:
                type: object
              example:
                status: error
                message: Deposit account is not ready
                data:
                  deposit_account_status: pending
    get:
      tags:
      - partner-customer-accounts
      summary: List accounts for a ready customer
      description: List customer accounts, refreshing pending coordinates when available.
      operationId: partner_customer_list_accounts
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        description: Public customer id returned by POST /partner/customers
        schema:
          type: string
          example: pcus_a1b2c3d4e5f6
        example: pcus_a1b2c3d4e5f6
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
              example:
                status: success
                message: Accounts
                data:
                  accounts:
                  - id: 21
                    customer_id: pcus_a1b2c3d4e5f6
                    asset_type: stablecoin
                    currency: USDC
                    network: Base
                    status: active
                    display_name: USDC Base
                    wallet_address: '0x40C2f2e0326bD1f647fbeB8732529e08B4DB309f'
                    balance:
                      available: '12.50'
                      currency: USDC
                    created_at: '2026-08-01T12:00:00+00:00'
                  - id: 18
                    customer_id: pcus_a1b2c3d4e5f6
                    asset_type: fiat
                    currency: EUR
                    network: null
                    status: active
                    display_name: EUR
                    account_number: DE89370400440532013000
                    bank_name: Example Bank
                    swift_bic: COBADEFFXXX
                    balance:
                      available: '250.00'
                      currency: EUR
                    created_at: '2026-08-01T12:00:00+00:00'
        '409':
          description: Deposit account is not ready
          content:
            application/json:
              schema:
                type: object
              example:
                status: error
                message: Deposit account is not ready
                data:
                  deposit_account_status: pending
  /partner/customers/{customer_id}/accounts/{account_id}:
    get:
      tags:
      - partner-customer-accounts
      summary: Get one account for a ready customer
      description: Get one customer-owned account and its current coordinates.
      operationId: partner_customer_get_account
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        description: Public customer id returned by POST /partner/customers
        schema:
          type: string
          example: pcus_a1b2c3d4e5f6
        example: pcus_a1b2c3d4e5f6
      - name: account_id
        in: path
        required: true
        description: Account id from list/open
        schema:
          type: integer
          minimum: 1
          example: 21
        example: 21
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
              example:
                status: success
                message: Account
                data:
                  id: 21
                  customer_id: pcus_a1b2c3d4e5f6
                  asset_type: stablecoin
                  currency: USDC
                  network: Base
                  status: active
                  display_name: USDC Base
                  wallet_address: '0x40C2f2e0326bD1f647fbeB8732529e08B4DB309f'
                  balance:
                    available: '12.50'
                    currency: USDC
                  created_at: '2026-08-01T12:00:00+00:00'
        '404':
          description: Account not found
          content:
            application/json:
              schema:
                type: object
              example:
                status: error
                message: Account not found
                data: null
        '409':
          description: Deposit account is not ready
          content:
            application/json:
              schema:
                type: object
              example:
                status: error
                message: Deposit account is not ready
                data:
                  deposit_account_status: pending
  /partner/customers/{customer_id}/accounts/{account_id}/deposit-instructions:
    get:
      tags:
      - partner-customer-accounts
      summary: Get deposit instructions for an account
      description: |-
        Funding coordinates for one customer account (fiat bank details or stablecoin wallet). Account must be active with usable coordinates.
      operationId: partner_customer_get_deposit_instructions
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        description: Public customer id returned by POST /partner/customers
        schema:
          type: string
          example: pcus_a1b2c3d4e5f6
        example: pcus_a1b2c3d4e5f6
      - name: account_id
        in: path
        required: true
        description: Account id from list/open
        schema:
          type: integer
          minimum: 1
          example: 21
        example: 21
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                type: object
              example:
                status: success
                message: Deposit instructions
                data:
                  account_id: 18
                  customer_id: pcus_a1b2c3d4e5f6
                  asset_type: fiat
                  currency: EUR
                  network: null
                  status: ready
                  account_holder_name: Jane Doe
                  account_number: DE89370400440532013000
                  bank_code: COBADEFF
                  bank_name: Example Bank
                  swift_bic: COBADEFFXXX
                  instructions: |-
                    Show the account holder name and these bank details to the customer. They should send a bank transfer in the account currency to this account.
        '409':
          description: Banking gate not ready
          content:
            application/json:
              example:
                status: error
                message: Banking profile incomplete
                data:
                  deposit_account_status: pending
                  reason: banking_profile_incomplete
        '422':
          description: Coordinates not ready yet
          content:
            application/json:
              example:
                status: error
                message: Deposit instructions are not ready yet
                data:
                  account_id: 18
                  status: pending
                  hint: Poll GET account or wait for account.ready
  /partner/customers/{customer_id}/accounts/{account_id}/sends/preview:
    post:
      tags:
      - partner-customer-transfers
      summary: Preview a stablecoin send for a ready customer account
      description: Preview fees and amounts for a stablecoin send.
      operationId: partner_customer_preview_send_partner_customers__customer_id__accounts__account_id__sends_preview_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_a1b2c3d4e5f6
        description: Public customer id returned by POST /partner/customers
        example: pcus_a1b2c3d4e5f6
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
          description: Account id returned by the customer account API
          title: Account Id
          example: 21
        description: Account id returned by the customer account API
        example: 21
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerEntitySendPreviewRequest'
            example:
              to_address: '0x40C2f2e0326bD1f647fbeB8732529e08B4DB309f'
              amount: '5.00'
              network: Base
              memo: optional-stellar-memo
      responses:
        '201':
          description: Estimated fees and preview token for confirm step.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Send preview
                data:
                  preview_token: nvsend.eyJhbGciOiJIUzI1NiJ9.preview
                  currency: USDC
                  network: Base
                  amount: '5.00'
                  fee: '0.05'
                  receive_amount: '4.95'
                  fee_status: estimated
                  chain_disclaimer: Send only USDC on Base to the destination address.
                  expires_at: '2026-07-30T12:10:00+00:00'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '409':
          description: Deposit account is not ready
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Deposit account is not ready
                data:
                  deposit_account_status: pending
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
  /partner/customers/{customer_id}/accounts/{account_id}/sends:
    post:
      tags:
      - partner-customer-transfers
      summary: Confirm a stablecoin send for a ready customer account
      description: Submit a stablecoin send using a prior preview token.
      operationId: partner_customer_confirm_send_partner_customers__customer_id__accounts__account_id__sends_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_a1b2c3d4e5f6
        description: Public customer id returned by POST /partner/customers
        example: pcus_a1b2c3d4e5f6
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
          description: Account id returned by the customer account API
          title: Account Id
          example: 21
        description: Account id returned by the customer account API
        example: 21
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerEntitySendConfirmRequest'
            example:
              preview_token: <from preview response>
              idempotency_key: send-2026-08-22-001
      responses:
        '201':
          description: Stablecoin send accepted for processing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Send submitted
                data:
                  id: 55
                  entity_id: 12
                  account_id: 21
                  status: submitted
                  currency: USDC
                  network: Base
                  to_address: '0x40C2f2e0326bD1f647fbeB8732529e08B4DB309f'
                  amount: '5.00'
                  fee: '0.05'
                  receive_amount: '4.95'
                  fee_status: final
                  chain_disclaimer: Send only USDC on Base to the destination address.
                  created_at: '2026-08-01T12:05:00+00:00'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
  /partner/customers/{customer_id}/accounts/{account_id}/sends/{send_id}:
    get:
      tags:
      - partner-customer-transfers
      summary: Get a stablecoin send for a ready customer account
      description: Get one stablecoin send status for a customer-owned account.
      operationId: partner_customer_get_send_partner_customers__customer_id__accounts__account_id__sends__send_id__get
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_a1b2c3d4e5f6
        description: Public customer id returned by POST /partner/customers
        example: pcus_a1b2c3d4e5f6
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
          description: Account id returned by the customer account API
          title: Account Id
          example: 21
        description: Account id returned by the customer account API
        example: 21
      - name: send_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
          description: Send id returned by the send API
          title: Send Id
          example: 55
        description: Send id returned by the send API
        example: 55
      responses:
        '200':
          description: Stablecoin send status for polling.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Send
                data:
                  id: 55
                  entity_id: 12
                  account_id: 21
                  status: submitted
                  currency: USDC
                  network: Base
                  to_address: '0x40C2f2e0326bD1f647fbeB8732529e08B4DB309f'
                  amount: '5.00'
                  fee: '0.05'
                  receive_amount: '4.95'
                  fee_status: final
                  chain_disclaimer: Send only USDC on Base to the destination address.
                  created_at: '2026-08-01T12:05:00+00:00'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
  /partner/customers/{customer_id}/accounts/{account_id}/book-transfers/preview:
    post:
      tags:
      - partner-customer-transfers
      summary: Preview a fiat book-transfer for a ready customer account
      operationId: partner_customer_preview_book_transfer_partner_customers__customer_id__accounts__account_id__book_transfers_preview_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_06a83150db3c
        description: Public customer id returned by POST /partner/customers
        example: pcus_06a83150db3c
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          description: Source account id owned by this customer
          examples:
          - 17
          title: Account Id
          example: 1
        description: Source account id owned by this customer
        example: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerEntityBookTransferPreviewRequest'
            example:
              to_account_id: 7
              amount: '0.50'
      responses:
        '201':
          description: Same-currency fiat book-transfer preview
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
              example:
                status: success
                message: Book-transfer preview
                data:
                  preview_token: nvbook.eyJhbGciOiJIUzI1NiJ9.preview
                  currency: EUR
                  from_account_id: 21
                  to_account_id: 31
                  amount: '10.50'
                  fee: '0.00'
                  receive_amount: '10.50'
                  fee_status: estimated
                  expires_at: '2026-07-30T12:10:00+00:00'
              examples:
                preview:
                  summary: Book-transfer preview
                  value:
                    status: success
                    message: Book-transfer preview
                    data:
                      preview_token: nvbook.eyJhbGciOiJIUzI1NiJ9.preview
                      currency: EUR
                      from_account_id: 21
                      to_account_id: 31
                      amount: '10.50'
                      fee: '0.00'
                      receive_amount: '10.50'
                      fee_status: estimated
                      expires_at: '2026-07-30T12:10:00+00:00'
        '422':
          description: Currency mismatch, inactive account, or invalid amount
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      id:
                        type: integer
                      status:
                        type: string
                      field:
                        type: string
                      allowed:
                        type: array
                        items:
                          type: string
                      upstream_http_status:
                        type: integer
                      liveness_required:
                        type: boolean
                      hint:
                        type: string
                      missing_fields:
                        type: array
                        items:
                          type: string
              example:
                status: error
                message: Book transfers require the same currency on both accounts
                data: null
              examples:
                same_currency:
                  summary: Currency mismatch
                  value:
                    status: error
                    message: Book transfers require the same currency on both accounts
                    data: null
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      id:
                        type: integer
                      status:
                        type: string
                      field:
                        type: string
                      allowed:
                        type: array
                        items:
                          type: string
                      upstream_http_status:
                        type: integer
                      liveness_required:
                        type: boolean
                      hint:
                        type: string
                      missing_fields:
                        type: array
                        items:
                          type: string
              example:
                status: error
                message: Unauthorized
              examples:
                unauthorized:
                  summary: Unauthorized
                  value:
                    status: error
                    message: Unauthorized
        '503':
          description: International entity onboarding not configured on this environment
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      id:
                        type: integer
                      status:
                        type: string
                      field:
                        type: string
                      allowed:
                        type: array
                        items:
                          type: string
                      upstream_http_status:
                        type: integer
                      liveness_required:
                        type: boolean
                      hint:
                        type: string
                      missing_fields:
                        type: array
                        items:
                          type: string
              example:
                status: error
                message: International entity onboarding is not configured
                data: null
              examples:
                not_configured:
                  summary: Feature not enabled
                  value:
                    status: error
                    message: International entity onboarding is not configured
                    data: null
  /partner/customers/{customer_id}/accounts/{account_id}/book-transfers:
    post:
      tags:
      - partner-customer-transfers
      summary: Confirm a fiat book-transfer for a ready customer account
      operationId: partner_customer_confirm_book_transfer_partner_customers__customer_id__accounts__account_id__book_transfers_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_06a83150db3c
        description: Public customer id returned by POST /partner/customers
        example: pcus_06a83150db3c
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          description: Source account id owned by this customer
          examples:
          - 17
          title: Account Id
          example: 1
        description: Source account id owned by this customer
        example: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerEntityBookTransferConfirmRequest'
            example:
              preview_token: <from preview response>
              idempotency_key: book-aly-kh-2026-08-22-001
      responses:
        '201':
          description: Same-currency fiat book-transfer submitted
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
              example:
                status: success
                message: Book transfer submitted
                data:
                  id: 01KYPXBOOKTRANSFER0000000001
                  status: completed
                  from_account_id: 21
                  to_account_id: 31
                  currency: EUR
                  amount: '10.50'
                  fee: '0.00'
                  receive_amount: '10.50'
                  fee_status: final
                  created_at: '2026-07-30T12:00:00+00:00'
              examples:
                submitted:
                  summary: Book transfer submitted
                  value:
                    status: success
                    message: Book transfer submitted
                    data:
                      id: 01KYPXBOOKTRANSFER0000000001
                      status: completed
                      from_account_id: 21
                      to_account_id: 31
                      currency: EUR
                      amount: '10.50'
                      fee: '0.00'
                      receive_amount: '10.50'
                      fee_status: final
                      created_at: '2026-07-30T12:00:00+00:00'
        '409':
          description: Idempotent replay conflict while confirm is in progress
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      id:
                        type: integer
                      status:
                        type: string
                      field:
                        type: string
                      allowed:
                        type: array
                        items:
                          type: string
                      upstream_http_status:
                        type: integer
                      liveness_required:
                        type: boolean
                      hint:
                        type: string
                      missing_fields:
                        type: array
                        items:
                          type: string
              example:
                status: error
                message: Book transfer already in progress
                data:
                  field: idempotency_key
              examples:
                in_progress:
                  summary: In progress
                  value:
                    status: error
                    message: Book transfer already in progress
                    data:
                      field: idempotency_key
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      id:
                        type: integer
                      status:
                        type: string
                      field:
                        type: string
                      allowed:
                        type: array
                        items:
                          type: string
                      upstream_http_status:
                        type: integer
                      liveness_required:
                        type: boolean
                      hint:
                        type: string
                      missing_fields:
                        type: array
                        items:
                          type: string
              example:
                status: error
                message: Unauthorized
              examples:
                unauthorized:
                  summary: Unauthorized
                  value:
                    status: error
                    message: Unauthorized
        '503':
          description: International entity onboarding not configured on this environment
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      id:
                        type: integer
                      status:
                        type: string
                      field:
                        type: string
                      allowed:
                        type: array
                        items:
                          type: string
                      upstream_http_status:
                        type: integer
                      liveness_required:
                        type: boolean
                      hint:
                        type: string
                      missing_fields:
                        type: array
                        items:
                          type: string
              example:
                status: error
                message: International entity onboarding is not configured
                data: null
              examples:
                not_configured:
                  summary: Feature not enabled
                  value:
                    status: error
                    message: International entity onboarding is not configured
                    data: null
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
  /partner/customers/{customer_id}/accounts/{account_id}/conversions/preview:
    post:
      tags:
      - partner-customer-transfers
      summary: Preview a currency conversion for a ready customer account
      description: Preview a **cross-currency** conversion between two accounts owned by this customer.
      operationId: partner_customer_preview_conversion
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_06a83150db3c
        description: Public customer id returned by POST /partner/customers
        example: pcus_06a83150db3c
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          description: Source account id owned by this customer
          examples:
          - 63
          title: Account Id
          example: 63
        description: Source account id owned by this customer
        example: 63
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - to_account_id
              - amount
              properties:
                to_account_id:
                  type: integer
                  description: Destination partner account id (different currency, same customer)
                amount:
                  type: string
                  description: Decimal debit amount in the source account currency
                  example: '1.00'
            example:
              to_account_id: 68
              amount: '1.00'
      responses:
        '201':
          description: Cross-currency conversion preview
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
              example:
                status: success
                message: Conversion preview
                data:
                  preview_token: ep_fx_prev_example.token
                  from_account_id: 63
                  to_account_id: 68
                  from_currency: EUR
                  to_currency: NGN
                  amount_from: '1.00'
                  amount_to: '1511.72'
                  rate: 1511.724589
                  fee: '0.00'
                  fee_status: estimated
                  expires_at: '2026-09-15T11:05:13+00:00'
              examples:
                eur_to_ngn:
                  summary: EUR → NGN preview
                  value:
                    status: success
                    message: Conversion preview
                    data:
                      preview_token: ep_fx_prev_example.token
                      from_account_id: 63
                      to_account_id: 68
                      from_currency: EUR
                      to_currency: NGN
                      amount_from: '1.00'
                      amount_to: '1511.72'
                      rate: 1511.724589
                      fee: '0.00'
                      fee_status: estimated
                      expires_at: '2026-09-15T11:05:13+00:00'
        '422':
          description: Validation or quote expiry
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      code:
                        type: string
                      min_amount:
                        type: number
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Source and destination accounts must differ
                data:
                  field: to_account_id
      x-mint:
        content: |-
          Preview a **cross-currency** conversion between two accounts owned by this customer.

          Returns a signed `preview_token`, `rate`, `amount_from` / `amount_to`, and `expires_at` (often only a few minutes). Confirm before expiry.

          <Note>
          Same-currency moves use [book transfers](/customers/book-transfers). Corridor ramps use [quote → accept](/orders/quote-and-accept).
          </Note>

          Guide: [Currency conversions](/customers/conversions).
  /partner/customers/{customer_id}/accounts/{account_id}/conversions:
    post:
      tags:
      - partner-customer-transfers
      summary: Confirm a currency conversion for a ready customer account
      description: Confirm a conversion using `preview_token` + `idempotency_key` from a prior preview on the **same** source
        `account_id`.
      operationId: partner_customer_confirm_conversion
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
          example: pcus_06a83150db3c
        description: Public customer id returned by POST /partner/customers
        example: pcus_06a83150db3c
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          description: Source account id owned by this customer
          examples:
          - 63
          title: Account Id
          example: 63
        description: Source account id owned by this customer
        example: 63
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
              - preview_token
              - idempotency_key
              properties:
                preview_token:
                  type: string
                  minLength: 16
                  description: Token from conversions/preview
                idempotency_key:
                  type: string
                  minLength: 8
                  maxLength: 64
                  description: Partner-stable id; forwarded as upstream unique_reference
                  example: fx-2026-09-15-001
            example:
              preview_token: ep_fx_prev_example.token
              idempotency_key: fx-2026-09-15-001
      responses:
        '201':
          description: Cross-currency conversion submitted
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - success
                  message:
                    type: string
                  data:
                    type: object
              example:
                status: success
                message: Conversion submitted
                data:
                  id: 01M2JBPTX2A9R85G1SZMQC5AKS
                  status: completed
                  from_account_id: 63
                  to_account_id: 68
                  from_currency: EUR
                  to_currency: NGN
                  amount_from: '1.00'
                  amount_to: '1511.72'
                  rate: 1511.724589
                  fee: '0.00'
                  fee_status: final
              examples:
                completed:
                  summary: Conversion completed
                  value:
                    status: success
                    message: Conversion submitted
                    data:
                      id: 01M2JBPTX2A9R85G1SZMQC5AKS
                      status: completed
                      from_account_id: 63
                      to_account_id: 68
                      from_currency: EUR
                      to_currency: NGN
                      amount_from: '1.00'
                      amount_to: '1511.72'
                      rate: 1511.724589
                      fee: '0.00'
                      fee_status: final
        '422':
          description: Invalid or mismatched preview
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
                    properties:
                      field:
                        type: string
                      code:
                        type: string
                      min_amount:
                        type: number
                      currency:
                        type: string
                      upstream_http_status:
                        type: integer
              example:
                status: error
                message: Conversion preview does not match this account
                data: null
      x-mint:
        content: |-
          Confirm a conversion using `preview_token` + `idempotency_key` from a prior preview on the **same** source `account_id`.

          Reuse the same `idempotency_key` after network errors. Request a **fresh** preview for each new conversion.

          Guide: [Currency conversions](/customers/conversions).
  /partner/customers/{customer_id}/accounts/{account_id}/payout-methods:
    get:
      tags:
      - partner-customer-payouts
      summary: List payout schemes for a customer fiat account
      description: List **payout schemes** for this fiat account before preview.
      operationId: partner_customer_list_payout_methods_partner_customers__customer_id__accounts__account_id__payout_methods_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
        description: Public customer id returned by POST /partner/customers
        example: pcus_a1b2c3d4e5f6
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
          description: Account id returned by the customer account API
          title: Account Id
        description: Account id returned by the customer account API
      responses:
        '200':
          description: Schemes and required fields for this fiat account currency.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Payout methods
                data:
                  account_id: 39
                  account_status: active
                  currency: NGN
                  customer_id: pcus_a1b2c3d4e5f6
                  methods:
                  - scheme: nip
                    country: NG
                    default: true
                    required_fields:
                    - bank_code
                    - account_number
                    - bank_name
                    - country
                    - account_holder_name
                  - scheme: swift
                    country: ''
                    default: false
                    required_fields:
                    - swift_bic
                    - bank_name
                    - country
                    - account_holder_name
                    require_one_of:
                    - - iban
                      - account_number
        '422':
          description: Currency does not support external bank payouts
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: External bank payout is not supported for this currency
                data:
                  currency: XXX
                  supported:
                  - CAD
                  - EUR
                  - USD
                  - GBP
                  - AED
                  - NGN
                  - GHS
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
      x-mint:
        content: |-
          List **payout schemes** for this fiat account before preview.

          ### What to use
          - `methods[].scheme` — send as `bank.scheme` (or omit when `default: true`)
          - `required_fields` / `require_one_of` / `optional_fields` / `aliases`

          ### SWIFT
          `require_one_of` means **iban or account_number** (not both optional).

          Full guide: [External bank payouts](/customers/payouts).
  /partner/customers/{customer_id}/accounts/{account_id}/payout-banks:
    get:
      tags:
      - partner-customer-payouts
      summary: List destination banks for a customer fiat payout account
      description: Bank routing directory for **local** payout rails (NGN / GHS / CAD).
      operationId: partner_customer_list_payout_banks_partner_customers__customer_id__accounts__account_id__payout_banks_get
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
        description: Public customer id returned by POST /partner/customers
        example: pcus_a1b2c3d4e5f6
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
          description: Account id returned by the customer account API
          title: Account Id
        description: Account id returned by the customer account API
      responses:
        '200':
          description: Local bank directory (bank_code / bank_name) for this account country.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Payout banks
                data:
                  account_id: 39
                  currency: NGN
                  country: NG
                  customer_id: pcus_a1b2c3d4e5f6
                  banks:
                  - bank_code: '044'
                    bank_name: Access Bank
                    swift_bic: ABNGNGLA
                  - bank_code: 058
                    bank_name: Guaranty Trust Bank
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
      x-mint:
        content: |-
          Bank routing directory for **local** payout rails (NGN / GHS / CAD).

          Use `bank_code` + `bank_name` from `data.banks[]` on preview. Not the same as corridor [`GET /partner/banks`](/partner/banks) (`network_id` for quotes).

          Country is derived from the account currency. Empty `banks` when no directory exists for that currency.

          Guide: [External bank payouts](/customers/payouts).
  /partner/customers/{customer_id}/accounts/{account_id}/payouts/preview:
    post:
      tags:
      - partner-customer-payouts
      summary: Preview an external bank payout for a ready customer account
      description: Preview a same-currency fiat payout to an external bank.
      operationId: partner_customer_preview_payout_partner_customers__customer_id__accounts__account_id__payouts_preview_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
        description: Public customer id returned by POST /partner/customers
        example: pcus_a1b2c3d4e5f6
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
          description: Account id returned by the customer account API
          title: Account Id
        description: Account id returned by the customer account API
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerEntityPayoutPreviewRequest'
      responses:
        '201':
          description: Preview token for confirm. Fee often pending_confirm until confirm.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Payout preview
                data:
                  preview_token: nvpay.eyJhbGciOiJIUzI1NiJ9.preview
                  currency: NGN
                  from_account_id: 39
                  amount: '1.00'
                  fee: null
                  receive_amount: null
                  fee_status: pending_confirm
                  scheme: nip
                  destination:
                    rail: bank
                    country: NG
                    scheme: nip
                    bank_name: Access Bank
                    account_number_masked: '****0031'
                  expires_at: '2026-09-14T12:10:00+00:00'
                  customer_id: pcus_a1b2c3d4e5f6
        '422':
          description: Insufficient balance or invalid bank fields
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Insufficient balance
                data:
                  available: '0.00'
                  amount: '1.00'
                  currency: NGN
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
      x-mint:
        content: |-
          Preview a same-currency fiat payout to an external bank.

          Requires `available >= amount`. Call [`payout-methods`](/customers/payouts) (and [`payout-banks`](/customers/payouts) for local rails) first. Returns `preview_token`; fees may be `pending_confirm` until confirm.

          Guide: [External bank payouts](/customers/payouts).
  /partner/customers/{customer_id}/accounts/{account_id}/payouts:
    post:
      tags:
      - partner-customer-payouts
      summary: Confirm an external bank payout for a ready customer account
      description: Confirm a payout with `preview_token` + `idempotency_key`.
      operationId: partner_customer_confirm_payout_partner_customers__customer_id__accounts__account_id__payouts_post
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
        description: Public customer id returned by POST /partner/customers
        example: pcus_a1b2c3d4e5f6
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
          description: Account id returned by the customer account API
          title: Account Id
        description: Account id returned by the customer account API
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PartnerEntityPayoutConfirmRequest'
      responses:
        '201':
          description: External bank payout accepted for processing.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Payout submitted
                data:
                  id: 101
                  status: submitted
                  from_account_id: 39
                  currency: NGN
                  amount: '1.00'
                  fee: '0.50'
                  receive_amount: '0.50'
                  fee_status: final
                  scheme: nip
                  destination:
                    rail: bank
                    country: NG
                    scheme: nip
                    bank_name: Access Bank
                    account_number_masked: '****0031'
                  created_at: '2026-09-14T12:05:00+00:00'
                  customer_id: pcus_a1b2c3d4e5f6
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
      x-mint:
        content: |-
          Confirm a payout with `preview_token` + `idempotency_key`.

          On live this **sends funds**. Reuse the same idempotency key after network errors; re-preview if the token expired.

          Guide: [External bank payouts](/customers/payouts).
  /partner/customers/{customer_id}/accounts/{account_id}/payouts/{payout_id}:
    get:
      tags:
      - partner-customer-payouts
      summary: Get an external bank payout for a ready customer account
      description: Poll payout status after confirm.
      operationId: partner_customer_get_payout_partner_customers__customer_id__accounts__account_id__payouts__payout_id__get
      security:
      - APIKeyHeader: []
      parameters:
      - name: customer_id
        in: path
        required: true
        schema:
          type: string
          description: Public customer id returned by POST /partner/customers
          examples:
          - pcus_a1b2c3d4e5f6
          title: Customer Id
        description: Public customer id returned by POST /partner/customers
        example: pcus_a1b2c3d4e5f6
      - name: account_id
        in: path
        required: true
        schema:
          type: integer
          minimum: 1
          description: Account id returned by the customer account API
          title: Account Id
        description: Account id returned by the customer account API
      - name: payout_id
        in: path
        required: true
        schema:
          type: string
          minLength: 8
          description: Payout id returned by payout confirm
          title: Payout Id
        description: Payout id returned by payout confirm
      responses:
        '200':
          description: Payout status for polling.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PartnerSuccessEnvelope'
              example:
                status: success
                message: Payout
                data:
                  id: 101
                  status: submitted
                  from_account_id: 39
                  currency: NGN
                  amount: '1.00'
                  fee: '0.50'
                  receive_amount: '0.50'
                  fee_status: final
                  scheme: nip
                  destination:
                    rail: bank
                    country: NG
                    scheme: nip
                    bank_name: Access Bank
                    account_number_masked: '****0031'
                  created_at: '2026-09-14T12:05:00+00:00'
                  customer_id: pcus_a1b2c3d4e5f6
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Validation error
                data:
                  field: country
        '401':
          description: Missing or invalid API key
          content:
            application/json:
              schema:
                type: object
                required:
                - status
                - message
                properties:
                  status:
                    type: string
                    enum:
                    - error
                  message:
                    type: string
                  data:
                    type:
                    - object
                    - 'null'
              example:
                status: error
                message: Unauthorized
                data: null
      x-mint:
        content: |-
          Poll payout status after confirm.

          Guide: [External bank payouts](/customers/payouts).
components:
  schemas:
    HTTPValidationError:
      properties: {}
      type: object
      title: HTTPValidationError
    PartnerOrderAcceptRequest:
      properties:
        provider:
          anyOf:
          - type: string
            enum:
            - local fiat rail
            - international bank
            - elementpay
          - type: 'null'
          title: Provider
          description: Optional provider assertion. Usually inferred from quote_id.
        payment_method:
          anyOf:
          - type: object
          - type: 'null'
          title: Payment Method
          description: |-
            Required for international bank OffRamp: form fields from the corridor's ``form_schema`` (returned in the quote response). Keys match the international bank FormSchema properties e.g. ``BankDetails``, ``AccountHolderName``, ``PaymentPurpose``.
      additionalProperties: false
      type: object
      title: PartnerOrderAcceptRequest
      description: Accept a partner quote. Empty body is supported when quote_id identifies the route.
      examples:
      - {}
      - rail: local_fiat
    PartnerOrderQuoteRequest:
      properties:
        provider:
          anyOf:
          - type: string
            enum:
            - local fiat rail
            - international bank
            - elementpay
            - native
          - type: 'null'
          title: Provider
          description: |-
            Optional route override. Omit for ElementPay auto-routing. Use `elementpay` for native on-chain routes; `local fiat rail` and `international bank` for ramp providers.
        order_type:
          enum:
          - OnRamp
          - OffRamp
          - onramp
          - offramp
          - 0
          - 1
          title: Order Type
          description: OnRamp/0 = fiat to crypto. OffRamp/1 = crypto to fiat.
        token:
          anyOf:
          - type: string
          - type: 'null'
          title: Token
          description: Token contract address or route token hint. local fiat rail currently requires Base USDC or Polygon
            USDT address.
        channel_id:
          anyOf:
          - type: string
            minLength: 1
          - type: 'null'
          title: Channel Id
        channel_type:
          anyOf:
          - type: string
          - type: 'null'
          title: Channel Type
        sequence_id:
          anyOf:
          - type: string
          - type: 'null'
          title: Sequence Id
        currency:
          anyOf:
          - type: string
            maxLength: 3
            minLength: 3
          - type: 'null'
          title: Currency
        country:
          anyOf:
          - type: string
            maxLength: 2
            minLength: 2
          - type: 'null'
          title: Country
        reason:
          type: string
          title: Reason
          default: other
        customer_uid:
          anyOf:
          - type: string
          - type: 'null'
          title: Customer Uid
        customer_type:
          type: string
          enum:
          - retail
          - institution
          title: Customer Type
          default: retail
        asset:
          anyOf:
          - type: object
          - type: 'null'
          title: Asset
          description: |-
            Canonical crypto asset block. Use `token` for contract-address based routes and `currency` + `network` for provider currency routes.
        subject_type:
          anyOf:
          - type: string
            enum:
            - user
            - organization
          - type: 'null'
          title: Subject Type
          description: |-
            Stable subject type for providers that require pre-approved PSP customer links (for example international bank USD/EUR IBAN payins).
        subject_id:
          anyOf:
          - type: string
            maxLength: 64
          - type: 'null'
          title: Subject Id
          description: Stable subject id used to resolve provider approval/onboarding state.
        crypto_currency:
          anyOf:
          - type: string
          - type: 'null'
          title: Crypto Currency
          description: Provider crypto currency hint, e.g. USDC or USDC_TEST for international bank.
        crypto_network:
          anyOf:
          - type: string
          - type: 'null'
          title: Crypto Network
          description: Provider network hint, e.g. Base or PolygonTestAmoy for international bank.
        amount:
          anyOf:
          - type: number
          - type: string
          - type: 'null'
          title: Amount
        local_amount:
          anyOf:
          - type: integer
            minimum: 1.0
          - type: 'null'
          title: Local Amount
        fiat_amount:
          anyOf:
          - type: integer
            minimum: 1.0
          - type: 'null'
          title: Fiat Amount
        crypto_amount:
          anyOf:
          - type: number
            exclusiveMinimum: 0.0
          - type: string
          - type: 'null'
          title: Crypto Amount
        customer:
          anyOf:
          - type: object
          - type: 'null'
          title: Customer
          description: |-
            Provider-neutral customer details. Retail: personal KYC fields (name, dob, id_number, …). Institution (`type: institution` with top-level `customer_type: institution`): `uid`, `business_name`, `business_id` (legal registration/tax id of the paying business), and `email` — no DOB / national ID / personal name. Used to derive provider party details when provider-specific fields are omitted.
        payment_method:
          anyOf:
          - type: object
          - type: 'null'
          title: Payment Method
          description: |-
            Provider-neutral fiat rail. For ``type: mobile_money`` use ``phone_number`` (MSISDN) and ``network_id`` (institution UUID from catalog ``providers[].id``). For ``type: bank`` use ``account_number``, ``account_name``, and ``network_id`` (UUID from ``GET /banks`` or catalog). Do not use top-level legacy fields.
        recipient:
          anyOf:
          - type: object
          - type: 'null'
          title: Recipient
        source:
          anyOf:
          - type: object
          - type: 'null'
          title: Source
        sender:
          anyOf:
          - type: object
          - type: 'null'
          title: Sender
        destination:
          anyOf:
          - type: object
          - type: 'null'
          title: Destination
        wallet_address:
          anyOf:
          - type: string
          - type: 'null'
          title: Wallet Address
        wallet_tag:
          anyOf:
          - type: string
          - type: 'null'
          title: Wallet Tag
        refund_address:
          anyOf:
          - type: string
          - type: 'null'
          title: Refund Address
        sender_address:
          anyOf:
          - type: string
          - type: 'null'
          title: Sender Address
        refund_to_source_address:
          type: boolean
          title: Refund To Source Address
          default: false
        redirect_url:
          anyOf:
          - type: string
          - type: 'null'
          title: Redirect Url
      type: object
      required:
      - order_type
      title: PartnerOrderQuoteRequest
      description: |-
        Generic partner quote request for the `quote -> accept -> webhook` flow. `provider` is optional. When omitted, the partner order router selects the route from country, currency, order type, payment method, asset, and amount. New partner integrations should use the canonical `asset`, `customer`, and `payment_method` blocks. For local fiat rail momo/bank, ``payment_method.network_id`` is required (catalog or ``GET /banks``). For mobile money MSISDN, use ``payment_method.phone_number`` only — do not fall back to ``customer.phone``. Legacy provider-specific blocks (``destination``, etc.) are still accepted and mapped to the canonical request fields.
      examples:
      - asset:
          currency: USDC
          network: BASE
          token: '0x833589fcd6edb6e08f4c7c32d4f71b54bda02913'
        country: KE
        currency: KES
        customer:
          address: Nairobi
          country: KE
          dob: 02/01/1997
          email: jane@example.com
          id_number: A1234567
          id_type: passport
          name: Successful Jane Customer
          phone: '+2541111111111'
          type: user
          uid: sandbox-ke-onramp-success-001
        local_amount: 800
        order_type: OnRamp
        payment_method:
          network_id: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
          phone_number: '+2541111111111'
          type: mobile_money
        wallet_address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
      - asset:
          currency: USDT
          network: POLYGON
          token: '0xc2132d05d31c914a87c6611c10748aeb04b58e8f'
        country: KE
        crypto_amount: 20
        currency: KES
        customer:
          address: Nairobi
          country: KE
          dob: 02/01/1997
          email: jane@example.com
          idNumber: A1234567
          idType: passport
          name: Successful Jane Customer
          phone: '+254712345678'
          type: user
          uid: sandbox-ke-offramp-success-001
        order_type: OffRamp
        payment_method:
          account_name: Successful Jane Customer
          network_id: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
          phone_number: '+2541111111111'
          type: mobile_money
        rail: local_fiat
        refund_address: '0x3333333333333333333333333333333333333333'
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
            - type: string
            - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
      - loc
      - msg
      - type
      title: ValidationError
    PartnerCustomerDocumentMeta:
      type: object
      required:
      - id
      - category
      - content_type
      - created_at
      properties:
        id:
          type: string
          description: Public document id (pdoc_*).
          example: pdoc_a1b2c3d4e5f6
        category:
          type: string
          description: Document key from requirements (e.g. identity, address).
          example: identity
        content_type:
          type: string
          example: application/pdf
        created_at:
          type: string
          format: date-time
      title: PartnerCustomerDocumentMeta
      description: Uploaded document metadata (no file bytes).
    PartnerCustomerVaultRow:
      type: object
      required:
      - id
      - partner_customer_ref
      - type
      - status
      - profile
      - documents
      - products
      - created_at
      - updated_at
      properties:
        id:
          type: string
          description: Public customer id (pcus_*).
          example: pcus_a1b2c3d4e5f6
        partner_customer_ref:
          type: string
          description: Partner-stable customer reference.
          example: partner-cust-001
        type:
          type: string
          enum:
          - individual
          - business
        status:
          type: string
          enum:
          - incomplete
          - pending_review
          - approved
          - active
          - rejected
          - suspended
        profile:
          type: object
          description: Collected identity / KYB fields.
          additionalProperties: true
        documents:
          type: array
          items:
            $ref: '#/components/schemas/PartnerCustomerDocumentMeta'
          description: Document metadata. Populated on ref lookup and GET by id; often empty on unpaginated list rows.
        products:
          type: object
          required:
          - deposit_account
          properties:
            deposit_account:
              type: object
              required:
              - status
              properties:
                status:
                  type: string
                  enum:
                  - none
                  - provisioning
                  - ready
                  - failed
                  - unavailable
        missing:
          type: array
          items:
            type: string
          description: Present when status is incomplete — fields/docs still required before submit.
        review_note:
          type: string
          description: Partner-safe rejection summary when status is rejected.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        submitted_at:
          type:
          - string
          - 'null'
          format: date-time
      title: PartnerCustomerVaultRow
      description: One customer vault case returned to partners.
    PartnerCustomerListData:
      type: object
      required:
      - customers
      properties:
        customers:
          type: array
          items:
            $ref: '#/components/schemas/PartnerCustomerVaultRow'
          description: 'Tenant-scoped customers. With partner_customer_ref: zero or one full row. Without: up to limit summary
            rows.'
      title: PartnerCustomerListData
    PartnerCustomerListSuccessResponse:
      type: object
      required:
      - status
      - message
      - data
      properties:
        status:
          type: string
          enum:
          - success
        message:
          type: string
          example: Customers
        data:
          $ref: '#/components/schemas/PartnerCustomerListData'
      title: PartnerCustomerListSuccessResponse
    PartnerCustomerDocumentUploadRequest:
      properties:
        category:
          type: string
          maxLength: 64
          minLength: 1
          title: Category
          description: Document key from requirements (e.g. identity, address).
          examples:
          - identity
          example: identity
        content_base64:
          type: string
          maxLength: 12000000
          minLength: 1
          title: Content Base64
          description: Base64-encoded file bytes (max ~8 MiB decoded).
          example: |-
            JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFI+PmVuZG9iagoyIDAgb2JqCjw8L1R5cGUvUGFnZXMvQ291bnQgMC9LaWRzW10+PmVuZG9iagp4cmVmCjAgMwowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMDA2OCAwMDAwMCBuIAp0cmFpbGVyCjw8L1NpemUgMy9Sb290IDEgMCBSPj4Kc3RhcnR4cmVmCjEyMQolJUVPRgo=
        content_type:
          anyOf:
          - type: string
          - type: 'null'
          title: Content Type
          description: 'MIME type. Required for upload: image/jpeg, image/png, or application/pdf.'
          examples:
          - image/jpeg
          - application/pdf
          example: application/pdf
        file_name:
          anyOf:
          - type: string
            maxLength: 128
          - type: 'null'
          title: File Name
          description: Optional original filename for the partner only; not stored in object keys.
          example: passport.pdf
      type: object
      required:
      - category
      - content_base64
      title: PartnerCustomerDocumentUploadRequest
      example:
        category: identity
        content_base64: |-
          JVBERi0xLjQKJeLjz9MKMSAwIG9iago8PC9UeXBlL0NhdGFsb2cvUGFnZXMgMiAwIFI+PmVuZG9iagoyIDAgb2JqCjw8L1R5cGUvUGFnZXMvQ291bnQgMC9LaWRzW10+PmVuZG9iagp4cmVmCjAgMwowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMDA2OCAwMDAwMCBuIAp0cmFpbGVyCjw8L1NpemUgMy9Sb290IDEgMCBSPj4Kc3RhcnR4cmVmCjEyMQolJUVPRgo=
        content_type: application/pdf
        file_name: passport.pdf
    PartnerCustomerProfilePatchRequest:
      properties:
        profile:
          type: object
          title: Profile
          description: Partial profile merge into the customer vault.
          example:
            first_name: Jane
            last_name: Doe
            email: jane@example.com
            date_of_birth: '1990-01-15'
            country_of_residence: GB
            phone: '+447700900123'
            gender: f
            address:
              line1: 1 Example Street
              city: London
              country: GB
              postal_code: E1 6AN
      type: object
      required:
      - profile
      title: PartnerCustomerProfilePatchRequest
      example:
        profile:
          first_name: Jane
          last_name: Doe
          email: jane@example.com
          date_of_birth: '1990-01-15'
          country_of_residence: GB
          phone: '+447700900123'
          gender: f
          address:
            line1: 1 Example Street
            city: London
            country: GB
            postal_code: E1 6AN
    PartnerCustomerCreateRequest:
      properties:
        partner_customer_ref:
          type: string
          maxLength: 128
          minLength: 1
          title: Partner Customer Ref
          description: Partner's stable customer reference (unique per tenant).
          examples:
          - cust-ke-001
          example: cust-ke-001
        type:
          type: string
          title: Type
          description: Customer vault package type.
          examples:
          - individual
          example: individual
          enum:
          - individual
          - business
        profile:
          anyOf:
          - type: object
          - type: 'null'
          title: Profile
          description: Identity / KYB fields (see GET /customers/requirements).
          example:
            first_name: Jane
            last_name: Doe
            email: jane@example.com
            date_of_birth: '1990-01-15'
            country_of_residence: GB
            phone: '+447700900123'
            gender: f
            address:
              line1: 1 Example Street
              city: London
              country: GB
              postal_code: E1 6AN
      type: object
      required:
      - partner_customer_ref
      - type
      title: PartnerCustomerCreateRequest
      example:
        partner_customer_ref: cust-ke-001
        type: individual
        profile:
          first_name: Jane
          last_name: Doe
          email: jane@example.com
          date_of_birth: '1990-01-15'
          country_of_residence: GB
          phone: '+447700900123'
          gender: f
          address:
            line1: 1 Example Street
            city: London
            country: GB
            postal_code: E1 6AN
    PartnerCustomerRevokeRequest:
      properties:
        reason:
          anyOf:
          - type: string
            maxLength: 512
          - type: 'null'
          title: Reason
          description: Optional partner audit note (not returned in API responses).
          example: account_closed
      type: object
      title: PartnerCustomerRevokeRequest
      example:
        reason: account_closed
    PartnerCustomerAccountOpenRequest:
      type: object
      required:
      - asset_type
      - currency
      properties:
        asset_type:
          type: string
          description: fiat or stablecoin
          example: fiat
        currency:
          type: string
          example: EUR
        network:
          type: string
          description: 'Required for stablecoin: Base or Polygon'
          example: Base
        display_name:
          type: string
          example: EUR operating
      example:
        asset_type: fiat
        currency: EUR
    PartnerEntitySendPreviewRequest:
      properties:
        to_address:
          type: string
          maxLength: 128
          minLength: 8
          title: To Address
        amount:
          type: string
          title: Amount
          description: Decimal amount in USDC, e.g. 10.50
        network:
          anyOf:
          - type: string
          - type: 'null'
          title: Network
          description: Must match the account network when set (Base or Polygon)
      type: object
      required:
      - to_address
      - amount
      title: PartnerEntitySendPreviewRequest
      description: Preview a same-asset USDC send (fee + receive amount; not an FX quote).
      example:
        amount: '5.00'
        network: Base
        to_address: 0xRecipientWalletAddress
    PartnerEntitySendConfirmRequest:
      properties:
        preview_token:
          type: string
          minLength: 16
          title: Preview Token
          description: Token from sends/preview
        idempotency_key:
          type: string
          maxLength: 64
          minLength: 8
          title: Idempotency Key
          description: Partner-stable id; same key returns the prior send
      type: object
      required:
      - preview_token
      - idempotency_key
      title: PartnerEntitySendConfirmRequest
      description: Confirm a previewed send using the signed preview token.
      example:
        idempotency_key: send-2026-07-30-001
        preview_token: preview_token_from_sends_preview_response
    PartnerOrderQuoteRequestTryIt:
      type: object
      required:
      - order_type
      properties:
        order_type:
          type: string
          enum:
          - OnRamp
          - OffRamp
          description: OnRamp = fiat to crypto. OffRamp = crypto to fiat.
          example: OnRamp
        country:
          type: string
          minLength: 2
          maxLength: 2
          description: ISO country (African corridors). Omit for EUR/USD international bank payin.
          example: KE
        currency:
          type: string
          minLength: 3
          maxLength: 3
          example: KES
        local_amount:
          type: integer
          minimum: 1
          description: 'OnRamp: fiat amount the customer pays.'
          example: 800
        crypto_amount:
          type: number
          exclusiveMinimum: 0
          description: 'OffRamp: stablecoin amount the customer sends.'
          example: 20
        customer_id:
          type: string
          description: Approved vault customer id (pcus_*). Use this **or** inline `customer`, not both.
          example: pcus_a1b2c3d4e5f6
        customer:
          type: object
          description: 'Inline retail KYC when you do not use customer_id. Corridor extras (BVN, institution): /sandbox/test-payloads.'
          properties:
            uid:
              type: string
              description: Partner-stable user id for this order.
              example: sandbox-ke-onramp-success-001
            type:
              type: string
              enum:
              - user
              - institution
              example: user
            name:
              type: string
              example: Successful Jane Customer
            country:
              type: string
              example: KE
            phone:
              type: string
              example: '+2541111111111'
            address:
              type: string
              description: Customer address (required for many local corridors, e.g. KE).
              example: Nairobi
            dob:
              type: string
              description: Date of birth (corridor-specific format, e.g. MM/DD/YYYY for KE).
              example: 02/01/1997
            email:
              type: string
              example: jane@example.com
            id_number:
              type: string
              example: A1234567
            id_type:
              type: string
              example: passport
          additionalProperties: true
        asset:
          type: object
          description: 'Stablecoin asset block (sandbox default: Base USDC).'
          properties:
            token:
              type: string
              example: '0x833589fcd6edb6e08f4c7c32d4f71b54bdA02913'
            currency:
              type: string
              example: USDC
            network:
              type: string
              example: BASE
        payment_method:
          type: object
          description: 'Fiat rail. mobile_money: phone_number + network_id. bank: account_number, account_name, network_id.'
          properties:
            type:
              type: string
              enum:
              - mobile_money
              - bank
              example: mobile_money
            phone_number:
              type: string
              description: E.164 MSISDN (mobile_money).
              example: '+2541111111111'
            account_number:
              type: string
            account_name:
              type: string
            network_id:
              type: string
              description: Institution UUID from GET /partner/catalog.
              example: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
        wallet_address:
          type: string
          description: 'OnRamp: destination wallet for stablecoin delivery.'
          example: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
        refund_address:
          type: string
          description: 'OffRamp: refund wallet if payout fails.'
          example: '0x3333333333333333333333333333333333333333'
      title: PartnerOrderQuoteRequestTryIt
      description: |-
        Quote body for Mintlify Try it. Includes customer_id **or** inline customer, asset, and payment_method only. Not shown here (still accepted on live API if needed): provider, channel_id, channel_type, sequence_id, destination, source, sender, recipient, rail, token top-level alias, crypto_currency/crypto_network hints.
      example:
        order_type: OnRamp
        currency: KES
        country: KE
        local_amount: 800
        customer_id: pcus_a1b2c3d4e5f6
        asset:
          token: '0x833589fcd6edb6e08f4c7c32d4f71b54bdA02913'
          currency: USDC
          network: BASE
        payment_method:
          type: mobile_money
          phone_number: '+2541111111111'
          network_id: 7ea6df5c-6bba-46b2-a7e6-f511959e7edb
        wallet_address: '0xde0B295669a9FD93d5F28D9Ec85E40f4cb697BAe'
    PartnerErrorEnvelope:
      type: object
      required:
      - status
      - message
      properties:
        status:
          type: string
          enum:
          - error
        message:
          type: string
        data:
          type:
          - object
          - 'null'
    PartnerSuccessEnvelope:
      type: object
      required:
      - status
      - message
      - data
      properties:
        status:
          type: string
          enum:
          - success
        message:
          type: string
        data:
          type: object
    PartnerCustomerRequirementsData:
      type: object
      required:
      - type
      - required_fields
      - required_documents
      - optional_fields
      - conditional_fields
      - products
      - notes
      properties:
        type:
          type: string
          enum:
          - individual
          - business
        required_fields:
          type: array
          items:
            type: string
        required_documents:
          type: array
          items:
            type: object
            required:
            - key
            - description
            properties:
              key:
                type: string
              description:
                type: string
        optional_fields:
          type: array
          items:
            type: string
        conditional_fields:
          type: array
          items:
            type: object
            additionalProperties: true
        products:
          type: object
        notes:
          type: string
      title: PartnerCustomerRequirementsData
    PartnerCustomerRequirementsSuccessResponse:
      type: object
      required:
      - status
      - message
      - data
      properties:
        status:
          type: string
          enum:
          - success
        message:
          type: string
          example: Customer requirements
        data:
          $ref: '#/components/schemas/PartnerCustomerRequirementsData'
      title: PartnerCustomerRequirementsSuccessResponse
    PartnerCustomerVaultSuccessResponse:
      type: object
      required:
      - status
      - message
      - data
      properties:
        status:
          type: string
          enum:
          - success
        message:
          type: string
        data:
          $ref: '#/components/schemas/PartnerCustomerVaultRow'
      title: PartnerCustomerVaultSuccessResponse
    PartnerCustomerDocumentUploadData:
      type: object
      required:
      - document
      - customer
      properties:
        document:
          $ref: '#/components/schemas/PartnerCustomerDocumentMeta'
        customer:
          $ref: '#/components/schemas/PartnerCustomerVaultRow'
      title: PartnerCustomerDocumentUploadData
    PartnerCustomerDocumentUploadSuccessResponse:
      type: object
      required:
      - status
      - message
      - data
      properties:
        status:
          type: string
          enum:
          - success
        message:
          type: string
          example: Document uploaded
        data:
          $ref: '#/components/schemas/PartnerCustomerDocumentUploadData'
      title: PartnerCustomerDocumentUploadSuccessResponse
    PartnerCustomerCreateRequestTryIt:
      title: PartnerCustomerCreateRequestTryIt
      description: |-
        Create body for Mintlify Try it. Pick **Individual** or **Business** — `type` and `profile` update together. Live API accepts the same shapes; see GET /partner/customers/requirements for the full package.
      oneOf:
      - title: Individual
        type: object
        required:
        - partner_customer_ref
        - type
        properties:
          partner_customer_ref:
            type: string
            description: Your stable id (unique per tenant).
            example: partner-cust-001
          type:
            type: string
            enum:
            - individual
            description: Individual retail KYC package.
            example: individual
          profile:
            type: object
            description: Individual profile. Requires id_number, id_type, address, and documents before submit.
            example:
              first_name: Jane
              last_name: Doe
              email: jane@example.com
              date_of_birth: '1990-01-15'
              country_of_residence: GB
              phone: '+447700900123'
              gender: f
              id_number: A1234567
              id_type: passport
              address:
                line1: 1 Example Street
                city: London
                country: GB
                postal_code: E1 6AN
            additionalProperties: true
        example:
          partner_customer_ref: partner-cust-001
          type: individual
          profile:
            first_name: Jane
            last_name: Doe
            email: jane@example.com
            date_of_birth: '1990-01-15'
            country_of_residence: GB
            phone: '+447700900123'
            gender: f
            id_number: A1234567
            id_type: passport
            address:
              line1: 1 Example Street
              city: London
              country: GB
              postal_code: E1 6AN
      - title: Business
        type: object
        required:
        - partner_customer_ref
        - type
        properties:
          partner_customer_ref:
            type: string
            description: Your stable id (unique per tenant).
            example: partner-biz-001
          type:
            type: string
            enum:
            - business
            description: Business KYB package.
            example: business
          profile:
            type: object
            description: Business profile including complete profile.officers[] (person + identity_document + address per
              officer).
            example:
              legal_name: Acme Payments Ltd
              email: ops@acme.example
              phone: '+14155550100'
              website: https://acme.example
              business_type: llc
              country_of_incorporation: US
              tax_id: '123456789'
              registration_number: REG-001
              industry: Payment services
              description: B2B payments for SMEs
              registered_address:
                line1: 100 Market Street
                city: San Francisco
                state: CA
                country: US
                postal_code: '94105'
              incorporation_meta:
                year: 2020
                month: 6
                country: US
                state: CA
              monthly_payments_count: 100
              monthly_transaction_value: 250000
              max_transfer_amount: 50000
              annual_turnover: 2000000
              customer_types:
              - b2b
              funding_source: equity
              officers:
              - role: director
                first_name: Ada
                last_name: Lovelace
                date_of_birth: '1990-01-15'
                email: ada@acme.example
                nationality: US
                identity_document:
                  type: passport
                  number: A1234567
                  issuing_country: US
                address:
                  line1: 200 Officer Lane
                  city: San Francisco
                  state: CA
                  country: US
                  postal_code: '94105'
            additionalProperties: true
        example:
          partner_customer_ref: partner-biz-001
          type: business
          profile:
            legal_name: Acme Payments Ltd
            email: ops@acme.example
            phone: '+14155550100'
            website: https://acme.example
            business_type: llc
            country_of_incorporation: US
            tax_id: '123456789'
            registration_number: REG-001
            industry: Payment services
            description: B2B payments for SMEs
            registered_address:
              line1: 100 Market Street
              city: San Francisco
              state: CA
              country: US
              postal_code: '94105'
            incorporation_meta:
              year: 2020
              month: 6
              country: US
              state: CA
            monthly_payments_count: 100
            monthly_transaction_value: 250000
            max_transfer_amount: 50000
            annual_turnover: 2000000
            customer_types:
            - b2b
            funding_source: equity
            officers:
            - role: director
              first_name: Ada
              last_name: Lovelace
              date_of_birth: '1990-01-15'
              email: ada@acme.example
              nationality: US
              identity_document:
                type: passport
                number: A1234567
                issuing_country: US
              address:
                line1: 200 Officer Lane
                city: San Francisco
                state: CA
                country: US
                postal_code: '94105'
    PartnerEntityPayoutBank:
      properties:
        scheme:
          anyOf:
          - type: string
          - type: 'null'
          title: Scheme
          description: |-
            CAD: eft|interac_email|interac_account; USD: ach|wire; NGN: nip; GHS: gh_eft|eft; swift for cross-border / non-local corridors
        swift_bic:
          anyOf:
          - type: string
          - type: 'null'
          title: Swift Bic
          description: Required for scheme=swift
        iban:
          anyOf:
          - type: string
          - type: 'null'
          title: Iban
        routing_number:
          anyOf:
          - type: string
          - type: 'null'
          title: Routing Number
        account_type:
          anyOf:
          - type: string
          - type: 'null'
          title: Account Type
          description: USD — checking or savings
        bank_institution_number:
          anyOf:
          - type: string
          - type: 'null'
          title: Bank Institution Number
          description: CAD EFT / Interac account — 3 digits
        transit_number:
          anyOf:
          - type: string
          - type: 'null'
          title: Transit Number
          description: CAD EFT / Interac account — 5 digits
        bank_code:
          anyOf:
          - type: string
          - type: 'null'
          title: Bank Code
          description: Local bank code — NGN NIP, GHS EFT (and similar bank-code rails)
        account_number:
          anyOf:
          - type: string
          - type: 'null'
          title: Account Number
        email:
          anyOf:
          - type: string
          - type: 'null'
          title: Email
          description: Required for CAD scheme=interac_email (Interac e-Transfer destination)
        account_holder_name:
          type: string
          maxLength: 128
          minLength: 1
          title: Account Holder Name
        bank_name:
          anyOf:
          - type: string
            maxLength: 128
            minLength: 1
          - type: 'null'
          title: Bank Name
          description: Required except CAD interac_email
        country:
          type: string
          maxLength: 2
          minLength: 2
          title: Country
          description: ISO-3166 alpha-2
      type: object
      required:
      - account_holder_name
      - country
      title: PartnerEntityPayoutBank
      description: |-
        External bank destination. Required fields depend on account currency / scheme. CAD local: scheme ``eft`` (default) | ``interac_email`` | ``interac_account`` - eft / interac_account: bank_institution_number (3), transit_number (5), account_number, bank_name, country=CA - interac_email: email, account_holder_name, country=CA (bank_name optional) EUR SEPA: iban, country (EU), optional swift_bic USD ACH/wire: routing_number, account_number, country=US, optional scheme/account_type NGN NIP: bank_code, account_number, bank_name, country=NG (scheme ``nip`` or omit) GHS EFT: bank_code, account_number, bank_name, country=GH (scheme ``gh_eft``, ``eft``, or omit) SWIFT: scheme=swift, swift_bic, plus iban or account_number (any supported currency)
    PartnerEntityPayoutBeneficiary:
      properties:
        first_name:
          type: string
          maxLength: 64
          minLength: 1
          title: First Name
        last_name:
          type: string
          maxLength: 64
          minLength: 1
          title: Last Name
        email:
          type: string
          maxLength: 254
          minLength: 3
          title: Email
        address:
          $ref: '#/components/schemas/PartnerEntityResidentialAddress'
      type: object
      required:
      - first_name
      - last_name
      - email
      - address
      title: PartnerEntityPayoutBeneficiary
      description: External payout recipient identity (counterparty).
    PartnerEntityPayoutConfirmRequest:
      properties:
        preview_token:
          type: string
          minLength: 16
          title: Preview Token
          description: Token from payouts/preview
        idempotency_key:
          type: string
          maxLength: 64
          minLength: 8
          title: Idempotency Key
          description: Partner-stable id; same key returns the prior payout
      type: object
      required:
      - preview_token
      - idempotency_key
      title: PartnerEntityPayoutConfirmRequest
      description: Confirm a previewed bank payout using the signed preview token.
    PartnerEntityPayoutPreviewRequest:
      properties:
        amount:
          type: string
          title: Amount
          description: Decimal amount in account currency, e.g. 1.00
        beneficiary:
          $ref: '#/components/schemas/PartnerEntityPayoutBeneficiary'
        bank:
          $ref: '#/components/schemas/PartnerEntityPayoutBank'
        security_question:
          anyOf:
          - type: string
            maxLength: 256
            minLength: 1
          - type: 'null'
          title: Security Question
          description: |-
            CAD Interac outbound only: question the recipient must answer to deposit. Requires security_answer. Mapped upstream as payment-details meta.
        security_answer:
          anyOf:
          - type: string
            maxLength: 128
            minLength: 1
          - type: 'null'
          title: Security Answer
          description: |-
            CAD Interac outbound only: answer for security_question. Share with the recipient out-of-band; never returned in partner responses.
      type: object
      required:
      - amount
      - beneficiary
      - bank
      title: PartnerEntityPayoutPreviewRequest
      description: Preview an external bank payout from a fiat account (same-currency, no FX).
    PartnerEntityResidentialAddress:
      properties:
        line_1:
          type: string
          title: Line 1
        city:
          type: string
          title: City
        country:
          type: string
          maxLength: 2
          minLength: 2
          title: Country
          description: ISO-3166 alpha-2
        line_2:
          anyOf:
          - type: string
          - type: 'null'
          title: Line 2
        state:
          anyOf:
          - type: string
          - type: 'null'
          title: State
        postal_code:
          anyOf:
          - type: string
          - type: 'null'
          title: Postal Code
      type: object
      required:
      - line_1
      - city
      - country
      title: PartnerEntityResidentialAddress
      description: Partner address shape; mapped to upstream ``country_code`` on attach.
    PartnerWebhookHeaders:
      type: object
      description: |-
        Headers on every webhook delivery. Signature: HMAC-SHA256 over `{t}.{raw_body}` using `webhook_secret`, base64-encoded as `v1`. Reject if `t` older than 5 minutes. Deduplicate with `X-Webhook-Id`.
      properties:
        Content-Type:
          type: string
          const: application/json
        User-Agent:
          type: string
          example: ElementPay/1.0 (+support@elementpay.net)
        X-Webhook-Event:
          type: string
          description: Event name
          enum:
          - order.processing
          - order.settled
          - order.failed
          - order.refunded
          - customer.submitted
          - customer.approved
          - customer.rejected
          - customer.revoked
          - customer.updated
          - customer.deposit_account.updated
          - account.opened
          - account.ready
          - account.credited
          - account.send.completed
          - account.send.failed
        X-Webhook-Id:
          type: string
          format: uuid
          description: Idempotency key for this delivery
        X-Webhook-Signature:
          type: string
          description: 'Format: `t=<unix_ts>,v1=<base64_hmac>`'
          example: t=1710000000,v1=<base64_signature>
      required:
      - X-Webhook-Event
      - X-Webhook-Id
      - X-Webhook-Signature
    PartnerOrderWebhookPayload:
      type: object
      description: Typical order webhook body. Fields vary by corridor and rail. `client_metadata` and upstream PSP blobs
        are not included.
      properties:
        order_id:
          type: string
          example: YC-580e04c2-a136-5cca-be54-b49fcf80970c
        status:
          type: string
          example: settled
        amount_fiat:
          type: number
          example: 800.0
        currency:
          type: string
          example: KES
        amount_crypto:
          type: number
          example: 5.12
        exchange_rate:
          type: number
          example: 156.25
        order_type:
          type: string
          example: OnRamp
        wallet_address:
          type: string
          example: '0x4F07419E6bfCCF8D256E8ef803Cc2653dfbB9558'
        phone_number:
          type: string
          example: '2541111111111'
        settlement_transaction_hash:
          type: string
          example: 0xabc...
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - order_id
      - status
      example: &id001
        order_id: YC-580e04c2-a136-5cca-be54-b49fcf80970c
        status: settled
        amount_fiat: 800.0
        currency: KES
        amount_crypto: 5.12
        exchange_rate: 156.25
        order_type: OnRamp
        wallet_address: '0x4F07419E6bfCCF8D256E8ef803Cc2653dfbB9558'
        phone_number: '2541111111111'
        settlement_transaction_hash: 0xabc...
        created_at: '2026-07-07T10:00:00.000000Z'
        updated_at: '2026-07-07T10:00:15.000000Z'
    PartnerCustomerWebhookPayload:
      type: object
      description: Customer / deposit-account webhook body (example from docs).
      properties:
        customer_id:
          type: string
          example: pcus_…
        partner_customer_ref:
          type: string
          example: partner-cust-001
        type:
          type: string
          example: individual
        status:
          type: string
          example: approved
        environment:
          type: string
          example: sandbox
        submitted_at:
          type: string
          format: date-time
        reviewed_at:
          type: string
          format: date-time
        products:
          type: object
          properties:
            deposit_account:
              type: object
              properties:
                status:
                  type: string
                  example: ready
        can_open_deposit_account:
          type: boolean
      required:
      - customer_id
      - status
  securitySchemes:
    JWTBearer:
      type: http
      scheme: bearer
      description: Not used by `/partner/*` routes. Partner auth is `APIKeyHeader` (`X-API-Key`) only.
    APIKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
      description: |-
        Partner API key. Sandbox keys start with `is_test_`; production keys start with `is_live_`. Keys are not interchangeable across environments. Send on every request. Never expose in browser or mobile clients.
    HTTPBearer:
      type: http
      scheme: bearer
      description: Not used by `/partner/*` routes. Partner auth is `APIKeyHeader` (`X-API-Key`) only.
tags:
- name: partner
  description: |-
    Corridor discovery, indicative rates, binding quotes, and order acceptance (including order-path account currency conversion rails). Customer ledger conversions use partner-customer-transfers `/conversions`.
  x-group: Partner
- name: partner-customers
  description: 'Vault KYC: requirements, create, list, get/update, documents, submit, and revoke (`pcus_*`).'
  x-group: Customers
- name: partner-customer-accounts
  description: 'Customer deposit rails: open / list / get accounts and deposit instructions.'
  x-group: Customer accounts
- name: partner-customer-transfers
  description: 'On-ledger money movement: stablecoin sends, same-currency book transfers, and cross-currency conversions.'
  x-group: Customer transfers
- name: partner-customer-payouts
  description: 'External bank payouts: scheme discovery, local bank directory (NGN/GHS/CAD), preview, confirm, and status.'
  x-group: Customer payouts
servers:
- url: https://sandbox.elementpay.net/api/v1
  description: Sandbox (API keys prefixed is_test_)
- url: https://api.elementpay.net/api/v1
  description: Production (API keys prefixed is_live_)
security:
- APIKeyHeader: []
webhooks:
  partnerEvent:
    post:
      summary: Partner webhook delivery
      description: |-
        Element Pay POSTs to your configured `webhook_url` when orders, customers, or accounts change. Treat webhooks as the source of truth for settlement and KYC readiness.

        **Signature verification**
        1. Parse `X-Webhook-Signature`: `t=<unix_ts>,v1=<base64_hmac>`.
        2. Reject if `t` is older than 5 minutes.
        3. Compute HMAC-SHA256 over `{t}.{raw_body}` with `webhook_secret`; constant-time compare to `v1`.

        **Idempotency:** dedupe on `X-Webhook-Id`. Return 2xx quickly.

        Guide: `webhooks.mdx` / hosted `/webhooks`.
      parameters:
      - name: X-Webhook-Event
        in: header
        required: true
        schema:
          type: string
          enum:
          - order.processing
          - order.settled
          - order.failed
          - order.refunded
          - customer.submitted
          - customer.approved
          - customer.rejected
          - customer.revoked
          - customer.updated
          - customer.deposit_account.updated
          - account.opened
          - account.ready
          - account.credited
          - account.send.completed
          - account.send.failed
      - name: X-Webhook-Id
        in: header
        required: true
        schema:
          type: string
          format: uuid
      - name: X-Webhook-Signature
        in: header
        required: true
        schema:
          type: string
        description: '`t=<unix_ts>,v1=<base64_hmac>`'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
              - $ref: '#/components/schemas/PartnerOrderWebhookPayload'
              - $ref: '#/components/schemas/PartnerCustomerWebhookPayload'
              description: 'Payload shape depends on X-Webhook-Event. Account event bodies: TODO - see docs/KNOWN_GAPS.md.'
            examples:
              order.settled:
                summary: order.settled
                value: *id001
              customer.approved:
                summary: customer.approved
                value:
                  customer_id: pcus_…
                  partner_customer_ref: partner-cust-001
                  type: individual
                  status: approved
                  environment: sandbox
                  submitted_at: '2026-08-01T12:00:00+00:00'
                  reviewed_at: '2026-08-01T12:05:00+00:00'
                  products:
                    deposit_account:
                      status: ready
      responses:
        2XX:
          description: Acknowledge receipt. Return any 2xx quickly; process asynchronously if needed.
