Public developer API
POST /v1/payouts
Sends money to a mobile money wallet or bank account. The amount plus the Dutch fee is debited from your wallet immediately; a failed payout is returned to your balance.
Access
A project-specific API key (Authorization: Bearer dapi_live_...) and its Business ID (X-Business-Id). Rate limited per business (120 calls a minute by default).
Requires an Idempotency-Key header.
Requires an Idempotency-Key header. Repeating a request with the same key returns the original payout and never pays twice.
If payout approval is switched on for your organization, the response is 202 with status awaiting_approval, and an approver must confirm it in the dashboard.
Subscribe to payout.completed and payout.failed webhooks, or poll GET /v1/payouts/{id}.
Body
| Field | Type | Required | Description |
|---|---|---|---|
amount | number | yes | Amount to send, in the source currency. Greater than 0. |
currency | string | yes | Source wallet currency: USD, XAF, GHS, ZAR, NGN, RWF, UGX or KES. |
rail | string | yes | mobile_money or bank, where that rail is supported: CM/RW/CD/CI/SN/TZ/ZM mobile money; GH/KE/UG mobile money or bank; NG/ZA bank. |
recipient.name | string | yes | Recipient full name (2 to 100 characters). |
recipient.account | string | yes | Mobile number in international format, or bank account number. |
recipient.country | string | yes | ISO 3166 alpha-2 payout destination: CM, GH, KE, RW, UG, NG, ZA, CD, TZ, ZM, SN or CI. Only the rail listed for each country is accepted. |
recipient.bankCode | string | no | Required for bank unless recipient.bank is sent. The public developer API has no bank-list endpoint; obtain the code from your business dashboard or support. |
recipient.bank | string | no | Bank name (required for bank unless recipient.bankCode is sent). |
markupPercent | number | no | Your own markup as a percentage of the amount (0 to 50). Reported in fees, never debited. |
markupFixed | number | no | Your own fixed markup in the request currency. Reported in fees, never debited. |
reference | string | no | Your own reference, 4 to 64 characters (letters, digits, - _ : .). Must be unique. |
description | string | no | Up to 140 characters. |
fund | string | no | Use balance to fund from the wallet. Just-in-time funding requests return HTTP 501 with funding_not_available. |
Example request
curl --request POST \
--url 'https://production.dutchapi.co/v1/payouts' \
--header 'X-Business-Id: YOUR_BUSINESS_ID' \
--header 'Authorization: Bearer bsk_live_YOUR_BUSINESS_SECRET' \
--header 'Idempotency-Key: payouts-0001' \
--header 'Content-Type: application/json' \
--data '{"amount":40000,"currency":"XAF","rail":"mobile_money","recipient":{"name":"Jean Mbarga","account":"+237670000001","country":"CM"},"reference":"order-1042","description":"Supplier payment"}'
Response 201
{
"id": "pyt_8f2c1a",
"object": "payout",
"kind": "disbursement",
"status": "processing",
"amount": 40000,
"currency": "XAF",
"fee": 300,
"description": "Payout to Ada Obi",
"created_at": "2026-10-13T09:30:00.000Z",
"completed_at": null,
"failure_reason": null,
"funding": "balance",
"rail": "bank",
"recipient": {
"name": "Ada Obi",
"account": "******6789",
"country": "NG"
},
"receive": {
"amount": 88978.6,
"currency": "NGN",
"rate": 2.2244
},
"fees": {
"currency": "XAF",
"rule": "fixed",
"ruleDetail": "Under 50,000 XAF: 300 XAF fixed",
"dutchFee": 300,
"markup": 100,
"totalFee": 400
}
}
Errors
| Status | error | Meaning |
|---|---|---|
| 400 | idempotency_key_required | Send an Idempotency-Key header. |
| 400 | valid_amount_required | amount must be a positive number. |
| 400 | unsupported_currency | currency must be one of USD, XAF, GHS, ZAR, NGN, RWF, UGX or KES. |
| 402 | insufficient_funds | The wallet balance is too low. |
| 403 | limits_not_set | No live limit is enabled for this currency (Dashboard, Limits & safety). |
| 422 | over_per_request_limit | The amount is above the per-request limit. |
| 422 | over_daily_limit | The daily limit would be exceeded. |
| 423 | money_movement_paused | The kill switch is on. |
| 409 | duplicate_reference | That reference was already used. |
| 409 | request_in_progress | A request with the same Idempotency-Key is still running. |
| 422 | idempotency_key_reused | The Idempotency-Key was used with a different request. |
| 400 | network_not_supported | Do not send a named mobile-money network. |
| 422 | unsupported_payout_rail | That bank or mobile-money rail is not supported in the requested country. |
| 422 | payout_rejected | Dutch API could not complete the payout; the amount was returned. |