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, expressed as a decimal string in the source asset (e.g. '10' = 10 USDC). 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
chainstringOptional

Blockchain network used when source is 'onchain' (e.g. 'BITCOIN', 'trc20', 'erc20'). 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. 'QT_100003'). 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. Shape depends on destination_type (bank, mobile_money, swift). For SWIFT, populate the bank fields, a nested beneficiary address, and a nested sender identity.

6
beneficiary.destination_typestringRequired

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

7
beneficiary.countrystringRequired

Two-letter ISO country code of the destination account.

8
beneficiary.account_namestringRequired

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

9
beneficiary.account_numberstringRequired

Bank account number (or IBAN for SWIFT corridors).

10
beneficiary.bank_codestringConditional

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

11
beneficiary.swift_codestringConditional

BIC/SWIFT code of the destination bank. Required when destination_type is 'swift'.

12
beneficiary.bank_namestringConditional

Display name of the destination bank. Required for SWIFT.

13
beneficiary.bank_address / bank_city / bank_post_code / bank_countrystringConditional

Physical address of the destination bank branch. All required for SWIFT.

14
beneficiary.remittance_purposestringConditional

Regulator-visible reason code (e.g. 'salary_payment', 'family_support'). Required for SWIFT.

15
beneficiary.beneficiaryobjectConditional

Physical address of the recipient (country, city, post_code, address). Required for SWIFT.

16
beneficiary.senderobjectConditional

Identity of the sender. type is 'business' or 'individual'. Business senders provide registration_number; individual senders provide date_of_birth and country_of_birth.

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
data.payoutObject

The initialized payout record.

4
data.payout.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
data.payout.quote_idString

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

6
data.payout.statusString

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

7
data.payout.sourceString

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

8
data.payout.from_assetString

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

9
data.payout.to_currencyString

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

10
data.payout.amountString

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

11
data.payout.settlement_amountString

Fiat amount the beneficiary will receive after conversion.

12
data.payout.btc_amountString

Equivalent amount expressed in BTC for internal pricing.

13
data.payout.sat_amountString

Equivalent amount expressed in satoshis.

14
data.payout.feesString

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

15
data.payout.cent_feesString

Total fees expressed in cents / smallest fiat unit.

16
data.payout.exchange_rateObject

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

17
data.payout.beneficiaryObject

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

18
data.payout.payment_reasonString

Reason code provided on the request.

19
data.payout.referenceString

Reference provided on the request.

20
data.payout.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
metadata.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
data.payout.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
data.payout.sourceString

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

3
data.payout.company_idUUID

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

4
data.payout.cent_amountString

Settlement amount in cents / smallest fiat unit.

5
data.payout.callback_urlString

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

6
data.payout.provider_settlement_idString

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

7
data.payout.countryString

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

8
data.payout.tripObject

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

9
data.payout.trip.quote_atDate

When the quote was created.

10
data.payout.trip.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