Skip to content
iSmartPay Developers
Esc
↑↓navigate↵open⌘Jpreview
On this page

Payout batches

Send up to 100 payouts in one request.

A batch sends many payouts in one call. Each item is an ordinary payout. It is accepted or refused on its own, so one refusal does not stop the others.

Send a batch

POST /v1/payout-batches
Idempotency-Key: payroll-2026-10
{
  "reference": "payroll-2026-10",
  "items": [
    {
      "reference": "payroll-2026-10-001",
      "amount": "450.00",
      "currency": "GHS",
      "provider": "mtn",
      "destination": { "type": "msisdn", "value": "233244123456" }
    },
    {
      "reference": "payroll-2026-10-002",
      "amount": "380.00",
      "currency": "GHS",
      "provider": "telecel",
      "destination": { "type": "msisdn", "value": "233201234567" }
    }
  ]
}
  • reference is yours, and unique for each batch.
  • items holds 1 to 100 payouts. Each has the same fields as POST /v1/payouts.
  • Each item’s reference must be unique within the batch, and is the payout’s own reference.

What comes back

If the batch itself is malformed, the whole batch is refused with 400 invalid_input and nothing is sent. That covers a missing reference, no items, more than 100 items, an invalid item, or a reference used twice in the batch. message names the item.

Otherwise you get 200, with one entry per item in the order you sent them:

{
  "batchId": "b2f1c7e4-5a1d-4c3e-9f0a-7d6b2e8c1a90",
  "reference": "payroll-2026-10",
  "items": [
    {
      "reference": "payroll-2026-10-001",
      "status": 202,
      "payout": {
        "reference": "payroll-2026-10-001",
        "amount": "450.00",
        "currency": "GHS",
        "status": "accepted",
        "provider": "mtn",
        "createdAt": "2026-10-05T09:00:00Z"
      }
    },
    {
      "reference": "payroll-2026-10-002",
      "status": 403,
      "error": {
        "code": "daily_limit_exceeded",
        "message": "daily limit exceeded"
      }
    }
  ]
}

The values above only show the shape.

  • status is 202 when the payout was accepted. It then carries the payout.
  • Any other status is the one a single payout would have been refused with. error has the same code, such as daily_limit_exceeded.

A 200 does not mean every payout went out. Check each item.

Limits

Your limits apply to each item as if it were sent alone. A batch cannot move more than the same payouts sent one by one. Check GET /v1/limits before a large batch.

Retrying

After a timeout or a 5xx, retry with the same Idempotency-Key and the same body. Accepted items are not sent again.

Following the payouts

There is no batch read. Read each payout with GET /v1/payouts/{reference}. Webhooks arrive for each payout (payout.accepted, payout.status_changed), not for the batch. See Webhooks.

Permissions

To The key needs
Send a batch disbursements.write
Read a payout disbursements.read

Errors

As well as the common errors:

Status Code What to do
400 invalid_input The batch is malformed and nothing was sent. Fix the item message names and send again.
409 idempotency_key_reused This key was used with a different body. Send the original body, or use a new key for a new batch.
409 request_in_flight The first request with this key is still running. Wait, then retry the same request.

Was this page helpful?