Bulk Payout (Bulk Bank Transfer)
Process multiple bank transfers in a single API request. Ideal for batch payments like salaries, vendor payments, and commission disbursements across multiple recipients.
Endpoint
POST https://api.budpay.com/api/v2/bulk_bank_transferSample Request
curl https://api.budpay.com/api/v2/bulk_bank_transfer \
-H "Authorization: Bearer YOUR_SECRET_KEY" \
-H "Encryption: Signature_HMAC-SHA-512" \
-H "Content-Type: application/json" \
-d '{
"currency": "NGN",
"transfers": [
{
"amount": "200",
"bank_code": "000013",
"bank_name": "GUARANTY TRUST BANK",
"account_number": "0050883605",
"narration": "January Salary"
},
{
"amount": "100",
"bank_code": "000013",
"bank_name": "GUARANTY TRUST BANK",
"account_number": "0050883605",
"narration": "February Salary"
},
{
"amount": "100",
"bank_code": "000013",
"bank_name": "GUARANTY TRUST BANK",
"account_number": "0050883605",
"narration": "March Salary"
}
]
}' \
-X POSTSample Response
{
"success": true,
"message": "3 Transfers queued",
"data": [
{
"reference": "trf_j51m4695fk57nf",
"currency": "NGN",
"amount": "200",
"fee": "10",
"bank_code": "000013",
"bank_name": "GUARANTY TRUST BANK",
"account_number": "0050883605",
"account_name": "OYENIYI TOLULOPE OYEBIYI",
"narration": "January Salary",
"domain": "test",
"status": "pending",
"updated_at": "2022-03-30T00:03:12.000000Z",
"created_at": "2022-03-30T00:03:12.000000Z"
},
{
"reference": "trf_1h1x3v5400n612",
"currency": "NGN",
"amount": "100",
"fee": "10",
"bank_code": "000013",
"bank_name": "GUARANTY TRUST BANK",
"account_number": "0050883605",
"account_name": "OYENIYI TOLULOPE OYEBIYI",
"narration": "February Salary",
"domain": "test",
"status": "pending",
"updated_at": "2022-03-30T00:03:13.000000Z",
"created_at": "2022-03-30T00:03:13.000000Z"
},
{
"reference": "trf_f9098ac5272653",
"currency": "NGN",
"amount": "100",
"fee": "10",
"bank_code": "000013",
"bank_name": "GUARANTY TRUST BANK",
"account_number": "0050883605",
"account_name": "OYENIYI TOLULOPE OYEBIYI",
"narration": "March Salary",
"domain": "test",
"status": "pending",
"updated_at": "2022-03-30T00:03:13.000000Z",
"created_at": "2022-03-30T00:03:13.000000Z"
}
]
}Try it out
Request Parameters
Header Parameters
| Field Name | Description | Required |
|---|---|---|
| Authorization | Bearer token with your secret key | Yes |
| Encryption | Signature_HMAC-SHA-512 for request encryption | Yes |
| Content-Type | application/json | Yes |
Body Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
currency | String | Yes | Transfer currency: NGN, KES, or GHS |
transfers | Array | Yes | Array of transfer objects (see below) |
Transfer Object Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
amount | String | Yes | Transfer amount for this recipient |
bank_code | String | Yes | Bank code from bank list API |
bank_name | String | Yes | Bank name |
account_number | String | Yes | Recipient bank account number |
narration | String | Yes | Transfer description/purpose |
Response Fields
| Field | Type | Description |
|---|---|---|
success | Boolean | Indicates if bulk transfer was queued successfully |
message | String | Response message with number of transfers queued |
data | Array | Array of transfer objects with details |
Transfer Object Response Fields
| Field | Type | Description |
|---|---|---|
reference | String | Unique transfer reference ID |
currency | String | Transfer currency |
amount | String | Transfer amount |
fee | String | Transaction fee charged |
bank_code | String | Recipient bank code |
bank_name | String | Recipient bank name |
account_number | String | Recipient account number |
account_name | String | Verified account holder name |
narration | String | Transfer description |
domain | String | Environment: test or live |
status | String | Transfer status: pending, success, failed |
created_at | String | Transfer creation timestamp |
updated_at | String | Last update timestamp |
Transfer Status
| Status | Description |
|---|---|---|
| pending | Transfer queued and being processed |
| success | Transfer completed successfully |
| failed | Transfer failed (insufficient funds, invalid account, etc.) |
Error Handling
400 Bad Request
{
"success": false,
"message": "Invalid request parameters"
}401 Unauthorized
{
"success": false,
"message": "Authentication failed"
}422 Validation Error
{
"success": false,
"message": "Validation error",
"errors": {
"currency": ["The currency field is required"],
"transfers": ["The transfers field must be an array"]
}
}500 Server Error
{
"success": false,
"message": "Bulk transfer processing failed"
}Best Practices
Tip: Validate all account details before bulk transfers to prevent partial failures and ensure smooth processing.
- Validate Accounts: Verify all account details using account name validation before bulk transfer
- Batch Size: Keep batch sizes reasonable (recommended: 100-500 transfers per request)
- Track References: Store all reference IDs for individual transfer tracking
- Monitor Status: Use webhooks to track individual transfer completion
- Error Handling: Implement retry logic for failed transfers within the batch
- Balance Check: Ensure sufficient wallet balance for total batch amount plus fees
- Idempotency: Implement unique identifiers to prevent duplicate batch submissions
- Test First: Always test bulk transfers in sandbox with small batches
Bulk Transfer Workflow
Process Flow: Transfers are queued immediately and processed asynchronously. Each transfer receives a unique reference for tracking.
- Submit Batch: Send array of transfers in single API request
- Queue Confirmation: API returns immediately with all transfer references
- Async Processing: Transfers process independently in the background
- Status Updates: Each transfer updates individually (webhook notifications)
- Verification: Track each transfer using its unique reference
Security Considerations
Security: The Encryption header with HMAC-SHA-512 signature is required for all bulk transfer requests.
- HMAC Signature: Always include the
Encryption: Signature_HMAC-SHA-512header - Server-Side Only: Never expose secret keys in frontend code
- HTTPS Only: All requests must use secure HTTPS connections
- Validate Webhooks: Verify webhook signatures before processing status updates
- Audit Logs: Maintain detailed logs of all bulk transfer requests
- Data Privacy: Never log or store sensitive account details in plain text
Next Steps
- Single Payout - Process individual bank transfers
- Account Name Validation - Verify accounts before transfer
- Bank List - Get supported banks for each currency
- Transaction Verification - Verify individual transfer status
- Webhooks - Set up real-time status notifications