Try it out

Payouts

The Payouts API allows you to convert crypto assets (BTC, USDT, USDC) into local fiat currencies (e.g., NGN, KES). The flow involves creating a quote, initializing the payout with beneficiary details, depositing funds, and finalizing the transaction.

Payout Flow

Create quote → Initialize (with beneficiary) → Finalize. Use account-lookup, banks/:countryCode, and supported-countries/:country upstream to build a valid Initialize request.


Create Payouts Quote

Creates a quote for converting cryptocurrency to fiat. You can specify either amount (crypto amount) or settlement_amount (target fiat amount).

Create Payouts Quote

Create Payouts Quote Request
1
amountstringRequired if settlement_amount not provided

Crypto amount to convert. Takes priority over settlement_amount when both are provided.

2
settlement_amountstringRequired if amount not provided

Target fiat amount you want the beneficiary to receive. Ignored when amount is also provided.

3
countrystringRequired

Two-letter ISO 3166-1 alpha-2 country code for the destination (e.g. 'NG', 'KE', 'GH'). Must be one of the codes returned by GET /api/payouts/supported-countries.

4
from_assetstringRequired

Crypto asset you're debiting from your wallet: 'BTC', 'USDT', or 'USDC'.

5
to_currencystringRequired

Target fiat currency code the beneficiary will receive (e.g. 'NGN', 'KES', 'GHS'). Must be a currency supported on the chosen country.

6
sourcestringRequired

Source of funds (lowercase). 'offchain' debits your Bitnob wallet balance directly; 'onchain' expects a blockchain deposit to cover the quote.

7
chainstringRequired for onchain

Blockchain network used when source is 'onchain' (e.g. 'BITCOIN', 'TRON', 'ETHEREUM') — must be one supported by your from_asset. Omit when source is 'offchain'.

8
referencestringRequired

Client-generated unique identifier for this quote. Reused on initialize and finalize for idempotency and reconciliation.

Amount vs. Settlement Amount

Provide either amount (crypto side) or settlement_amount (fiat side) — not both. When both are sent, amount takes priority and settlement_amount is ignored.

Create Payouts Quote

Create Payouts Quote Response
1
idstring (UUID)

A globally unique identifier for the payout. Used to reference this payout in future requests.

2
quote_idstring

An internal reference string for the quote, passed into subsequent payout endpoints.

3
company_idstring (UUID)

The unique identifier of the company that created the quote.

4
statusstring

The current state of the quote (e.g., 'QUOTE'). Changes as the payout progresses through its lifecycle.

5
sourcestring

The source of funds used for the payout (e.g., 'OFFCHAIN' for wallet balance, 'ONCHAIN' for blockchain deposit).

6
from_assetstring

The crypto asset being converted (e.g., 'USDT', 'BTC', 'USDC').

7
chainstring

The blockchain network for the transaction (e.g., 'CHAIN_TYPE_ETHEREUM', 'CHAIN_TYPE_BITCOIN').

8
to_currencystring

The target fiat currency code (e.g., 'GHS', 'NGN').

9
amountstring

The original crypto amount provided in the quote request.

10
settlement_amountstring

The exact amount of fiat the recipient will receive after conversion.

11
sat_amountstring

The equivalent amount in satoshis for the requested crypto amount.

12
btc_amountstring

The equivalent BTC amount for the requested crypto amount.

13
feesstring

The fee charged for this payout in the from_asset currency.

14
exchange_rateobject

Contains the conversion rate details: 'rate' (crypto to fiat), 'btc_rate' (BTC to fiat), and 'currency'.

15
referencestring

Your unique reference string for this quote.

16
countrystring

Two-letter ISO country code for the destination.

17
expires_atstring (ISO 8601)

Timestamp indicating when this quote expires. After this time, the quote must be re-generated.

18
created_atstring (ISO 8601)

Timestamp when the quote was created.

Create Payouts Quote - Response

Initialize Payout

Locks the quote, attaches a beneficiary, and moves the payout to INITIATED. The beneficiary object varies by destination_type and country — call GET /api/payouts/supported-countries/:country (and, for bank rails, GET /api/payouts/banks/:countryCode + Account Lookup) to build a valid shape.

Initialize Payout

Initialize Payout - Path Parameters
1
quoteIdstringRequired

The ID of the quote returned by Create Payouts Quote (e.g. 'QT2_21015643'). Must not be expired.

Initialize Payout - Request Body
1
quote_idstringRequired

The quote you're initializing. Must match the :quoteId path parameter.

2
referencestringRequired

Client-generated unique identifier for this payout. Reused on Finalize for idempotency and reconciliation.

3
payment_reasonstringRequired

Short reason code for the payment (e.g. 'salary', 'vendor_payment', 'family_support'). Some corridors require a value from a fixed list — check Get Country Details.

4
callback_urlstringOptional

HTTPS URL that will receive payout lifecycle webhooks (completed, failed).

