> ## Documentation Index
> Fetch the complete documentation index at: https://www.bitnob.dev/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Bitnob API requests authenticate with an `X-Auth-Client` API key header against https://api.bitnob.com.
> Always use the sandbox environment for testing. Never put live API keys in sample code.
> Money amounts are integers in the smallest unit of the currency (satoshis for BTC, cents for fiat). Never use floats.
> Every state-changing request takes a client-supplied `reference` and must be treated as idempotent on retry.
> Quotes expire. Re-quote rather than reusing a stale quote id.

# Initialize a payout

> Step 2 of 3: attaches a beneficiary to a quote and returns the final fees and total_amount. The beneficiary must meet the country's requirements (GET /api/payouts/supported-countries/{country}). For an onchain quote, address and deposit_amount say where and how much to send.



## OpenAPI

````yaml /api-collections/swagger/bitnob-api-v2.openapi.json post /api/payouts/{quoteId}/initialize
openapi: 3.1.0
info:
  description: >-
    The Bitnob API for businesses: customers, virtual accounts, cards, payouts,
    crypto addresses and transfers, Lightning, trading and exchange rates.


    ## Authentication

    Every request is signed with your API key's client id and secret.


    **Signed requests (recommended).** Send:

    - `X-Auth-Client`: your client id

    - `X-Auth-Timestamp`: the current Unix time in seconds; requests more than 5
    minutes off are refused

    - `X-Auth-Nonce`: a unique random string for this request

    - `X-Auth-Signature`: hex HMAC-SHA256 of
    `{client_id}:{timestamp}:{nonce}:{body}` using your secret, where body is
    the raw request body (empty for GET)


    **Secret mode.** Send `X-Auth-Client` and `X-Auth-Secret` instead. Simpler,
    but the secret travels with every request.


    Live keys work only for an active organisation; sandbox keys work at any
    time. `ANY /api/whoami` echoes the authenticated client and is the quickest
    way to check your signing.


    ## Responses

    Successful responses are wrapped in an envelope with `success`, `message`,
    `data` and, on lists, `metadata`. Errors come either as the envelope with
    `success: false` and an `error` object, or as an RFC 7807 problem with a
    machine-readable `code`; branch on the code.


    Every response carries an `X-Correlation-ID` header; errors repeat it as
    `request_id`. Quote it to support.



    Every request passes a per-IP rate limit of 500 requests a minute (429 with
    `Retry-After`).



    This document is maintained by hand and checked against the route table on
    every build: every /api route is listed here.
  title: Bitnob API
  version: 1.0.0
servers:
  - description: Production
    url: https://api.bitnob.com
security:
  - BitnobClientId: []
    BitnobClientSecret: []
tags:
  - description: Check that your requests are signed correctly.
    name: Authentication
  - description: >-
      The people and businesses you serve. Creating and editing them needs the
      customers feature.
    name: Customers
  - description: >-
      Naira accounts that receive bank transfers, for your company or for a
      customer.
    name: Virtual accounts
  - description: Crypto deposit addresses, for your company or for a customer.
    name: Addresses
  - description: >-
      Virtual cards: issue, fund, withdraw, freeze, terminate, and the card KYC
      and corporate onboarding behind them.
    name: Cards
  - description: 'Pay out to bank accounts and mobile money: quote, initialize, finalize.'
    name: Payouts
  - description: Saved payout recipients.
    name: Beneficiaries
  - description: Banks and account lookups for payouts.
    name: Banks
  - description: Balance transfers between Bitnob organisations.
    name: Transfers
  - description: Crypto withdrawals.
    name: Withdrawals
  - description: Lightning invoices and payments.
    name: Lightning
  - description: Lightning addresses, LNURL withdraw links and LNURL payments.
    name: LNURL
  - description: Blockchain node access.
    name: Nodes
  - description: Quotes and orders for buying and selling.
    name: Trading
  - description: Rates and conversions.
    name: Exchange rates
  - description: Your transaction history.
    name: Transactions
  - description: Wallet balances.
    name: Balances
