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

# Reveal card details

> Returns the card number, CVV and expiry. If you have registered an encryption key, they come back in encrypted_details instead.



## OpenAPI

````yaml /api-collections/swagger/bitnob-api-v2.openapi.json get /api/cards/{cardId}/secure
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/cards/{cardId}/secure:
    get:
      tags:
        - Cards
      summary: Reveal card details
      description: >-
        Returns the card number, CVV and expiry. If you have registered an
        encryption key, they come back in encrypted_details instead.
      operationId: cardsGetSecureDetails
      parameters:
        - description: Card ID
          example: 019a3b5c-2c4d-7e6f-8a9b-0c1d2e3f4a51
          in: path
          name: cardId
          required: true
          schema:
            format: uuid
            type: string
      responses:
        '200':
          content:
            application/json:
              examples:
                encrypted:
                  summary: Company with a registered encryption key
                  value:
                    data:
                      balance_amount: '25000000'
                      balance_breakdown: null
                      balance_currency: USD
                      encrypted_details:
                        algorithm: RSA-OAEP-256+AES-256-GCM
                        encrypted_data: c2FuZGJveC1lbmNyeXB0ZWQtcGF5bG9hZC1leGFtcGxl...
                        encrypted_key: c2FuZGJveC13cmFwcGVkLWFlcy1rZXktZXhhbXBsZQ...
                    message: Card details retrieved successfully
                    success: true
                    timestamp: '2026-10-30T09:15:02.481Z'
                plaintext:
                  summary: Company without an encryption key
                  value:
                    data:
                      balance_amount: '25000000'
                      balance_breakdown: null
                      balance_currency: USD
                      details:
                        card_id: 019a3b5c-2c4d-7e6f-8a9b-0c1d2e3f4a51
                        card_number: '4111111111111111'
                        cvv: '123'
                        expiry_month: '10'
                        expiry_year: '2029'
                        name: Adaeze Okafor
                    message: Card details retrieved successfully
                    success: true
                    timestamp: '2026-10-30T09:15:02.481Z'
                terminated:
                  summary: 'Terminated card: numbers are zeroed'
                  value:
                    data:
                      balance_amount: '0'
                      balance_breakdown: null
                      balance_currency: USD
                      details:
                        card_id: 019a3b5c-2c4d-7e6f-8a9b-0c1d2e3f4a51
                        card_number: '0000000000000000'
                        cvv: '000'
                        expiry_month: ''
                        expiry_year: ''
                        name: ''
                    message: Card details retrieved successfully
                    success: true
                    timestamp: '2026-10-30T09:15:02.481Z'
              schema:
                allOf:
                  - $ref: '#/components/schemas/Envelope'
                  - properties:
                      data:
                        $ref: '#/components/schemas/CardsCardDetails'
                    type: object
          description: OK
        '400':
          content:
            application/json:
              examples:
                invalid_card_id:
                  summary: The Card ID in the path is not a UUID
                  value:
                    error:
                      code: BAD_REQUEST
                      message: Invalid Card ID, expected a UUID
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f0118
                    success: false
                    timestamp: '2026-10-30T09:15:02.481Z'
                not_active:
                  summary: >-
                    The card is not active (frozen, blocked, terminated or still
                    provisioning)
                  value:
                    code: VALIDATION_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f0099
                    detail: Card is not active
                    extensions:
                      card_id: 019a3b5c-2c4d-7e6f-8a9b-0c1d2e3f4a51
                      created_status: completed
                      status: frozen
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f0099
                    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 card id is not a UUID (envelope), or the card is not active
            (Problem, VALIDATION_ERROR).
          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:
                card_not_found:
                  summary: No card with this id belongs to your organisation
                  value:
                    code: NOT_FOUND
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f0119
                    detail: >-
                      card with ID '019a3b5c-2c4d-7e6f-8a9b-0c1d2e3f4a51' was
                      not found
                    extensions:
                      id: 019a3b5c-2c4d-7e6f-8a9b-0c1d2e3f4a51
                      resource: card
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f0119
                    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 card with this 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:
                no_encryption_key:
                  summary: Encryption is on but no key is registered
                  value:
                    code: PRECONDITION_FAILED
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f011a
                    detail: >-
                      encryption is enabled but no encryption key is registered;
                      call RegisterEncryptionKey first
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f011a
                    status: 422
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Precondition Failed
                    type: https://api.bitnob.com/errors/PRECONDITION_FAILED
              schema:
                $ref: '#/components/schemas/Problem'
          description: >-
            Encrypted details are switched on for the company but no key is
            registered (PRECONDITION_FAILED); register one with POST
            /api/cards/encryption-key.
          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'
                card_service_unavailable:
                  summary: The card service is not reachable
                  value:
                    code: SERVICE_UNAVAILABLE
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f009b
                    detail: >-
                      Service is temporarily unavailable. Please try again
                      later.
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f009b
                    status: 503
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Service Unavailable
                    type: https://api.bitnob.com/errors/SERVICE_UNAVAILABLE
                issuer_failed:
                  summary: The card issuer refused or failed the call
                  value:
                    code: EXTERNAL_SERVICE_ERROR
                    correlation_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f009a
                    detail: An internal error occurred. Please try again later.
                    request_id: req_019a3b5c-7d1e-7f20-8a4b-3c5d6e7f009a
                    status: 503
                    timestamp: '2026-10-30T09:15:02Z'
                    title: Card Operation Failed
                    type: https://api.bitnob.com/errors/EXTERNAL_SERVICE_ERROR
              schema:
                oneOf:
                  - $ref: '#/components/schemas/ErrorEnvelope'
                  - $ref: '#/components/schemas/Problem'
          description: >-
            Temporarily unavailable; retry later. The identity service could not
            check the credentials, the card is not provisioned at the issuer yet
            or the issuer is unreachable, or the encryption key could not be
            read.
          headers:
            Retry-After:
              $ref: '#/components/headers/Retry-After'
            X-Correlation-ID:
              $ref: '#/components/headers/X-Correlation-ID'
