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

FieldTypeRequiredDescription
amountnumberyesAmount to send, in the source currency. Greater than 0.
currencystringyesSource wallet currency: USD, XAF, GHS, ZAR, NGN, RWF, UGX or KES.
railstringyesmobile_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.namestringyesRecipient full name (2 to 100 characters).
recipient.accountstringyesMobile number in international format, or bank account number.
recipient.countrystringyesISO 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.bankCodestringnoRequired 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.bankstringnoBank name (required for bank unless recipient.bankCode is sent).
markupPercentnumbernoYour own markup as a percentage of the amount (0 to 50). Reported in fees, never debited.
markupFixednumbernoYour own fixed markup in the request currency. Reported in fees, never debited.
referencestringnoYour own reference, 4 to 64 characters (letters, digits, - _ : .). Must be unique.
descriptionstringnoUp to 140 characters.
fundstringnoUse 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

StatuserrorMeaning
400idempotency_key_requiredSend an Idempotency-Key header.
400valid_amount_requiredamount must be a positive number.
400unsupported_currencycurrency must be one of USD, XAF, GHS, ZAR, NGN, RWF, UGX or KES.
402insufficient_fundsThe wallet balance is too low.
403limits_not_setNo live limit is enabled for this currency (Dashboard, Limits & safety).
422over_per_request_limitThe amount is above the per-request limit.
422over_daily_limitThe daily limit would be exceeded.
423money_movement_pausedThe kill switch is on.
409duplicate_referenceThat reference was already used.
409request_in_progressA request with the same Idempotency-Key is still running.
422idempotency_key_reusedThe Idempotency-Key was used with a different request.
400network_not_supportedDo not send a named mobile-money network.
422unsupported_payout_railThat bank or mobile-money rail is not supported in the requested country.
422payout_rejectedDutch API could not complete the payout; the amount was returned.

Related references

Browse the complete endpoint directory, the developer portal and the security and controls guide.