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

# Core concepts and architecture

> The objects the Bitnob Business API is built from, how a request moves through the platform, and why money movement completes asynchronously.

Bitnob exposes one API over three kinds of rail: bitcoin, stablecoins, and local currency payment networks. The products differ, but they share the same object model and the same request lifecycle. This page explains that shared model. Learn it once and every product section reads the same way.

## The object model

Nine objects carry almost every integration.

| Object | What it is | Where you meet it |
| - | - | - |
| Account | Your Bitnob business account. It holds your credentials, your balances, and your settings. | [Set up your account](https://www.bitnob.dev/docs/getting-started/account-setup.md) |
| Customer | A person or business you serve. Cards and virtual accounts belong to a customer. | [Create customer](https://www.bitnob.dev/api-reference/customers/create-customer.md) |
| Beneficiary | A saved payout destination, such as a bank account or a mobile money wallet. | [Create beneficiary](https://www.bitnob.dev/api-reference/beneficiaries/create-beneficiary.md) |
| Address | A deposit address you issue for bitcoin or a stablecoin chain. | [Generate address](https://www.bitnob.dev/api-reference/addresses/generate-address.md) |
| Balance | Funds you hold, held separately per currency. | [List balances](https://www.bitnob.dev/api-reference/balances/list-balances.md) |
| Quote | A price and an amount, fixed for a short time. | [Create payout quote](https://www.bitnob.dev/api-reference/payouts/create-quote.md) |
| Reference | A unique string you attach to an action. It makes retries safe. | [Idempotency and references](https://www.bitnob.dev/docs/getting-started/api-best-practices/idempotency-and-reference-integrity.md) |
| Transaction | The record of one movement of value. | [List transactions](https://www.bitnob.dev/api-reference/transactions/list-transactions.md) |
| Webhook event | A message we push to your server when state changes. | [Webhooks and event handling](https://www.bitnob.dev/docs/getting-started/api-best-practices/webhook-best-practices.md) |

> [!NOTE]
>
> The API returns `company_id` on some objects. It identifies your account.

### Accounts and customers

Your account is the top-level container. It owns your credentials and your balances.

A customer is a person or business you serve. You create customers when a product needs to attribute funds or a card to a named end user. Cards and virtual accounts always belong to a customer. Payouts and trades do not.

This distinction matters for compliance. When you issue a card, the card carries your customer's identity, not yours.

### Addresses

An address is where you receive crypto. You generate one per asset and network: a bitcoin address for on-chain deposits, or a stablecoin address on a supported chain, such as USDT or USDC on ERC20 or TRC20.

Funds sent to an address you issued land in your balance for that currency, and a webhook event tells you when.

### Balances

You hold a balance per currency. Balances are your working capital on the platform.

Funds arrive in a balance in four ways:

* A deposit to an address you issued.
* A deposit to a virtual account.
* The proceeds of a trade.
* A card withdrawal, or a refund on a terminated card.

Funds leave a balance through a payout, a withdrawal, a card funding operation, or a trade.

### Transactions

A transaction is the record of one movement of value. Every movement in or out of a balance produces one, whatever the rail:

* **Crypto:** on-chain bitcoin transfers, Lightning payments, and stablecoin transfers.
* **Fiat:** deposits from bank accounts or mobile money, and payouts back to them.
* **Cards and trades:** card funding and conversions between currencies.

Read transactions to reconcile. Use webhook events to learn when a transaction's status changes.

### References

You supply a reference on every action that moves money. The reference is your idempotency key. If you send the same request twice with the same reference, the platform executes it once.

This is the single most important habit in the API. [Idempotency and references](https://www.bitnob.dev/docs/getting-started/api-best-practices/idempotency-and-reference-integrity.md) explains how to design them.

## The request lifecycle

Every authenticated call follows the same path.

**1. You sign the request**

You compute an HMAC-SHA256 signature over `CLIENT_ID:TIMESTAMP:NONCE:BODY` and send it in four headers. See [Authentication](https://www.bitnob.dev/api-reference/authentication/authentication.md).

**2. We verify the signature and the timestamp**

A bad signature returns `401`. A stale timestamp also returns `401`, because the timestamp prevents replay of an old request.

**3. We validate the request**

Missing or malformed fields return `400`. Requests that parse but cannot execute, such as an amount above your limit, return `422`.

**4. We accept the action and answer**

The response confirms that we accepted the action. For money movement it does not confirm delivery.

**5. We send a webhook event when the outcome is known**

Settlement happens on an external rail. The webhook carries the result.

![Architecture diagram](https://mintcdn.com/bitnob/5PGS9OuNC096evyI/images/architecture-diagram.png?fit=max\&auto=format\&n=5PGS9OuNC096evyI\&q=85\&s=1efa5eb6d29d766024b79e7480c6e257)

## Money movement is asynchronous

The API answers in milliseconds. Bitcoin, stablecoin chains, and bank rails do not.

A bitcoin transaction waits for confirmations. A bank transfer waits for the receiving bank. A card authorization waits for the network. Bitnob cannot make an external rail faster, so it reports progress instead of blocking.

This has one consequence that shapes every integration:

> [!WARNING]
>
> A `200` response means we accepted the action. It does not mean the money arrived. Treat the webhook event as the record of the outcome.

Integrations that treat the synchronous response as final report success too early. Users then see a delivered payment that has not settled.

## Quotes and price risk

Exchange rates move. A quote fixes a rate and an amount for a short window, and it carries an `expires_at` timestamp.

You create a quote, then execute against it before it expires. If it expires, you create a new one. The platform never re-prices an expired quote at the old rate, because that rate no longer reflects the market.

[Quote lifecycle and expiry](https://www.bitnob.dev/docs/getting-started/api-best-practices/quote-expiry-and-transaction-windows.md) covers the handling in detail.

## Amounts

The unit depends on the product. Balances, transactions, and withdrawals use integer strings in the smallest unit: one BTC is 100,000,000 satoshis, one USDT is 1,000,000 base units, and one naira is 100 kobo. Trading and payouts use decimal strings in major units. Cards use micro-units, where 1 USD is 1,000,000.

Check the unit before you parse or send an amount, and store integers in the smallest unit in your own ledger. [Currencies and amounts](https://www.bitnob.dev/docs/getting-started/core-concepts-and-architecture/currencies-and-amounts.md) has the table for every product.

## Rate limits

The API allows 500 requests per minute per IP address. Every response carries `X-Ratelimit-Limit`, `X-Ratelimit-Remaining`, and `X-Ratelimit-Reset`. Over the limit, you get `429`; see [Errors and retries](https://www.bitnob.dev/docs/getting-started/api-best-practices/errors-and-retries.md#rate-limits).

## One environment, two credentials

Sandbox and production share the base URL `https://api.bitnob.com`. Your `CLIENT_ID` is the same in both. Your `CLIENT_SECRET` differs.

The secret you sign with selects the environment. Keep the two secrets in separate configuration, because a production secret in a test job moves real money.

## Errors

The Bitnob Business API uses one error model across payouts, cards, trading, and virtual accounts. Bodies follow RFC 7807 and carry a `correlation_id`. Quote that value when you contact support, because it identifies the exact request.

The Bitnob Enterprise API is a separate product and returns a different shape: a nested `error` object with `type`, `code`, and `message`. Handle the two separately if you integrate both.

See [Errors and retries](https://www.bitnob.dev/docs/getting-started/api-best-practices/errors-and-retries.md) for the status codes and the retry rules.

## Where to go next

> [card] [Currencies and amounts](https://www.bitnob.dev/docs/getting-started/core-concepts-and-architecture/currencies-and-amounts.md)
>
> How to store, convert, and display value without precision loss.

> [card] [Build reliably](https://www.bitnob.dev/docs/getting-started/api-best-practices/api-keys-and-credentials.md)
>
> Credentials, idempotency, webhooks, errors, and observability.


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