Bulk Payouts
Send funds to hundreds of recipients at once — no per-recipient API calls, no manual data entry, no embed UI required. Bulk Payouts lets you submit up to 1,000 payouts in a single request and lets MoneyHash handle scheduling, validation, and execution automatically.
When to use Bulk Payouts vs. individual Payouts
Use a single Payout Intent when you need a customer-facing embed experience or full per-payout control. Use Bulk Payouts when you need to disburse to many recipients programmatically — payroll runs, affiliate commissions, marketplace settlements, and similar batch workflows.
How it works
Each bulk request goes through four distinct stages before money moves.
What each status means:
| Status | Description |
|---|---|
VALIDATION_PENDING | Your request was received and is queued for validation. |
VALIDATION_FAILED | One or more records failed validation. Details delivered via webhook. |
SCHEDULED | All records passed validation and are queued for execution on their scheduled dates. |
CANCELLED | You cancelled the bulk request before processing began. |
PROCESSING_IN_PROGRESS | Payouts are being executed against providers. |
PROCESSED | All payout intents were created and executed. Success/failure details delivered via webhook. |
INTENT_CREATION_FAILED | A payout could not be executed — typically due to missing routing or provider configuration. |
Each payout in a bulk request is independent. A validation failure or processing failure on one record does not affect other records in the same request.
Prerequisites
Before submitting a bulk payout request, make sure each recipient has:
- A valid
customer_id - Complete billing information — full name, phone, email, and billing address. This is required by most payout providers and must be collected upfront. Payouts without complete billing data will fail validation.
- A specified payout method — bank account, card, mobile wallet, or mobile money. Without a method, execution cannot proceed.
Missing information = validation failure. Both the payout method and customer billing data are mandatory for each record. Records missing either will move to
VALIDATION_FAILEDstatus, and you will be notified via webhook.
API reference summary
Bulk payout requests
| Method | Endpoint | Description |
|---|---|---|
POST | /api/v1.4/payout/bulk/requests/ | Create a bulk payout request |
GET | /api/v1.4/payout/bulk/requests/ | List all bulk payout requests |
GET | /api/v1.4/payout/bulk/requests/{id}/ | Retrieve a single bulk payout request |
POST | /api/v1.4/payout/bulk/requests/{id}/cancel/ | Cancel a bulk payout request |
Bulk payout request items
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1.4/payout/bulk/requests/{id}/items/ | List all items in a bulk payout request |
GET | /api/v1.4/payout/bulk/requests/{request_id}/items/ {merchant_reference}/ | Retrieve a single item |
POST | /api/v1.4/payout/bulk/requests/{request_id}/items/ {merchant_reference}/cancel/ | Cancel a single item |
For complete parameter documentation, see the API Reference — Bulk Payouts.
Creating a bulk payout request
POST /api/v1.4/payout/bulk/requests/
Submit a labeled bulk request with an array of payout items. Each item requires a unique reference, an optional scheduled date, and a payout_intent_details object that mirrors the Create payout intent request body.
{
"label": "June payroll run",
"webhook_url": "https://yourapp.com/webhooks/bulk-payout",
"items": [
{
"merchant_reference": "1234567890",
"scheduled_date": "2026-07-01",
"payout_intent_details": {
"payout_method": "BANK_ACCOUNT",
"amount": 500,
"amount_currency": "NGN",
"webhook_url": "https://yourapp.com/webhooks/bulk-payout-item1",
"customer": "8c91204b-5a5b-4496-9904-76a6b72bc15d"
}
}
]
}
Key fields:
| Field | Required | Description |
|---|---|---|
label | Yes | A human-readable name for this bulk request (max 255 characters). |
webhook_url | Yes | URL that receives status updates for the bulk request and all its items. |
items | Yes | Array of payout items to execute. |
items[].merchant_reference | Yes | Your internal identifier for this item. Used to track status in webhook events and retrieve individual items. |
items[].scheduled_date | No | ISO 8601 date on which this item should execute. If omitted, the item executes as soon as it passes validation. |
items[].payout_intent_details | Yes | The payout intent payload for this item. Accepts the same fields as the Create payout intent endpoint — including amount, amount_currency, payout_method, customer, and webhook_url. |
After submission, the bulk request is immediately assigned an id and each item moves to VALIDATION_PENDING.
Monitoring status
Because bulk payouts are processed asynchronously, you have two options for tracking progress:
1. Webhooks (recommended)
MoneyHash sends a webhook to the webhook_url you specified when:
- Validation completes — success or failure
- A payout intent is executed — success or failure
- A payout intent fails to be created
Each webhook payload includes themerchant_referenceyou provided, allowing you to map events back to your internal records.
See Webhooks and Webhook Types for payload structure and event types.
2. Polling
Retrieve the bulk request details and item status counts:
GET /api/v1.4/payout/bulk/requests/{id}/
The response includes fields like validation_pending_items_count, scheduled_items_count, validation_failed_items_count, and intent_creation_failed_items_count — giving you a high-level picture of where your items stand.
To inspect individual item statuses, use the items list endpoint:
GET /api/v1.4/payout/bulk/requests/{id}/items/
Cancelling individual items
You can cancel a single item within a bulk request without cancelling the entire request.
POST /api/v1.4/payout/bulk/requests/{request_id}/items/{merchant_reference}/cancel/
Rules:
- The item must not yet be in
PROCESSING_IN_PROGRESSor a terminal state. - Cancelling an item does not affect other items in the same request.
- Once cancelled, the item cannot be reactivated — submit a new bulk request to retry it.
Cancelling a bulk payout request
POST /api/v1.4/payout/bulk/requests/{id}/cancel/
Cancels all payouts in the request that have not yet entered PROCESSING_IN_PROGRESS. Records already in processing are not affected.
After cancellation:
- All eligible records move to
CANCELLEDstatus. - No further actions can be taken on those records.
- Failed intents from
INTENT_CREATION_FAILEDrecords can be retried in a new bulk request.
Handling failures
Two types of failures can occur:
Validation failures (VALIDATION_FAILED)
Triggered before any money moves. Caused by missing or invalid data — incomplete billing information, unsupported payout method, or an invalid customer. Cancel the affected items and resubmit them in a new bulk request with corrected data.
Intent creation failures (INTENT_CREATION_FAILED)
Triggered during execution. Caused by routing misconfiguration, provider unavailability, or unsupported payout method for the target currency/country. These records need to be recreated in a new bulk payout request after the underlying issue is resolved.
Limits
| Parameter | Limit |
|---|---|
| Records per bulk request | 1,000 |
| Adding records to existing request | Not supported |
Updated 5 days ago