> ## 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.

# Submit a trade order

> Submits a market order. side and quantity refer to the pair's base currency. Pass a quote_id from POST /api/trading/quotes to trade at the locked price.



## OpenAPI

````yaml /api-collections/swagger/bitnob-api-v2.openapi.json post /api/trading/orders
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/trading/orders:
    post:
      tags:
        - Trading
      summary: Submit a trade order
      description: >-
        Submits a market order. side and quantity refer to the pair's base
        currency. Pass a quote_id from POST /api/trading/quotes to trade at the
        locked price.
      operationId: tradingSubmitOrder
      requestBody:
        content:
          application/json:
            examples:
              crypto_buy_base_units:
                summary: >-
                  Buy 1000000 satoshis (0.01 BTC), quantity in the base
                  currency's smallest unit
                value:
                  base_currency: BTC
                  quantity: '1000000'
                  quantity_in_base_units: true
                  quote_currency: USDT
                  reference: trade_sbx_20261030_0003
                  side: BUY
              crypto_buy_with_quote:
                summary: Buy 0.01 BTC with USDT against a locked quote
                value:
                  base_currency: BTC
                  quantity: '0.01'
                  quote_currency: USDT
                  quote_id: 019a3b5d-02a4-7e61-b8c9-d0e1f2a3b4c5
                  reference: trade_sbx_20261030_0001
                  side: BUY
              crypto_sell_market:
                summary: Sell 0.005 BTC for USDT at the market, no quote
                value:
                  base_currency: BTC
                  quantity: '0.005'
                  quote_currency: USDT
                  side: SELL
              ngn_buy_with_quote:
                summary: Buy 100 USDT with naira against a locked NGN quote
                value:
                  base_currency: USDT
                  quantity: '100'
                  quote_currency: NGN
                  quote_id: 019a3b5c-81f0-7b2e-9c3d-4e5f60718293
                  reference: trade_sbx_20261030_0004
                  side: BUY
              ngn_sell_without_quote:
                summary: >-
                  Sell 50 USDT for naira in one call (quoted and filled at once;
                  reference required)
                value:
                  base_currency: USDT
                  quantity: '50'
                  quote_currency: NGN
                  reference: trade_sbx_20261030_0005
                  side: SELL
            schema:
              $ref: '#/components/schemas/TradingSubmitOrderRequest'
        required: true
      responses:
        '201':
          content:
            application/json:
              examples:
                crypto_filled_with_quote:
                  summary: A crypto order filled against a quote
                  value:
                    data:
                      fills:
                        - counterparty_order_id: 019a3b4f-9988-7766-a554-433221100ffe
                          created_at: '2026-10-30T09:15:02.398114207Z'
                          id: 019a3b5d-1a2c-7f00-8a11-223344556677
                          order_id: 019a3b5d-1a2b-7c3d-9e4f-5a6b7c8d9e0f
                          quantity: '0.01'
                      order:
                        base_currency: BTC
                        created_at: '2026-10-30T09:15:02.307403836Z'
                        filled_quantity: '0.01'
                        id: 019a3b5d-1a2b-7c3d-9e4f-5a6b7c8d9e0f
                        order_type: market
                        price: '68301.25'
                        quantity: '0.01'
                        quote_currency: USDT
                        quote_id: 019a3b5d-02a4-7e61-b8c9-d0e1f2a3b4c5
                        reference: trade_sbx_20261030_0001
                        remaining_quantity: '0'
                        side: BUY
                        status: filled
                        updated_at: '2026-10-30T09:15:02.412870114Z'
                      quote_consumption:
                        consumed_quantity: '0.01'
                        is_exhausted: true
                        quote_id: 019a3b5d-02a4-7e61-b8c9-d0e1f2a3b4c5
                        remaining_quantity: '0'
                    message: Order submitted successfully
                    success: true
                    timestamp: '2026-10-30T09:15:02.481Z'
                crypto_market_without_quote:
                  summary: >-
                    A crypto market order without a quote; quote_consumption is
                    null
                  value:
                    data:
                      fills:
                        - counterparty_order_id: 019a3b40-1122-7334-8556-778899aabbcc
                          created_at: '2026-10-30T08:47:19.176320915Z'
                          id: 019a3b41-77c1-7a00-9b22-334455667788
                          order_id: 019a3b41-77c0-7d12-8e3f-4a5b6c7d8e9f
                          quantity: '0.005'
                      order:
                        base_currency: BTC
                        created_at: '2026-10-30T08:47:19.104552301Z'
                        filled_quantity: '0.005'
                        id: 019a3b41-77c0-7d12-8e3f-4a5b6c7d8e9f
                        order_type: market
                        price: '68240.10'
                        quantity: '0.005'
                        quote_currency: USDT
                        quote_id: ''
                        reference: ''
                        remaining_quantity: '0'
                        side: SELL
                        status: filled
                        updated_at: '2026-10-30T08:47:19.188010447Z'
                      quote_consumption: null
                    message: Order submitted successfully
                    success: true
                    timestamp: '2026-10-30T08:47:19.224Z'
                ngn_conversion:
                  summary: >-
                    An NGN order, settled as a conversion; no fills and no
                    quote_consumption
                  value:
                    data:
                      fills: []
                      order:
                        base_currency: USDT
                        created_at: '2026-10-30T09:14:41Z'
                        filled_quantity: '100'
                        id: 019a3b5c-8e21-7c44-a1b2-c3d4e5f60718
                        order_type: market
                        price: '1563.9196'
                        quantity: '100'
                        quote_currency: NGN
                        quote_id: 019a3b5c-81f0-7b2e-9c3d-4e5f60718293
                        reference: trade_sbx_20261030_0004
                        remaining_quantity: '0'
                        side: BUY
                        status: filled
                        updated_at: ''
                      quote_consumption: null
                    message: Order submitted successfully
                    success: true
                    timestamp: '2026-10-30T09:14:41.902Z'
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - properties:
                      data:
                        $ref: '#/components/schemas/TradingSubmitOrderResponse'
                    type: object
          description: Created
        '400':
          content:
            application/json:
              examples:
                invalid_auth_timestamp:
                  $ref: '#/components/examples/InvalidAuthTimestamp'
                invalid_body:
                  summary: The body does not decode
                  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'
                invalid_quote_id:
                  summary: An NGN order whose quote_id is not a UUID
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: invalid quote_id
                    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
                ngn_amount_above_maximum:
                  summary: >-
                    The naira side is above the per-conversion maximum (10000000
                    NGN by default)
                  value:
                    code: INVALID_AMOUNT
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: amount above configured maximum
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Invalid Amount
                    type: https://api.bitnob.com/errors/INVALID_AMOUNT
                ngn_amount_below_minimum:
                  summary: >-
                    The naira side is below the per-conversion minimum (500 NGN
                    by default)
                  value:
                    code: INVALID_AMOUNT
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: amount below configured minimum
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 400
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Invalid Amount
                    type: https://api.bitnob.com/errors/INVALID_AMOUNT
                ngn_amount_precision:
                  summary: >-
                    More decimals than the currency's smallest unit (kobo,
                    satoshi, micro-USDT)
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: amount has more decimal places than the currency supports
                    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
                reference_required:
                  summary: An NGN order without quote_id and without reference
                  value:
                    error:
                      code: BAD_REQUEST
                      message: reference is required when quote_id is omitted
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    success: false
                    timestamp: '2026-10-30T09:15:02.481Z'
                validation_failed:
                  summary: Field checks failed
                  value:
                    error:
                      code: BAD_REQUEST
                      details:
                        quantity: Quantity must be a number
                        side: 'Side must be one of: BUY SELL buy sell'
                      message: Validation failed
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    success: false
                    timestamp: '2026-10-30T09:15:02.481Z'
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - $ref: '#/components/schemas/Problem'
          description: >-
            The body or a field is invalid (answered by the handler), or a
            service refused it: VALIDATION_ERROR from the trading engine or the
            conversion service, INVALID_AMOUNT when the naira side is outside
            the per-conversion range.
          headers:
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/json:
              examples:
                ngn_quote_mismatch:
                  summary: The NGN quote is for another pair, side or amount
                  value:
                    code: NOT_FOUND
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: request does not match quote
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 404
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Not Found
                    type: https://api.bitnob.com/errors/NOT_FOUND
                ngn_quote_not_found:
                  summary: The NGN quote does not exist or is not yours
                  value:
                    code: NOT_FOUND
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: quote not found
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 404
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Not Found
                    type: https://api.bitnob.com/errors/NOT_FOUND
              schema:
                $ref: '#/components/schemas/Problem'
          description: >-
            The quote_id does not exist, belongs to another organisation, or
            does not match the order's pair, side or amount (NOT_FOUND). For
            crypto pairs the trading engine answers with its own detail.
          headers:
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
        '408':
          content:
            application/json:
              examples:
                trading_timeout:
                  summary: The trading engine did not answer in time
                  value:
                    code: TIMEOUT
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      The trading service is temporarily unavailable. Try again
                      shortly.
                    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
              schema:
                $ref: '#/components/schemas/Problem'
          description: >-
            The trading engine did not answer before the deadline (TIMEOUT);
            retry. Crypto pairs only.
          headers:
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
        '409':
          $ref: '#/components/responses/Conflict'
        '412':
          content:
            application/json:
              examples:
                tier_limit_reached:
                  summary: >-
                    The crypto or stablecoin leg of an NGN pair would exceed the
                    tier limit
                  value:
                    code: TIER_LIMIT_REACHED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      This conversion would exceed your daily outflow limit of
                      5000 USD (used 4980, requested 50)
                    extensions:
                      direction: out
                      limit: '5000'
                      rail: conversion
                      remaining: '20'
                      requested: '50'
                      tier: '1'
                      unit: usd
                      used: '4980'
                      window: daily
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 412
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Tier Limit Reached
                    type: https://api.bitnob.com/errors/TIER_LIMIT_REACHED
              schema:
                $ref: '#/components/schemas/Problem'
          description: >-
            NGN pairs only. The non-naira leg would exceed the organisation's
            tier limit (TIER_LIMIT_REACHED); extensions carry the rail
            (conversion), window, limit, used, requested and remaining figures.
          headers:
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
        '422':
          content:
            application/json:
              examples:
                insufficient_funds:
                  summary: >-
                    The balance in the currency you send does not cover the
                    amount (NGN pairs)
                  value:
                    code: INSUFFICIENT_FUNDS
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: insufficient balance
                    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
                market_moved:
                  summary: The BTC price moved beyond tolerance since the NGN quote
                  value:
                    code: PRECONDITION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: market moved beyond tolerance since quote; please re-quote
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Precondition Failed
                    type: https://api.bitnob.com/errors/PRECONDITION_FAILED
                quote_consumed:
                  summary: The NGN quote was already used by another order
                  value:
                    code: PRECONDITION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: quote already consumed
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Precondition Failed
                    type: https://api.bitnob.com/errors/PRECONDITION_FAILED
                quote_expired:
                  summary: The NGN quote expired (30 seconds by default)
                  value:
                    code: PRECONDITION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: quote has expired
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Precondition Failed
                    type: https://api.bitnob.com/errors/PRECONDITION_FAILED
                quote_rate_stale:
                  summary: The rate behind the NGN quote is too old
                  value:
                    code: PRECONDITION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: quote rate is stale; please re-quote
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Precondition Failed
                    type: https://api.bitnob.com/errors/PRECONDITION_FAILED
                swap_unavailable:
                  summary: The liquidity partner declined the swap; nothing moved
                  value:
                    code: PRECONDITION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      We couldn't complete the currency swap just now. Please
                      try again shortly.
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Swap Unavailable
                    type: https://api.bitnob.com/errors/PRECONDITION_FAILED
                unreasonable_rate:
                  summary: >-
                    Our partner's NGN rate is outside the sanity band; quote
                    again shortly
                  value:
                    code: PRECONDITION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: >-
                      We couldn't get a valid conversion rate right now. Please
                      try again shortly.
                    extensions:
                      reason: unreasonable_rate
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Rate Unavailable
                    type: https://api.bitnob.com/errors/PRECONDITION_FAILED
              schema:
                $ref: '#/components/schemas/Problem'
          description: >-
            Business rule refusal (Problem): INSUFFICIENT_FUNDS, or
            PRECONDITION_FAILED for an expired, used or stale quote, a BTC price
            that moved beyond tolerance since the quote, an out-of-band rate or
            a swap the liquidity partner declined. Nothing moved; quote again
            and resubmit.
          headers:
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
        '429':
          content:
            application/json:
              examples:
                quote_rate_limited:
                  summary: >-
                    The per-organisation NGN quote limit (10 a second, 600 an
                    hour by default) is reached
                  value:
                    code: RATE_LIMIT_EXCEEDED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: quote rate limit exceeded; retry after 1s
                    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
                rate_limited:
                  $ref: '#/components/examples/RateLimited'
              schema:
                $ref: '#/components/schemas/Problem'
          description: >-
            Rate limited. The per-IP limiter answers with Retry-After; the NGN
            quote limiter (NGN pairs) answers with the wait in detail and no
            Retry-After header.
          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'
        '500':
          $ref: '#/components/responses/ServerError'
        '503':
          content:
            application/json:
              examples:
                auth_service_busy:
                  $ref: '#/components/examples/AuthServiceBusy'
                auth_service_unavailable:
                  $ref: '#/components/examples/AuthServiceUnavailable'
                conversion_rate_unavailable:
                  $ref: '#/components/examples/PartnerUnavailable'
                limits_unavailable:
                  $ref: '#/components/examples/LimitsUnavailable'
                platform_paused:
                  $ref: '#/components/examples/PlatformPaused'
                trading_engine_unavailable:
                  description: >-
                    detail carries the trading engine's own message; this one is
                    what a deployment without the engine answers.
                  summary: >-
                    The trading engine is unreachable or not configured (crypto
                    pairs)
                  value:
                    code: SERVICE_UNAVAILABLE
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
                    detail: the trading service is unavailable
                    extensions: {}
                    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
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - $ref: '#/components/schemas/Problem'
          description: >-
            Temporarily unavailable; retry later. The trading engine is
            unreachable (crypto pairs), the conversion rate source is down (NGN
            pairs, detail sanitised), the tier limit check could not run
            (LIMITS_UNAVAILABLE), money movement is paused (PLATFORM_PAUSED), or
            the identity service could not check the credentials (with
            Retry-After).
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
components:
  schemas:
    TradingSubmitOrderRequest:
      properties:
        base_currency:
          example: BTC
          maxLength: 10
          pattern: ^[A-Za-z]+$
          type: string
          description: Base currency of the pair, for example BTC.
        price:
          description: >-
            Optional positive decimal price, quote currency per unit of base.
            Ignored for NGN pairs.
          type: string
        quantity:
          description: >-
            Positive decimal amount of the base currency, in major units unless
            quantity_in_base_units is true
          example: '0.01'
          type: string
        quantity_in_base_units:
          default: false
          description: >-
            When true, quantity is in the base currency's smallest unit (for
            example satoshis)
          type: boolean
        quote_currency:
          example: USDT
          maxLength: 10
          pattern: ^[A-Za-z]+$
          type: string
          description: Quote currency of the pair, for example NGN.
        quote_id:
          description: Quote from POST /api/trading/quotes to fill against
          maxLength: 100
          type: string
        reference:
          description: >-
            Your reference. Required for NGN pairs when quote_id is omitted,
            where it is the idempotency key.
          maxLength: 100
          type: string
        side:
          description: Relative to the base currency; upper-cased by the server
          enum:
            - BUY
            - SELL
            - buy
            - sell
          type: string
      required:
        - base_currency
        - quote_currency
        - side
        - quantity
      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
    TradingSubmitOrderResponse:
      properties:
        fills:
          items:
            $ref: '#/components/schemas/TradingFill'
          type: array
        order:
          $ref: '#/components/schemas/TradingOrder'
        quote_consumption:
          description: Present when the order used a quote; null otherwise
          oneOf:
            - $ref: '#/components/schemas/TradingQuoteConsumption'
            - type: 'null'
      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
    TradingFill:
      properties:
        counterparty_order_id:
          type: string
        created_at:
          format: date-time
          type: string
        id:
          type: string
        order_id:
          type: string
        quantity:
          type: string
      type: object
    TradingOrder:
      description: All fields are always present; unset values are empty strings.
      properties:
        base_currency:
          example: BTC
          type: string
        created_at:
          format: date-time
          type: string
        filled_quantity:
          type: string
        id:
          type: string
        order_type:
          example: market
          type: string
        price:
          description: Decimal price, quote currency per unit of base
          type: string
        quantity:
          description: Decimal amount of the base currency
          type: string
        quote_currency:
          example: USDT
          type: string
        quote_id:
          type: string
        reference:
          type: string
        remaining_quantity:
          type: string
        side:
          enum:
            - BUY
            - SELL
          type: string
        status:
          description: For example pending, filled, cancelled, failed
          type: string
        updated_at:
          description: ISO 8601 timestamp, empty when unset
          type: string
      type: object
    TradingQuoteConsumption:
      properties:
        consumed_quantity:
          description: Amount consumed by this order
          type: string
        is_exhausted:
          type: boolean
        quote_id:
          type: string
        remaining_quantity:
          description: Amount left on the quote after this order
          type: string
      type: object
  examples:
    InvalidAuthTimestamp:
      summary: X-Auth-Timestamp is not a number
      value:
        code: VALIDATION_ERROR
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: Invalid timestamp 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
    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
    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
    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
    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
    PlatformPaused:
      summary: Money movement is paused by a platform control
      value:
        code: PLATFORM_PAUSED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: >-
          Money movement is temporarily paused. Nothing is lost — requests can
          be retried once the pause lifts.
        extensions:
          scope: asset:BTC
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 503
        timestamp: '2026-10-30T09:15:02Z'
        title: Money Movement Paused
        type: https://api.bitnob.com/errors/PLATFORM_PAUSED
    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
    AccountTransactionsPaused:
      summary: Money movement is paused on this account
      value:
        code: FEATURE_NOT_ENABLED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: >-
          Transactions on this account are currently paused. Contact support if
          you did not request this.
        extensions:
          feature_key: send_fiat
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 403
        timestamp: '2026-10-30T09:15:02Z'
        title: Account Transactions Paused
        type: https://api.bitnob.com/errors/FEATURE_NOT_ENABLED
    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
    FeatureNotEnabled:
      description: feature_key names the feature that refused the call.
      summary: The feature is off for this organisation
      value:
        code: FEATURE_NOT_ENABLED
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: The fiat payouts feature is currently not available.
        extensions:
          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
    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'
    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
    ConflictEnvelope:
      summary: Conflicts with the resource's current state (answered by the handler)
      value:
        error:
          code: CONFLICT
          message: customer has no email address on file
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        success: false
        timestamp: '2026-10-30T09:15:02.481Z'
    DuplicateKey:
      summary: A resource with the same reference or identifier exists
      value:
        code: DUPLICATE_KEY_ERROR
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: A resource with the same identifier already exists.
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 409
        timestamp: '2026-10-30T09:15:02Z'
        title: Resource Already Exists
        type: https://api.bitnob.com/errors/DUPLICATE_KEY_ERROR
    OperationInProgress:
      summary: The same operation is already running; retry shortly
      value:
        code: ALREADY_EXISTS
        correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        detail: A freeze operation is already in progress, please try again shortly
        extensions:
          operation: freeze
        request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f8091
        status: 409
        timestamp: '2026-10-30T09:15:02Z'
        title: Operation In Progress
        type: https://api.bitnob.com/errors/ALREADY_EXISTS
    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
  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'
    Forbidden:
      content:
        application/json:
          examples:
            account_transactions_paused:
              $ref: '#/components/examples/AccountTransactionsPaused'
            client_inactive:
              $ref: '#/components/examples/ClientInactive'
            feature_not_enabled:
              $ref: '#/components/examples/FeatureNotEnabled'
            ip_not_whitelisted:
              $ref: '#/components/examples/IPNotWhitelisted'
            org_not_active:
              $ref: '#/components/examples/OrgNotActive'
            org_not_active_live:
              $ref: '#/components/examples/OrgNotActiveLive'
            tier_product_locked:
              $ref: '#/components/examples/TierProductLocked'
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorEnvelope'
              - $ref: '#/components/schemas/Problem'
      description: >-
        Not allowed: the request's IP is not on the key's allowlist, the client
        is inactive, a live key is used before the organisation is active
        (ORG_NOT_ACTIVE), a feature is off (FEATURE_NOT_ENABLED), or the
        organisation's tier does not include the product (TIER_PRODUCT_LOCKED).
      headers:
        X-Correlation-ID:
          $ref: '#/components/headers/X-Correlation-ID'
    Conflict:
      content:
        application/json:
          examples:
            conflict_envelope:
              $ref: '#/components/examples/ConflictEnvelope'
            duplicate_key:
              $ref: '#/components/examples/DuplicateKey'
            operation_in_progress:
              $ref: '#/components/examples/OperationInProgress'
          schema:
            oneOf:
              - $ref: '#/components/schemas/ErrorEnvelope'
              - $ref: '#/components/schemas/Problem'
      description: >-
        Conflicts with existing state: a repeated reference
        (DUPLICATE_KEY_ERROR), the same operation already in progress
        (ALREADY_EXISTS, retry shortly), or the resource's state (CONFLICT).
      headers:
        X-Correlation-ID:
          $ref: '#/components/headers/X-Correlation-ID'
    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'
  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.