Bulk Transfer
Process multiple transfers in a single API call. Maximum 100 transfers per request.
POST /v1/virtual-account/bulk-transfer
Headers
| Header | Required | Description |
|---|---|---|
X-Api-Key |
Yes | Your API key |
X-Idempotency-Key |
Yes | Unique key to prevent duplicate batch submissions |
Content-Type |
Yes | application/json |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
transfers |
array | Yes | Array of transfer objects (max 100) |
Transfer Object
| Field | Type | Required | Description |
|---|---|---|---|
currency |
string | Yes | Currency: NGN or GHS |
accountId |
integer | Yes | Source virtual account ID |
amount |
number | Yes | Amount to transfer |
destinationBankCode |
string | Yes | Destination bank code |
destinationAccountNumber |
string | Yes | Destination account number |
destinationAccountName |
string | Yes | Destination account name |
description |
string | No | Transfer description |
externalReference |
string | No | Your unique reference for this transfer. Must be unique per account. |
External Reference Uniqueness
The externalReference field must be unique per account. Validation will fail if:
- The same external reference is used multiple times within the batch for the same account
- The external reference already exists for a previous transfer from the same account
Example Request
curl -X POST "https://api.esca.finance/v1/virtual-account/bulk-transfer" \
-H "X-Api-Key: your_api_key_here" \
-H "X-Idempotency-Key: bulk-550e8400-e29b-41d4-a716-446655440000" \
-H "Content-Type: application/json" \
-d '{
"transfers": [
{
"currency": "NGN",
"accountId": 12345,
"amount": 10000,
"destinationBankCode": "000007",
"destinationAccountNumber": "0123456789",
"destinationAccountName": "JOHN DOE",
"description": "Salary payment",
"externalReference": "SAL-001"
},
{
"currency": "NGN",
"accountId": 12345,
"amount": 15000,
"destinationBankCode": "058",
"destinationAccountNumber": "9876543210",
"destinationAccountName": "JANE SMITH",
"description": "Salary payment",
"externalReference": "SAL-002"
}
]
}'
Example Response
{
"status": true,
"data": {
"batchId": "api-1705574400000-12345",
"transferCount": 2
}
}
Account Verification
Before processing, the API automatically verifies each destination account.
Verification Error Examples
Account not found:
{
"statusCode": 400,
"status": false,
"message": "Validation failed for 1 of 5 transfers",
"summary": {
"total": 5,
"successful": 4,
"failed": 1
},
"errors": [
{
"index": 2,
"reference": "SAL-003",
"errors": [
{
"code": "ACCOUNT_VERIFICATION_FAILED",
"field": "destinationAccountNumber",
"message": "Could not verify destination account. Please check the bank code and account number.",
"value": "0000000000"
}
]
}
]
}
Name mismatch:
{
"statusCode": 400,
"status": false,
"message": "Validation failed for 1 of 5 transfers",
"summary": {
"total": 5,
"successful": 4,
"failed": 1
},
"errors": [
{
"index": 0,
"reference": "SAL-001",
"errors": [
{
"code": "ACCOUNT_NAME_MISMATCH",
"field": "destinationAccountName",
"message": "Account name mismatch. Resolved: 'JOHN ADEBAYO DOE', Provided: 'JANE DOE'",
"value": "JANE DOE"
}
]
}
]
}
Tip: Use the Account Query endpoint to verify account details before initiating a bulk transfer.
Validation Errors
If any transfer fails validation, the entire batch is rejected with details about each failed transfer:
{
"statusCode": 400,
"status": false,
"message": "Validation failed for 1 of 2 transfers",
"summary": {
"total": 2,
"successful": 1,
"failed": 1
},
"errors": [
{
"index": 1,
"reference": "SAL-001",
"errors": [
{
"code": "DUPLICATE_EXTERNAL_REFERENCE",
"field": "externalReference",
"message": "A transfer with external reference 'SAL-001' already exists for this account.",
"value": "SAL-001"
}
]
}
]
}
Error Codes
| Code | Description |
|---|---|
INVALID_ACCOUNT |
Source account not found or doesn't belong to this business |
CURRENCY_MISMATCH |
Transfer currency doesn't match account currency |
INVALID_AMOUNT |
Amount must be a positive number |
INVALID_ACCOUNT_NUMBER |
Account number must be 10-15 digits |
MISSING_ACCOUNT_NAME |
Destination account name is required |
DUPLICATE_TRANSFER |
Possible duplicate within the batch |
DUPLICATE_EXTERNAL_REFERENCE |
External reference already exists for this account |
ACCOUNT_VERIFICATION_FAILED |
Destination account could not be verified against the bank |
ACCOUNT_NAME_MISMATCH |
Provided account name does not match the bank-resolved name |