5
beneficiaryobjectRequired

Recipient details — the sub-fields below cover the bank rail. The shape varies by `destination_type`; for SWIFT/international corridors, see the SWIFT Payouts page.

6
destination_typestringRequired

Rail selector: 'bank', 'mobile_money', or 'swift'.

7
countrystringRequired

Two-letter ISO country code of the destination account.

8
account_namestringRequired

Name on the destination account. Use the value returned by Account Lookup when available.

9
account_numberstringRequired

Bank account number (or IBAN for SWIFT corridors).

10
bank_codestringConditional

Provider code from Get Banks. Required for 'bank' and 'mobile_money' destination types.

Initialize Payout - Request

Initialize Payout - Response
1
successBoolean

Top-level flag indicating whether the request was processed successfully.

2
messageString

Human-readable status message.

3
payoutObject

The initialized payout record.

4
idUUID

Unique identifier for this payout. Pass it as :id to GET /api/payouts/:id or as the path param on Finalize is keyed off quote_id (see Finalize).

5
quote_idString

The quote that was locked (echoed from the request).

6
statusString

Lifecycle state. 'INITIATED' after a successful initialize; transitions through processing states to 'COMPLETED' or 'FAILED' after Finalize.

7
sourceString

Source of funds (from the original quote). 'SOURCE_UNSET' when source was not explicitly set.

8
from_assetString

Crypto asset being debited (e.g. 'USDT', 'USDC', 'BTC').

9
to_currencyString

Destination fiat currency (e.g. 'GHS', 'NGN').

10
amountString

Crypto amount being sent, as a decimal string in from_asset units.

11
settlement_amountString

Fiat amount the beneficiary will receive after conversion.

12
btc_amountString

Equivalent amount expressed in BTC for internal pricing.

13
sat_amountString

Equivalent amount expressed in satoshis.

14
feesString

Total fees applied to the payout, as a decimal string in the source asset.

15
cent_feesString

Total fees expressed in cents / smallest fiat unit.

16
exchange_rateObject

Locked FX details: rate (from_asset → to_currency), btc_rate (for BTC pricing), currency (display).

17
beneficiaryObject

The full beneficiary object echoed back from the request for auditability.

18
payment_reasonString

Reason code provided on the request.

19
referenceString

Reference provided on the request.

20
expires_atDate

RFC 3339 / ISO 8601 timestamp. Call Finalize before this time or re-request a quote.

21
data.payout.created_at / updated_atDate

Set once the payout is fully persisted downstream. May be null immediately after initialize.

22
request_idString

Request identifier for log correlation and support.

23
timestampDate

Top-level RFC 3339 / ISO 8601 server timestamp of when the response was generated (UTC).

Finalize Before expires_at

Initialize returns data.payout.expires_at. You must call POST /api/payouts/:quoteId/finalize before that timestamp — if it passes, re-run the quote and initialize flow to lock a fresh rate.

Initialize Payout - Response

Finalize Payout

Finalizes a payout after the deposit has been confirmed. No request body is required — simply call this endpoint with the quoteId path parameter.

Finalize Payout

Finalize Payout - Path Parameters
1
quoteIdstringRequired

The ID of the quote to finalize.

Finalize Payout - Request

Finalize Payout Response

The response echoes the same data.payout shape as Initialize, with a few settlement-specific additions once the rail has accepted the transfer.

1
statusString

Transitions from 'INITIATED' to 'PENDING' on finalize, then on to 'COMPLETED' or 'FAILED' once the rail settles. Watch the webhook for the terminal state.

2
sourceString

Populated from the quote (e.g. 'OFFCHAIN', 'ONCHAIN'). 'SOURCE_UNSET' is replaced with the real source at finalize.

3
company_idUUID

The company the payout is debited from (populated at finalize).

4
cent_amountString

Settlement amount in cents / smallest fiat unit.

5
callback_urlString

Echoed from the initialize request — URL that will receive lifecycle webhooks.

6
provider_settlement_idString

Identifier returned by the downstream rail (e.g. SWIFT provider / bank). Use it for reconciliation with the provider.

7
countryString

Destination country (populated at finalize, e.g. 'GH').

8
tripObject

Timestamps of each milestone in the payout's journey: quote_at, initialized_at, and (on completion) finalized_at.

9
quote_atDate

When the quote was created.

10
initialized_atDate

When the beneficiary was attached and the payout was initialized.

11
data.payout.created_at / updated_atDate

Now populated (not null) — the payout has been persisted through the finalize pipeline.

Baseline Fields

All other fields (id, quote_id, from_asset, to_currency, amount, settlement_amount, btc_amount, sat_amount, fees, cent_fees, nested exchange_rate, echoed beneficiary, reference, payment_reason, expires_at) use the same shape as the Initialize response — refer to that section for per-field explanations.

Finalize Payout - Response
Did you find this page useful?

Join our Discord