components:
  schemas:
    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
    CardsCardDetails:
      properties:
        balance_amount:
          description: Micro-units.
          pattern: ^-?[0-9]+$
          type: string
        balance_breakdown:
          oneOf:
            - $ref: '#/components/schemas/CardsBalanceBreakdown'
            - type: 'null'
        balance_currency:
          type: string
        details:
          description: Plaintext details; absent when encrypted_details is returned.
          properties:
            card_id:
              type: string
            card_number:
              type: string
            cvv:
              type: string
            expiry_month:
              type: string
            expiry_year:
              type: string
            name:
              type: string
          type: object
        encrypted_details:
          description: >-
            Envelope sealed to the registered RSA key; absent when details is
            returned.
          properties:
            algorithm:
              const: RSA-OAEP-256+AES-256-GCM
              description: RSA-OAEP-256 key wrap with AES-256-GCM.
              type: string
            encrypted_data:
              type: string
            encrypted_key:
              type: string
          type: object
      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
    CardsBalanceBreakdown:
      description: Live split of balance_amount.
      properties:
        amount_due:
          description: Owed to our partner, micro-units.
          pattern: ^-?[0-9]+$
          type: string
        as_of:
          description: When our partner was read; may be cached up to 5 minutes.
          format: date-time
          type: string
        available:
          description: Spendable now, micro-units. Equals balance_amount.
          pattern: ^-?[0-9]+$
          type: string
        currency:
          description: ISO 4217.
          type: string
        non_withdrawable:
          description: Spendable but not withdrawable, micro-units.
          pattern: ^-?[0-9]+$
          type: string
        pending:
          description: >-
            Authorization holds, micro-units; null when our partner does not
            report them.
          pattern: ^-?[0-9]+$
          type:
            - string
            - 'null'
        scope:
          enum:
            - CARD
            - SHARED_POOL
          type: string
        withdrawable:
          description: Withdrawable, micro-units.
          pattern: ^-?[0-9]+$
          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'
    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'
    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:
    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
    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
    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.