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:

StatusDescription
VALIDATION_PENDINGYour request was received and is queued for validation.
VALIDATION_FAILEDOne or more records failed validation. Details delivered via webhook.
SCHEDULEDAll records passed validation and are queued for execution on their scheduled dates.
CANCELLEDYou cancelled the bulk request before processing began.
PROCESSING_IN_PROGRESSPayouts are being executed against providers.
PROCESSEDAll payout intents were created and executed. Success/failure details delivered via webhook.
INTENT_CREATION_FAILEDA 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_FAILED status, and you will be notified via webhook.


API reference summary

Bulk payout requests

MethodEndpointDescription
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

MethodEndpointDescription
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:

FieldRequiredDescription
labelYesA human-readable name for this bulk request (max 255 characters).
webhook_urlYesURL that receives status updates for the bulk request and all its items.
itemsYesArray of payout items to execute.
items[].merchant_referenceYesYour internal identifier for this item. Used to track status in webhook events and retrieve individual items.
items[].scheduled_dateNoISO 8601 date on which this item should execute. If omitted, the item executes as soon as it passes validation.
items[].payout_intent_detailsYesThe 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 the merchant_reference you 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_PROGRESS or 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 CANCELLED status.
  • No further actions can be taken on those records.
  • Failed intents from INTENT_CREATION_FAILED records 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

ParameterLimit
Records per bulk request1,000
Adding records to existing requestNot supported