Payouts
A payout sends money from your available balance to a mobile-money wallet.
curl -s -X POST http://localhost:4000/v1/payouts \ -H "Authorization: Bearer $XAALIS_KEY" -H "Content-Type: application/json" \ -H "Idempotency-Key: payout-2026-09-25" \ -d '{"amount":5000,"provider":"wave","recipient":{"phone":"+221770000001","name":"Awa Ndiaye"}}'| Field | Notes |
|---|---|
amount |
integer XOF |
provider |
wave or orange_money (Orange Money payouts are not available in live mode yet → 422 unsupported) |
recipient.phone |
+2217XXXXXXXX |
recipient.name |
optional |
client_reference |
optional, your id |
How your balance moves
Section titled “How your balance moves”The money is reserved before anything is sent, so two payouts can never spend the same francs:
| Step | available |
pending_payouts |
|---|---|---|
POST /v1/payouts accepted (pending) |
− (amount + fee) | + amount |
provider confirms → succeeded |
— | − amount |
provider refuses → failed |
+ (amount + fee) | − amount |
If available can’t cover amount + fee, the request fails with 422 insufficient_funds and your balance doesn’t
change. The attempt is recorded as a payout with status: "failed", failure_reason: "insufficient_funds", and
retrying the same key returns the same 422.
The payout fee is shown on the object (0 by default).
Statuses
Section titled “Statuses”pending → processing → succeeded | failed. You get payout.succeeded / payout.failed webhooks.
Poll GET /v1/payouts/{id} if you need to wait synchronously. List with GET /v1/payouts?limit=&starting_after=.
An Idempotency-Key is required (400 without one): a retried payout request returns the first
payout — never a second transfer. The same key with a different amount, provider or recipient returns 409.
If the API answers 503 temporarily_unavailable, the reservation’s outcome isn’t known yet: retry with the
same key — you get the original payout or a clean refusal, never two.