paths:
  /api/payouts/{quoteId}/initialize:
    post:
      tags:
        - Payouts
      summary: Initialize a payout
      description: >-
        Step 2 of 3: attaches a beneficiary to a quote and returns the final
        fees and total_amount. The beneficiary must meet the country's
        requirements (GET /api/payouts/supported-countries/{country}). For an
        onchain quote, address and deposit_amount say where and how much to
        send.
      operationId: payoutsInitialize
      parameters:
        - description: The quote_id returned when the quote was created
          example: QT2_100482
          in: path
          name: quoteId
          required: true
          schema:
            type: string
      requestBody:
        content:
          application/json:
            examples:
              for_a_customer:
                summary: On behalf of one of your customers
                value:
                  beneficiary:
                    account_name: Adaeze Okafor
                    account_number: '0000000001'
                    bank_code: '000014'
                    country: NG
                    destination_type: bank
                  customer_id: 019a3b61-8eb7-76d9-a1a2-4d5e6f7a8b9a
                  metadata: '{"order_id":"ord_sbx_5521"}'
                  reference: payout_ref_20261030_0012
              ghs_mobile_money:
                summary: Ghana mobile money (MTN)
                value:
                  beneficiary:
                    account_name: Kwame Mensah
                    account_number: '0240000001'
                    country: GH
                    destination_type: mobile_money
                    network: mtn
              ngn_bank:
                summary: Nigerian bank account
                value:
                  beneficiary:
                    account_name: Adaeze Okafor
                    account_number: '0000000001'
                    bank_code: '000014'
                    country: NG
                    destination_type: bank
                  callback_url: https://example.com/webhooks/payouts
              swift_with_invoice:
                summary: SWIFT payout with the uploaded invoice
                value:
                  beneficiary:
                    account_name: Kwame Mensah Trading
                    account_number: 12345678901
                    bank_name: Example Bank Ghana
                    bank_swift_code: EXGHGHAC
                    country: GH
                    destination_type: swift
                    remittance_purpose: exported_goods
                  invoice_s3_key: >-
                    tmp/019a3b5c-1f0e-7d2c-8a9b-4c5d6e7f8a90/invoice_sbx_0042.pdf
              usd_wire:
                summary: US domestic wire with your own sender details
                value:
                  beneficiary:
                    account_number: '000123456789'
                    account_type: checking
                    bank_address: 1 Example Plaza
                    bank_name: Example Bank NA
                    beneficiary:
                      account_name: Acme Imports LLC
                      address: 2 Example Street
                      city: New York
                      country: US
                      post_code: '10001'
                      state: New York
                      type: business
                    city: New York
                    country: US
                    destination_type: wire
                    post_code: '10001'
                    remittance_purpose: exported_goods
                    routing_number: '000000001'
                    sender:
                      account_name: Acme Logistics Ltd
                      address: 1 Example Close, Victoria Island
                      city: Lagos
                      country: NG
                      post_code: '101241'
                      registration_number: RC0000001
                      state: Lagos
                      type: business
                    state: new_york
                  callback_url: https://example.com/webhooks/payouts
                  payment_reason: Invoice INV-2026-118
            schema:
              $ref: '#/components/schemas/PayoutsInitializeRequest'
        required: true
      responses:
        '200':
          content:
            application/json:
              examples:
                ngn_bank_initiated:
                  summary: 'Offchain: INITIATED, ready to finalize'
                  value:
                    data:
                      data: null
                      payout:
                        amount: '100'
                        beneficiary:
                          account_name: Adaeze Okafor
                          account_number: '0000000001'
                          bank_code: '000014'
                          country: NG
                          destination_type: bank
                        btc_amount: '0.001471'
                        cent_fees: '500000'
                        company_id: ''
                        country: ''
                        created_at: null
                        exchange_rate:
                          btc_rate: '68000'
                          currency: ''
                          effective_rate: '1497'
                          rate: '1500'
                        expires_at: '2026-10-30T09:31:02Z'
                        fee_currency: USD
                        fees: '0.5'
                        from_asset: USDT
                        id: 019a3b5c-8e21-7a4c-9b3d-2f6e8a1c4d70
                        payment_reason: Supplier invoice 0042
                        quote_id: QT2_100482
                        reference: payout_ref_20261030_0007
                        sat_amount: '147059'
                        settlement_amount: '149700'
                        source: SOURCE_UNSET
                        source_fee: '0.5'
                        status: INITIATED
                        to_currency: NGN
                        total_amount: '100.5'
                        updated_at: null
                    message: Payout initialized successfully
                    success: true
                    timestamp: '2026-10-30T09:15:02.481Z'
                onchain_awaiting_deposit:
                  summary: >-
                    Onchain: send deposit_amount of USDT to address on Tron,
                    then finalize
                  value:
                    data:
                      data: null
                      payout:
                        address: TExampleSandboxDeposit000000000002
                        amount: '98.881974'
                        beneficiary:
                          account_name: Kwame Mensah
                          account_number: '0240000001'
                          country: GH
                          destination_type: mobile_money
                          network: mtn
                        btc_amount: '0.001454'
                        cent_fees: '0'
                        chain: CHAIN_TYPE_TRON
                        company_id: ''
                        country: ''
                        created_at: null
                        deposit_amount: '98.881974'
                        exchange_rate:
                          btc_rate: '68000'
                          currency: ''
                          effective_rate: '15.1696000729111658'
                          rate: '15.2'
                        expires_at: '2026-10-30T09:31:02Z'
                        fee_currency: USD
                        fees: '0'
                        from_asset: USDT
                        id: 019a3b5d-0c3f-7e51-8f2a-6b7c8d9e0f12
                        quote_id: QT2_100483
                        reference: payout_ref_20261030_0008
                        sat_amount: '145415'
                        settlement_amount: '1500'
                        source: SOURCE_UNSET
                        source_fee: '0'
                        status: PENDING_ADDRESS_DEPOSIT
                        to_currency: GHS
                        total_amount: '98.881974'
                        updated_at: null
                    message: Payout initialized successfully
                    success: true
                    timestamp: '2026-10-30T09:15:02.481Z'
                usd_wire_priced:
                  summary: 'USD wire: the rail''s fee appears here for the first time'
                  value:
                    data:
                      data: null
                      payout:
                        amount: '2500'
                        beneficiary:
                          account_number: 123456789
                          account_type: checking
                          bank_address: 1 Example Plaza
                          bank_name: Example Bank NA
                          beneficiary:
                            account_name: Acme Imports LLC
                            address: 2 Example Street
                            city: New York
                            country: US
                            post_code: '10001'
                            state: New York
                            type: business
                          city: New York
                          country: US
                          destination_type: wire
                          post_code: '10001'
                          remittance_purpose: exported_goods
                          routing_number: '000000001'
                          sender:
                            account_name: Acme Logistics Ltd
                            address: 1 Example Close, Victoria Island
                            city: Lagos
                            country: NG
                            post_code: '101241'
                            registration_number: RC0000001
                            state: Lagos
                            type: business
                          state: new_york
                        btc_amount: '0.036765'
                        cent_fees: '15000000'
                        company_id: ''
                        country: ''
                        created_at: null
                        exchange_rate:
                          btc_rate: '68000'
                          currency: ''
                          effective_rate: '1'
                          rate: '1'
                        expires_at: '2026-10-30T09:31:02Z'
                        fee_currency: USD
                        fees: '15'
                        from_asset: USDC
                        id: 019a3b5d-1d40-7f62-a03b-7c8d9e0f1a23
                        payment_reason: Invoice INV-2026-118
                        quote_id: QT2_100484
                        reference: payout_ref_20261030_0009
                        sat_amount: '3676471'
                        settlement_amount: '2500'
                        source: SOURCE_UNSET
                        source_fee: '15'
                        status: INITIATED
                        to_currency: USD
                        total_amount: '2515'
                        updated_at: null
                    message: Payout initialized successfully
                    success: true
                    timestamp: '2026-10-30T09:15:02.481Z'
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - properties:
                      data:
                        $ref: '#/components/schemas/PayoutsInitializeResult'
                    type: object
          description: OK
        '400':
          content:
            application/json:
              examples:
                already_initialized:
                  summary: >-
                    The quote is past QUOTE status, or another initialize holds
                    it
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: Quote 'QT2_100482' has already been initialized
                    extensions:
                      quote_id: QT2_100482
                      reason: already_initialized
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                already_submitted:
                  summary: Our partner already has a payout for this quote
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      This payout has already been submitted. Please check your
                      transaction history or create a new quote.
                    extensions:
                      quote_id: QT2_100482
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                bank_details_unverified:
                  summary: Our partner could not verify the bank account
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      Invalid beneficiary bank_code: Unable to verify bank
                      details. Please check the bank and account information.
                    extensions:
                      field: bank_code
                      reason: >-
                        Unable to verify bank details. Please check the bank and
                        account information.
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                beneficiary_country_missing:
                  summary: beneficiary.country is missing
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      Invalid beneficiary country: beneficiary country is
                      required
                    extensions:
                      field: country
                      reason: beneficiary country is required
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                beneficiary_schema:
                  summary: A field fails the country's beneficiary schema
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      Invalid beneficiary destination: validation failed for NG
                      bank: account_number: Account Number does not match
                      required format
                    extensions:
                      field: destination
                      reason: >-
                        validation failed for NG bank: account_number: Account
                        Number does not match required format
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                destination_not_in_corridor:
                  summary: The destination type is not offered in this currency
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      Invalid beneficiary destination: bank is not available for
                      USD payouts to GH
                    extensions:
                      field: destination
                      reason: bank is not available for USD payouts to GH
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                destination_type_required:
                  summary: A USD beneficiary without destination_type
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      USD payouts need a destination type (ach, wire, or swift)
                      on the beneficiary so the correct fee applies. Add
                      destination_type and try again.
                    extensions:
                      quote_id: QT2_100484
                      reason: payout_destination_type_required
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                duplicate_submission_lock:
                  summary: Our partner's short dedup window; retry after 120 seconds
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      This payout is temporarily locked by a
                      duplicate-submission check. Please wait about two minutes
                      and try again.
                    extensions:
                      quote_id: QT2_100482
                      retry_after_seconds: 120
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                invoice_key_invalid:
                  summary: invoice_s3_key is not under tmp/{your company id}/
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      The document key is not valid for this account. Upload the
                      document again.
                    extensions:
                      error_code: DOCUMENT_INVALID_KEY
                      field: invoice_s3_key
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                malformed_body:
                  summary: The body is not valid JSON
                  value:
                    error:
                      code: BAD_REQUEST
                      message: Invalid request body
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    success: false
                    timestamp: '2026-10-30T09:15:02.481Z'
                quote_expired:
                  summary: >-
                    The quote expired (6 minutes for BTC, 16 for stablecoins and
                    NGN); create a new one
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: Quote 'QT2_100482' has expired
                    extensions:
                      quote_id: QT2_100482
                      reason: expired
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                unknown_customer:
                  summary: customer_id is a UUID but no such customer exists
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      Customer '019a3b61-8eb7-76d9-a1a2-4d5e6f7a8b9a' was not
                      found. Create the customer before initiating a payout.
                    extensions:
                      customer_id: 019a3b61-8eb7-76d9-a1a2-4d5e6f7a8b9a
                      reason: unknown_customer
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Validation Error
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - $ref: '#/components/schemas/Problem'
          description: >-
            The body does not parse (BAD_REQUEST envelope), or the service
            refuses it (VALIDATION_ERROR): the quote expired or is no longer in
            QUOTE status, the beneficiary fails the country schema, a USD payout
            without destination_type, an unknown customer, an invoice key that
            is not yours, or our partner's duplicate-submission lock (retry
            after retry_after_seconds).
          headers:
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          content:
            application/json:
              examples:
                client_inactive:
                  $ref: '#/components/examples/ClientInactive'
                customer_payouts_off:
                  summary: customer_id was sent but customer payouts are off
                  value:
                    code: FEATURE_NOT_ENABLED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      The payouts for customers feature is currently not
                      available.
                    extensions:
                      company_id: 019a3b5c-1f0e-7d2c-8a9b-4c5d6e7f8a90
                      feature_key: customer_payouts
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 403
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Feature Not Enabled
                    type: https://api.bitnob.com/errors/FEATURE_NOT_ENABLED
                feature_not_enabled:
                  summary: >-
                    send_fiat is off for this organisation, or money movement is
                    halted
                  value:
                    code: FEATURE_NOT_ENABLED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: The fiat payouts feature is currently not available.
                    extensions:
                      company_id: 019a3b5c-1f0e-7d2c-8a9b-4c5d6e7f8a90
                      feature_key: send_fiat
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 403
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Feature Not Enabled
                    type: https://api.bitnob.com/errors/FEATURE_NOT_ENABLED
                ip_not_whitelisted:
                  $ref: '#/components/examples/IPNotWhitelisted'
                kyb_required:
                  summary: SWIFT needs a verified business sender
                  value:
                    code: FORBIDDEN
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: Complete business verification to send SWIFT payouts.
                    extensions:
                      error_code: KYB_REQUIRED
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 403
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Verification Required
                    type: https://api.bitnob.com/errors/FORBIDDEN
                org_not_active:
                  $ref: '#/components/examples/OrgNotActive'
                org_not_active_live:
                  $ref: '#/components/examples/OrgNotActiveLive'
                personal_workspace_customers:
                  $ref: '#/components/examples/PersonalWorkspaceCustomers'
                swift_not_enabled:
                  summary: SWIFT is not enabled for this organisation
                  value:
                    code: FEATURE_NOT_ENABLED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: The SWIFT payouts feature is currently not available.
                    extensions:
                      company_id: 019a3b5c-1f0e-7d2c-8a9b-4c5d6e7f8a90
                      feature_key: swift_payouts_enabled
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 403
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Feature Not Enabled
                    type: https://api.bitnob.com/errors/FEATURE_NOT_ENABLED
                tier_swift_locked:
                  summary: A SWIFT payout on a tier without SWIFT
                  value:
                    code: TIER_PRODUCT_LOCKED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      Your account's tier 1 does not include SWIFT transfers.
                      Upgrade to tier 2 to unlock it.
                    extensions:
                      country: GH
                      product: swift
                      required_tier: '2'
                      tier: '1'
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 403
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Not Available On Your Tier
                    type: https://api.bitnob.com/errors/TIER_PRODUCT_LOCKED
                tier_usd_wire_locked:
                  $ref: '#/components/examples/TierProductLocked'
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - $ref: '#/components/schemas/Problem'
          description: >-
            On a personal account any customer but the owner, and any new
            customer, is refused (PERSONAL_WORKSPACE_CUSTOMERS).
            FEATURE_NOT_ENABLED (send_fiat, swift_payouts_enabled, or customers
            and customer_payouts for a customer payout), TIER_PRODUCT_LOCKED
            (usd_wire, swift or the corridor), FORBIDDEN with error_code
            KYB_REQUIRED for SWIFT without business verification, ORG_NOT_ACTIVE
            for a live key on an inactive organisation, or a refusal before the
            handler.
          headers:
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
        '404':
          content:
            application/json:
              examples:
                quote_not_found:
                  summary: No quote with this quote_id belongs to your organisation
                  value:
                    code: NOT_FOUND
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: quote with ID 'QT2_999999' was not found
                    extensions:
                      id: QT2_999999
                      resource: quote
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 404
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Resource Not Found
                    type: https://api.bitnob.com/errors/NOT_FOUND
              schema:
                $ref: '#/components/schemas/Problem'
          description: No quote with this quote_id belongs to your organisation.
          headers:
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
        '408':
          $ref: '#/components/responses/RequestTimeout'
        '422':
          content:
            application/json:
              examples:
                beneficiary_pending_approval:
                  summary: Retry initialize on the same quote once approval completes
                  value:
                    code: PRECONDITION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      This beneficiary is still being approved by our payout
                      partner and can't receive payouts yet. It'll be available
                      once approval completes.
                    extensions:
                      quote_id: QT2_100484
                      reason: beneficiary_pending_approval
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Beneficiary Pending Approval
                    type: https://api.bitnob.com/errors/PRECONDITION_FAILED
                beneficiary_verification_failed:
                  summary: Our partner rejected the beneficiary
                  value:
                    code: PRECONDITION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      Our payout partner could not verify this beneficiary.
                      Check the account details and create the beneficiary again
                      before retrying the payout.
                    extensions:
                      quote_id: QT2_100484
                      reason: beneficiary_verification_failed
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Beneficiary Verification Failed
                    type: https://api.bitnob.com/errors/PRECONDITION_FAILED
                insufficient_funds:
                  summary: The USDT balance does not cover amount plus fee
                  value:
                    code: INSUFFICIENT_FUNDS
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: Insufficient funds to complete the transaction
                    extensions:
                      account_id: usdt
                      available: '42.18'
                      required: '100.50'
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Insufficient Funds
                    type: https://api.bitnob.com/errors/INSUFFICIENT_FUNDS
                invoice_required:
                  summary: >-
                    A SWIFT payout with a business on either side, without
                    invoice_s3_key
                  value:
                    code: VALIDATION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      An invoice is required for this payout. Attach one and try
                      again.
                    extensions:
                      error_code: INVOICE_REQUIRED
                      field: invoice_s3_key
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Invoice Required
                    type: https://api.bitnob.com/errors/VALIDATION_FAILED
                new_destination_paused:
                  $ref: '#/components/examples/NewDestinationPaused'
                payout_rejected:
                  summary: >-
                    Our partner rejected the payout; fix the details and
                    re-quote
                  value:
                    code: PRECONDITION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      We couldn't process this payout. Please check the
                      beneficiary and account details, then try again with a new
                      quote.
                    extensions:
                      quote_id: QT2_100482
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Payout Rejected
                    type: https://api.bitnob.com/errors/PRECONDITION_FAILED
                sender_details_unavailable:
                  $ref: '#/components/examples/SenderDetailsUnavailable'
                sender_not_verified:
                  $ref: '#/components/examples/SenderNotVerified'
                swift_for_customer:
                  summary: customer_id on a SWIFT payout
                  value:
                    code: VALIDATION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      SWIFT payouts on behalf of a customer are not supported
                      yet.
                    extensions:
                      error_code: CUSTOMER_PATH_NOT_SUPPORTED
                      field: customer_id
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Not Supported
                    type: https://api.bitnob.com/errors/VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/Problem'
          description: >-
            The request is valid but cannot go ahead: the balance does not cover
            amount plus fee (INSUFFICIENT_FUNDS), our partner has the
            beneficiary pending approval or failed its verification, our partner
            rejected the payout, new destinations are paused for the
            organisation (PRECONDITION_FAILED, reason in extensions), or a SWIFT
            document is missing or unusable (VALIDATION_FAILED, error_code in
            extensions). On a personal account the sender is the owner, from
            their verified identity; no verified identity is
            SENDER_NOT_VERIFIED, and a rail needing sender details it lacks is
            SENDER_DETAILS_UNAVAILABLE (VALIDATION_FAILED, error_code in
            extensions).
          headers:
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/ServerError'
        '503':
          content:
            application/json:
              examples:
                auth_service_busy:
                  $ref: '#/components/examples/AuthServiceBusy'
                auth_service_unavailable:
                  $ref: '#/components/examples/AuthServiceUnavailable'
                document_uploads_unavailable:
                  summary: SWIFT document storage is not available
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      Document uploads are temporarily unavailable. Please try
                      again later.
                    extensions:
                      error_code: DOCUMENT_UPLOADS_UNAVAILABLE
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 503
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Document Uploads Unavailable
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
                limits_unavailable:
                  $ref: '#/components/examples/LimitsUnavailable'
                personal_sender_unavailable:
                  $ref: '#/components/examples/PersonalSenderUnavailable'
                partner_unavailable:
                  $ref: '#/components/examples/PartnerUnavailable'
                sender_verification_unavailable:
                  summary: The business verification lookup failed; retry
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      We could not confirm your business verification right now.
                      Please try again shortly.
                    extensions:
                      error_code: SENDER_IDENTITY_UNAVAILABLE
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 503
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Sender Verification Unavailable
                    type: https://api.bitnob.com/errors/VALIDATION_ERROR
              schema:
                $ref: '#/components/schemas/Problem'
          description: >-
            SERVICE_UNAVAILABLE: the settlement partner failed while creating
            the beneficiary or staging the payout, or a deposit address could
            not be generated; LIMITS_UNAVAILABLE: the tier product check could
            not run; document storage or the sender verification lookup is
            unavailable (SWIFT, error_code in extensions). Retry later; the
            quote stays usable until it expires. On a personal account, the
            identity lookup for the sender failed (SENDER_IDENTITY_UNAVAILABLE).
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
components:
  schemas:
    PayoutsInitializeRequest:
      properties:
        beneficiary:
          additionalProperties: true
          description: >-
            Beneficiary details. The fields depend on the country and
            destination type; see GET
            /api/payouts/supported-countries/{country}. USD payouts need
            destination_type (ach, wire or swift). A sender object may be
            supplied. On a personal (individual) account it is ignored on every
            rail; the sender is the owner's verified identity, and a rail whose
            sender needs details that identity does not hold is refused (422,
            error_code SENDER_DETAILS_UNAVAILABLE).
          type: object
        callback_url:
          format: uri
          type: string
          description: HTTPS URL that receives updates for this payout.
        customer_id:
          description: >-
            Make the payout on behalf of this customer. Needs the customers and
            customer_payouts features. A value that is not a UUID is ignored and
            the payout is made without a customer; a UUID with no customer is
            refused (400 unknown_customer).
          format: uuid
          type: string
        invoice_s3_key:
          description: >-
            Key of an uploaded invoice (SWIFT); must start with tmp/{your
            company id}/
          maxLength: 512
          type: string
        metadata:
          description: A JSON object encoded as a string; ignored if it does not parse
          type: string
        payment_reason:
          maxLength: 255
          type: string
          description: Reason for the payment.
        reference:
          maxLength: 255
          type: string
          description: Your unique reference for this payout.
      required:
        - beneficiary
      type: object
    Envelope:
      description: >-
        Successful responses are wrapped in this envelope, and so are errors a
        handler answers itself (request body and field validation, some
        not-found and conflict cases, ORG_NOT_ACTIVE): success is false and
        error carries a code and message. Errors raised by authentication and by
        the services behind a handler are a Problem instead.
      properties:
        data:
          description: >-
            The payload; its shape is given per operation. Omitted when there is
            none.
        error:
          $ref: '#/components/schemas/ErrorInfo'
        message:
          description: Human-readable summary; omitted when empty.
          type: string
        metadata:
          $ref: '#/components/schemas/Pagination'
        request_id:
          description: >-
            Set on error envelopes: the request's correlation id (req_ followed
            by a UUID), the same value as the X-Correlation-ID response header.
            Quote it to support.
          type: string
        success:
          description: true on success
          type: boolean
        timestamp:
          description: When the response was written.
          format: date-time
          type: string
      required:
        - success
        - timestamp
      type: object
    PayoutsInitializeResult:
      properties:
        data:
          description: Always null; kept for compatibility
          type: 'null'
        payout:
          $ref: '#/components/schemas/PayoutsPayout'
      required:
        - payout
        - data
      type: object
    ErrorEnvelope:
      allOf:
        - $ref: '#/components/schemas/Envelope'
        - properties:
            success:
              const: false
          required:
            - error
          type: object
      description: >-
        The envelope as an error: success is false, error is set, data is
        absent.
    Problem:
      description: >-
        RFC 7807 problem. Returned when authentication fails and for errors
        raised by the services behind a handler (validation, domain refusals
        such as FEATURE_NOT_ENABLED or PRECONDITION_FAILED, partner outages);
        branch on code.
      properties:
        code:
          description: >-
            Machine-readable; branch on this, not on the status or the wording.
            For example VALIDATION_ERROR, UNAUTHORIZED, FORBIDDEN,
            FEATURE_NOT_ENABLED, PERSONAL_WORKSPACE_CUSTOMERS,
            TIER_PRODUCT_LOCKED, NOT_FOUND, DUPLICATE_KEY_ERROR, ALREADY_EXISTS,
            PRECONDITION_FAILED, INSUFFICIENT_FUNDS, TIER_LIMIT_REACHED,
            RATE_LIMIT_EXCEEDED, TIMEOUT, SERVICE_UNAVAILABLE,
            LIMITS_UNAVAILABLE, PLATFORM_PAUSED, INTERNAL_ERROR.
          type: string
        correlation_id:
          description: >-
            The request's correlation id, the same value as the X-Correlation-ID
            response header.
          type: string
        detail:
          description: >-
            What went wrong for this request, safe to show; internal and partner
            failures carry a generic sentence.
          type: string
        extensions:
          additionalProperties: true
          description: >-
            Code-specific facts, for example feature_key (FEATURE_NOT_ENABLED),
            field or field_violations (VALIDATION_ERROR), rail, window, limit,
            used, requested and remaining (TIER_LIMIT_REACHED), scope
            (PLATFORM_PAUSED).
          type: object
        instance:
          type: string
        request_id:
          description: Equal to correlation_id.
          type: string
        status:
          description: The HTTP status, repeated.
          type: integer
        timestamp:
          format: date-time
          type: string
        title:
          description: >-
            Short summary of the code, for example Validation Error or Feature
            Not Enabled.
          type: string
        type:
          description: https://api.bitnob.com/errors/{code}
          format: uri
          type: string
      required:
        - type
        - title
        - status
        - code
        - timestamp
      type: object
    ErrorInfo:
      properties:
        code:
          description: >-
            Machine-readable, for example BAD_REQUEST, NOT_FOUND, CONFLICT,
            ORG_NOT_ACTIVE, RATE_LIMIT_EXCEEDED, SERVICE_UNAVAILABLE,
            INTERNAL_ERROR.
          type: string
        details:
          additionalProperties: true
          description: >-
            For field validation, a map of field name to message ("email":
            "Email must be a valid email address"); for a body that does not
            decode, the offending field.
          type: object
        message:
          type: string
      required:
        - message
      type: object
    Pagination:
      description: >-
        List metadata. Page lists set page, per_page, total and total_pages;
        offset and cursor lists set limit, offset, has_more and next_cursor.
        Zero and empty fields are omitted, and metadata is absent when nothing
        is set.
      properties:
        has_more:
          type: boolean
        limit:
          type: integer
        next_cursor:
          description: Opaque; pass as cursor for the next page.
          type: string
        offset:
          type: integer
        page:
          type: integer
        per_page:
          type: integer
        total:
          type: integer
        total_pages:
          type: integer
      type: object
    PayoutsPayout:
      description: >-
        A payout or quote. 64-bit integers are sent as strings. Optional fields
        are absent when unset.
      properties:
        address:
          description: Deposit address (or Lightning invoice) for onchain payouts
          type: string
        amount:
          description: >-
            Source amount in major units of from_asset (decimal string),
            excluding fees
          type: string
        beneficiary:
          additionalProperties: true
          description: Beneficiary details as stored
          type: object
        beneficiary_id:
          format: uuid
          type: string
        btc_amount:
          description: Decimal BTC
          type: string
        callback_url:
          type: string
        cent_amount:
          description: Source amount in base units, as a string
          type: string
        cent_fees:
          description: Fee in base units of the source asset, as a string
          type: string
        chain:
          description: CHAIN_TYPE_ followed by the upper-case chain, e.g. CHAIN_TYPE_TRON
          type: string
        company_id:
          anyOf:
            - format: uuid
              type: string
            - const: ''
          description: Empty on the initialize response.
        country:
          description: >-
            ISO 3166-1 alpha-2 destination country; empty on the initialize
            response.
          type: string
        created_at:
          description: Null on the initialize response.
          format: date-time
          type:
            - string
            - 'null'
        customer_id:
          format: uuid
          type: string
        deposit_amount:
          description: Amount to deposit for an onchain payout (initialize response only)
          type: string
        exchange_rate:
          $ref: '#/components/schemas/PayoutsExchangeRate'
        expires_at:
          format: date-time
          type: string
        fee_currency:
          description: Denomination of fees
          type: string
        fees:
          description: Fee as a decimal string, in fee_currency
          type: string
        from_asset:
          enum:
            - BTC
            - USDT
            - USDC
            - NGN
            - UNSPECIFIED_ASSET
          type: string
        id:
          format: uuid
          type: string
        invoice_s3_key:
          type: string
        payment_reason:
          type: string
        quote_id:
          description: Quote identifier used by initialize and finalize
          type: string
        reference:
          type: string
        sat_amount:
          description: Satoshis, as a string. For BTC this is principal plus fee
          type: string
        settlement_amount:
          description: Amount the beneficiary receives, in major units of to_currency
          type: string
        source:
          description: >-
            SOURCE_UNSET only on the initialize response, which does not carry
            the source
          enum:
            - OFFCHAIN
            - ONCHAIN
            - SOURCE_UNSET
          type: string
        source_fee:
          description: Fee in major units of from_asset
          type: string
        status:
          enum:
            - QUOTE
            - INITIATED
            - PENDING
            - PENDING_ADDRESS_DEPOSIT
            - PROCESSING
            - SUCCESS
            - FAILED
            - EXPIRED
            - UNDERPAYMENT
          type: string
        to_currency:
          description: Upper-case settlement currency, e.g. NGN
          type: string
        total_amount:
          description: amount plus source_fee, in major units of from_asset
          type: string
        trip:
          $ref: '#/components/schemas/PayoutsTrip'
        updated_at:
          description: Null on the initialize response.
          format: date-time
          type:
            - string
            - 'null'
      required:
        - id
        - quote_id
        - status
        - source
        - from_asset
        - to_currency
        - amount
        - settlement_amount
        - cent_fees
        - fees
        - fee_currency
        - source_fee
        - total_amount
        - company_id
        - country
        - created_at
        - updated_at
      type: object
    PayoutsExchangeRate:
      description: Rate snapshot on a payout. Values are decimal strings.
      properties:
        btc_rate:
          description: BTC to USD rate used for BTC payouts
          type: string
        currency:
          description: >-
            Settlement currency in lower case (for example "ngn"); empty on the
            initialize response.
          type: string
        effective_rate:
          description: settlement_amount divided by amount
          type: string
        rate:
          description: USD to to_currency rate
          type: string
      type: object
    PayoutsTrip:
      description: >-
        Milestones of the payout. Each is an RFC 3339 UTC timestamp, absent
        until reached.
      properties:
        asset_received:
          format: date-time
          type: string
        completion_time:
          format: date-time
          type: string
        initialized_at:
          format: date-time
          type: string
        processing_start:
          format: date-time
          type: string
        quote_at:
          format: date-time
          type: string
        submitted:
          format: date-time
          type: string
      type: object
  headers:
    X-Correlation-ID:
      description: >-
        Generated for every request (any value the client sends is ignored);
        quote it to support. Errors repeat it as request_id and correlation_id.
      example: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
      schema:
        type: string
    Retry-After:
      description: Seconds to wait before retrying.
      example: 1
      schema:
        minimum: 0
        type: integer
    X-RateLimit-Limit:
      description: Requests allowed per window by the per-IP limiter (500 a minute).
      example: 500
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests left in the current window.
      example: 0
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Seconds until the window resets.
      example: 37
      schema:
        type: integer
  responses:
    Unauthorized:
      content:
        application/json:
          examples:
            unauthorized_auth_failed:
              $ref: '#/components/examples/UnauthorizedAuthFailed'
            unauthorized_invalid_secret:
              $ref: '#/components/examples/UnauthorizedInvalidSecret'
            unauthorized_invalid_signature:
              $ref: '#/components/examples/UnauthorizedInvalidSignature'
            unauthorized_locked_out:
              $ref: '#/components/examples/UnauthorizedLockedOut'
          schema:
            $ref: '#/components/schemas/Problem'
      description: >-
        Authentication failed: a signing header is missing or malformed, the
        timestamp is more than 5 minutes off, the signature or secret is wrong,
        or the client is locked out after failed checks (UNAUTHORIZED).
      headers:
        X-Correlation-ID:
          $ref: '#/components/headers/X-Correlation-ID'
    RequestTimeout:
      content:
        application/json:
          examples:
            request_timeout:
              $ref: '#/components/examples/RequestTimeout'
          schema:
            $ref: '#/components/schemas/Problem'
      description: >-
        The request ran past its deadline (TIMEOUT); retry, with the same
        reference for writes.
      headers:
        X-Correlation-ID:
          $ref: '#/components/headers/X-Correlation-ID'
    TooManyRequests:
      content:
        application/json:
          examples:
            rate_limited:
              $ref: '#/components/examples/RateLimited'
            rate_limited_envelope:
              $ref: '#/components/examples/RateLimitedEnvelope'
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorEnvelope'
              - $ref: '#/components/schemas/Problem'
      description: >-
        Rate limited. The per-IP limiter (500 requests a minute) answers with a
        Problem and Retry-After; operation-specific throttles answer with the
        envelope.
      headers:
        Retry-After:
          $ref: '#/components/headers/Retry-After'
        X-Correlation-ID:
          $ref: '#/components/headers/X-Correlation-ID'
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
    ServerError:
      content:
        application/json:
          examples:
            internal_error:
              $ref: '#/components/examples/InternalError'
            internal_error_envelope:
              $ref: '#/components/examples/InternalErrorEnvelope'
            internal_error_unhandled:
              $ref: '#/components/examples/InternalErrorUnhandled'
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorEnvelope'
              - $ref: '#/components/schemas/Problem'
      description: >-
        Something failed on our side; safe to retry idempotent requests
        (INTERNAL_ERROR).
      headers:
        X-Correlation-ID:
          $ref: '#/components/headers/X-Correlation-ID'
  examples:
    ClientInactive:
      summary: The API key's client is deactivated
      value:
        code: FORBIDDEN
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Client account is inactive
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 403
        timestamp: '2026-10-30T09:15:02Z'
        title: Forbidden
        type: https://api.bitnob.com/errors/FORBIDDEN
    IPNotWhitelisted:
      summary: The request came from an IP not on the key's allowlist
      value:
        code: FORBIDDEN
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: IP address not whitelisted
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 403
        timestamp: '2026-10-30T09:15:02Z'
        title: Forbidden
        type: https://api.bitnob.com/errors/FORBIDDEN
    OrgNotActive:
      description: Live keys only; sandbox requests pass.
      summary: A money-moving operation from an organisation that is not active
      value:
        error:
          code: ORG_NOT_ACTIVE
          message: >-
            Your organisation is not currently active. Please contact your
            administrator.
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        success: false
        timestamp: '2026-10-30T09:15:02.481Z'
    OrgNotActiveLive:
      description: Sandbox keys are never refused this way.
      summary: A live key on an organisation that is not active yet
      value:
        error:
          code: ORG_NOT_ACTIVE
          message: >-
            Your business isn't active yet, so live isn't available. Use your
            sandbox keys until it's activated.
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        success: false
        timestamp: '2026-10-30T09:15:02.481Z'
    PersonalWorkspaceCustomers:
      description: >-
        A personal (individual) account has no customers but its owner. Creating
        a customer, or naming any customer other than the owner's own record, is
        refused whatever the organisation's enabled features say.
      summary: A personal account acting for someone other than its owner
      value:
        code: PERSONAL_WORKSPACE_CUSTOMERS
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: A personal account can only act for its owner.
        extensions:
          company_id: 019a3b5c-1a2b-7c3d-8e4f-5a6b7c8d9e01
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 403
        timestamp: '2026-10-30T09:15:02Z'
        title: Not Available On A Personal Account
        type: https://api.bitnob.com/errors/PERSONAL_WORKSPACE_CUSTOMERS
    TierProductLocked:
      summary: The organisation's tier does not include the product
      value:
        code: TIER_PRODUCT_LOCKED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: >-
          Your account's tier 1 does not include USD wire transfers. Upgrade to
          tier 2 to unlock it.
        extensions:
          product: usd_wire
          required_tier: '2'
          tier: '1'
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 403
        timestamp: '2026-10-30T09:15:02Z'
        title: Not Available On Your Tier
        type: https://api.bitnob.com/errors/TIER_PRODUCT_LOCKED
    NewDestinationPaused:
      summary: New payout destinations are paused on this account
      value:
        code: PRECONDITION_FAILED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: >-
          Payouts to new destinations are temporarily paused on this account.
          Destinations you have paid before still work. Contact support to lift
          this.
        extensions:
          reason: destination_quarantined
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 422
        timestamp: '2026-10-30T09:15:02Z'
        title: New Destination Paused
        type: https://api.bitnob.com/errors/PRECONDITION_FAILED
    SenderDetailsUnavailable:
      description: >-
        missing_fields lists them, comma separated. Nothing is filled in on the
        owner's behalf; use another rail.
      summary: >-
        The rail needs sender details a personal account's verified identity
        does not hold
      value:
        code: VALIDATION_FAILED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: >-
          This payout method needs sender details your verified identity does
          not include: city, address, post_code, country_of_birth.
        extensions:
          error_code: SENDER_DETAILS_UNAVAILABLE
          missing_fields: city,address,post_code,country_of_birth
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 422
        timestamp: '2026-10-30T09:15:02Z'
        title: Sender Details Unavailable
        type: https://api.bitnob.com/errors/VALIDATION_FAILED
    SenderNotVerified:
      summary: A personal account whose owner has no verified identity to send as
      value:
        code: VALIDATION_FAILED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Complete your identity verification to send payouts.
        extensions:
          error_code: SENDER_NOT_VERIFIED
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 422
        timestamp: '2026-10-30T09:15:02Z'
        title: Sender Not Verified
        type: https://api.bitnob.com/errors/VALIDATION_FAILED
    AuthServiceBusy:
      description: 'Sent with Retry-After: 1.'
      summary: Too many large signed bodies are being checked at once
      value:
        code: SERVICE_UNAVAILABLE
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Authentication service is busy, retry shortly
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 503
        timestamp: '2026-10-30T09:15:02Z'
        title: Service Unavailable
        type: https://api.bitnob.com/errors/SERVICE_UNAVAILABLE
    AuthServiceUnavailable:
      description: 'Sent with Retry-After: 1. The detail is worded exactly like this today.'
      summary: The identity service could not be reached to check the credentials
      value:
        code: SERVICE_UNAVAILABLE
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Service Authentication service unavailable is currently unavailable
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 503
        timestamp: '2026-10-30T09:15:02Z'
        title: Service Unavailable
        type: https://api.bitnob.com/errors/SERVICE_UNAVAILABLE
    LimitsUnavailable:
      summary: The tier limit check could not run
      value:
        code: LIMITS_UNAVAILABLE
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: >-
          We could not verify your account limits right now. Please try again
          shortly.
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 503
        timestamp: '2026-10-30T09:15:02Z'
        title: Limits Unavailable
        type: https://api.bitnob.com/errors/LIMITS_UNAVAILABLE
    PersonalSenderUnavailable:
      summary: The identity lookup for a personal account's sender failed; retry
      value:
        code: VALIDATION_ERROR
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: >-
          We could not confirm your identity verification right now. Please try
          again shortly.
        extensions:
          error_code: SENDER_IDENTITY_UNAVAILABLE
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 503
        timestamp: '2026-10-30T09:15:02Z'
        title: Sender Verification Unavailable
        type: https://api.bitnob.com/errors/VALIDATION_ERROR
    PartnerUnavailable:
      summary: A partner or internal service is unavailable
      value:
        code: SERVICE_UNAVAILABLE
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Service is temporarily unavailable. Please try again later.
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 503
        timestamp: '2026-10-30T09:15:02Z'
        title: Service Unavailable
        type: https://api.bitnob.com/errors/SERVICE_UNAVAILABLE
    UnauthorizedAuthFailed:
      description: >-
        Returned when X-Auth-Client, X-Auth-Timestamp, X-Auth-Nonce or
        X-Auth-Signature is missing, the nonce is not 8 to 128 characters, the
        signature is not hex, or the timestamp is more than 5 minutes from the
        server's clock. The detail does not say which; check each.
      summary: A signing header is missing or malformed, or the timestamp is stale
      value:
        code: UNAUTHORIZED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Authentication failed
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 401
        timestamp: '2026-10-30T09:15:02Z'
        title: Unauthorized
        type: https://api.bitnob.com/errors/UNAUTHORIZED
    UnauthorizedInvalidSecret:
      summary: 'Secret mode: the client id or secret is wrong'
      value:
        code: UNAUTHORIZED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Invalid credentials
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 401
        timestamp: '2026-10-30T09:15:02Z'
        title: Unauthorized
        type: https://api.bitnob.com/errors/UNAUTHORIZED
    UnauthorizedInvalidSignature:
      description: >-
        The detail is the identity service's reason when it gives one (an
        unknown client or a reused nonce reads differently); Invalid signature
        otherwise.
      summary: The signature does not match
      value:
        code: UNAUTHORIZED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Invalid signature
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 401
        timestamp: '2026-10-30T09:15:02Z'
        title: Unauthorized
        type: https://api.bitnob.com/errors/UNAUTHORIZED
    UnauthorizedLockedOut:
      summary: Too many failed credential checks
      value:
        code: UNAUTHORIZED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Too many failed credential checks; retry later
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 401
        timestamp: '2026-10-30T09:15:02Z'
        title: Unauthorized
        type: https://api.bitnob.com/errors/UNAUTHORIZED
    RequestTimeout:
      summary: The request ran past its deadline
      value:
        code: TIMEOUT
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: The request took too long to complete. Please try again.
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 408
        timestamp: '2026-10-30T09:15:02Z'
        title: Request Timeout
        type: https://api.bitnob.com/errors/TIMEOUT
    RateLimited:
      summary: The per-IP limit (500 requests a minute) is reached
      value:
        code: RATE_LIMIT_EXCEEDED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Too many requests. Please try again later.
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 429
        timestamp: '2026-10-30T09:15:02Z'
        title: Rate Limit Exceeded
        type: https://api.bitnob.com/errors/RATE_LIMIT_EXCEEDED
    RateLimitedEnvelope:
      summary: An operation-specific throttle (answered by the handler)
      value:
        error:
          code: RATE_LIMIT_EXCEEDED
          message: >-
            a verification link was sent to this customer in the last minute;
            try again shortly
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        success: false
        timestamp: '2026-10-30T09:15:02.481Z'
    InternalError:
      summary: Something failed on our side
      value:
        code: INTERNAL_ERROR
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: An internal error occurred. Please try again later.
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 500
        timestamp: '2026-10-30T09:15:02Z'
        title: Internal Server Error
        type: https://api.bitnob.com/errors/INTERNAL_ERROR
    InternalErrorEnvelope:
      summary: A failure answered by the handler
      value:
        error:
          code: INTERNAL_ERROR
          message: Failed to list transactions
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        success: false
        timestamp: '2026-10-30T09:15:02.481Z'
    InternalErrorUnhandled:
      summary: An unexpected failure
      value:
        code: INTERNAL_ERROR
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: An internal server error occurred
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 500
        timestamp: '2026-10-30T09:15:02Z'
        title: Internal Server Error
        type: https://api.bitnob.com/errors/INTERNAL_ERROR
  securitySchemes:
    BitnobClientId:
      type: apiKey
      in: header
      name: X-Auth-Client
      description: |
        Your workspace client id.

        All calls must include four headers:
        - `X-Auth-Client`   — your workspace client id
        - `X-Auth-Timestamp` — Unix seconds
        - `X-Auth-Nonce`    — 16-byte random hex
        - `X-Auth-Signature` — hex(HMAC-SHA256(
          `{client_id}:{timestamp}:{nonce}:{raw_body}`,
          client_secret))

        The playground computes the timestamp, nonce and signature for you.
    BitnobClientSecret:
      type: apiKey
      in: header
      name: X-Playground-Client-Secret
      description: >
        Your sandbox client secret. The playground uses it to sign the request
        in your browser and removes it before the request is sent. Never send
        your client secret as a header in your own integration.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.