Payouts
Send funds from your balance to a mobile wallet or a bank account.
Create a payout
POST /v1/payouts
Pass an Idempotency-Key — it matters even more than on a collection: a payout replayed without
idempotency would pay twice.
| Field | Required | Description |
|---|---|---|
asset_id |
yes | The asset, by identifier |
amount_minor |
yes | String, in minor units |
country |
yes | Country of the operation (ISO 3166-1 alpha-2) |
platform_id |
yes | The paying platform (GET /v1/corridors) |
recipient |
yes | The recipient — see below |
platform_account_handle |
— | The sub-account debited. Empty = the corridor's primary |
rail |
— | Forces a specific rail |
client_ref |
— | Your reference |
description |
— | Free text |
The recipient is typed
"recipient": {
"name": "Mouhamadou Sy",
"identifier_type": "msisdn",
"identifier": "+221771234567"
}
identifier_type says what kind of address you hold (msisdn, iban, an alias…) and identifier
carries it. That is what lets a platform carrying several rails resolve without you naming one.
phone alone remains fully supported and reads as (msisdn, phone). Supplying both forms, or a
type with no value, is refused — never guessed at.
Balance first
A payout is debited from your available balance:
GET /v1/balances
Balances are returned per asset and per (platform, country), with the available, pending and reserved amounts. Reserved covers outgoing operations already committed: it is not spendable.
Balances never add up across assets. There is no currency conversion on this platform, so a total across all assets would mean nothing.
A payout that would exceed the available balance is refused immediately, in the response itself:
422 with code insufficient_funds. It is never queued waiting for funds — there is no overdraft.
Requesting a withdrawal of your balance
POST /v1/payout-requests
GET /v1/payout-requests
GET /v1/payout-requests/{id}
It is a request, not a payout. No money moves and nothing is reserved: the operation opens at status
requested, and a person decides it in the dashboard. That is the maker-checker split — the API key asks, an account owner decides. There is deliberately no cancel: a pending request holds nothing, so it is rejected by the decider rather than withdrawn by you.
The amount is GROSS: withdrawal fees come out of it, they are not added on top. With no fee schedule
configured for the asset the request is refused with 409 — a free withdrawal is a zero row
somebody entered on purpose, never an absence.
Following up
payout.success, payout.failed and payout.cancelled arrive by webhook;
GET /v1/payouts/{id} gives the state on demand.