Using Payment Batches
This guide walks you through creating and processing a payment batch — grouping multiple payments into a single unit for rate-limited execution and a single completion notification.
What You'll Learn
- How to create a payment batch
- How to add payments to a batch
- How to submit a batch for processing
- How to monitor batch progress
- Handling failures and retries
Prerequisites
Before using payment batches:
- ✅ Company and entity created (see Setup Your Organization)
- ✅ Multi-currency feature enabled and ACTIVE (see Enable Multi-Currency)
- ✅ Funding account linked with active payment profile (see Connect Funding Accounts)
- ✅ At least one recipient created (see Add Your First Recipient)
- ✅ Familiar with single payments (see Make Your First Payment)
- ✅ A valid JWT token (see Authentication)
Understanding Payment Batches
Payment batches let you group up to 500 payments into a single unit. Instead of executing payments one by one, the batch processor handles rate limiting, quote refreshing, and error isolation automatically. When all payments complete, a single digest notification is sent — not one per payment.
When to Use Batches
- Payroll: Execute all salary payments in one batch
- Vendor disbursements: Pay multiple suppliers at once
- Recurring bulk payments: Monthly rent, subscription, or commission payments
- High-volume operations: Any scenario with more than a handful of payments
How It Works
Step 1: Create a Payment Batch
Create an empty batch that will hold your payment instructions.
curl -X POST "https://api.treasurypath.com/api/v1/companies/{company_id}/payment_batches" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{
"payment_batch": {
"idempotency_key": "payroll-2026-03",
"label": "March 2026 Payroll",
"metadata": {
"department": "engineering",
"period": "2026-03"
}
}
}'
Success Response (201 Created)
{
"data": {
"id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50QmF0Y2gvMQ",
"status": "building",
"label": "March 2026 Payroll",
"idempotency_key": "payroll-2026-03",
"total_count": 0,
"succeeded_count": 0,
"failed_count": 0,
"metadata": {
"department": "engineering",
"period": "2026-03"
},
"submitted_at": null,
"completed_at": null,
"created_at": "2026-03-15T10:00:00.000Z",
"updated_at": "2026-03-15T10:00:00.000Z"
}
}
Save the Batch ID
Copy the id from the response — you'll pass it as payment_batch_id when creating each payment.
Idempotency
If you send the same idempotency_key again, the existing batch is returned with a 200 OK instead of creating a duplicate. Use meaningful keys like "payroll-2026-03" or "vendor-disbursement-batch-42".
Step 2: Create Quotes and Add Payments
For each payment in the batch, create a quote and then a payment with the payment_batch_id set.
2a. Create a Quote
curl -X POST "https://api.treasurypath.com/api/v1/companies/{company_id}/quotes" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{
"quote": {
"from_profile_id": "{from_profile_id}",
"to_profile_id": "{to_profile_id}",
"instructed_amount": {
"amount": 5000.00,
"currency": "USD"
}
}
}'
2b. Add Payment to Batch
curl -X POST "https://api.treasurypath.com/api/v1/companies/{company_id}/payments" \
-H "Authorization: Bearer {jwt_token}" \
-H "Content-Type: application/json" \
-d '{
"payment_instruction": {
"payment_quote_id": "{quote_id}",
"reason": "wages_salary",
"idempotency_key": "payroll-2026-03-employee-101",
"credit_note": "March 2026 salary",
"payment_batch_id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50QmF0Y2gvMQ"
}
}'
Repeat steps 2a and 2b for each payment in the batch.
Batched Payments Are Not Executed Immediately
When payment_batch_id is set, the payment is held in the batch instead of being executed right away. Execution happens when you process the batch in Step 3.
Expired Quotes Are Refreshed Automatically
Don't worry if quotes expire before you process the batch. The batch processor automatically refreshes expired quotes during execution.
Batch Validation Errors
If the batch is full or not in building status:
{
"errors": [
{
"field": "payment_batch_id",
"message": "Payment batch has reached the maximum of 500 payments"
}
]
}
Step 3: Process the Batch
Once all payments have been added, submit the batch for processing.
curl -X POST "https://api.treasurypath.com/api/v1/companies/{company_id}/payment_batches/Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50QmF0Y2gvMQ/process_batch" \
-H "Authorization: Bearer {jwt_token}"
Success Response (202 Accepted)
{
"data": {
"id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50QmF0Y2gvMQ",
"status": "processing",
"label": "March 2026 Payroll",
"total_count": 25,
"succeeded_count": 0,
"failed_count": 0,
"submitted_at": "2026-03-15T11:00:00.000Z",
"completed_at": null
}
}
Processing Is Asynchronous
The 202 Accepted response means the batch has been queued for processing. Payments are executed in the background with rate-limited concurrency. Monitor progress via polling or webhooks.
Common Process Errors
| Status Code | Error | Cause |
|---|---|---|
| 422 | Batch is not in building status |
Batch was already processed or expired |
| 422 | Batch has no payment instructions |
No payments were added to the batch |
| 422 | Batch exceeds maximum of 500 payments |
Too many payments in the batch |
| 409 | Batch is already being processed |
Concurrent processing request |
Step 4: Monitor Batch Progress
Option A: Webhooks (Recommended)
When all payments in a batch finish processing, a PaymentBatchCompletedEvent webhook is sent:
{
"event": "PaymentBatchCompletedEvent",
"timestamp": "2026-03-15T11:05:30.000Z",
"company_id": "Z2lkOi8vYXBwL0NvbXBhbnkvMTIz",
"resource_id": "Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50QmF0Y2gvMQ",
"actor_id": null
}
Suppressed Individual Notifications
Individual payment webhooks (CompletedEvent, FailedEvent, DebitInitiatedEvent) are suppressed for batched payments. You receive only the batch-level notification.
Option B: Poll the Batch Status
curl -X GET "https://api.treasurypath.com/api/v1/companies/{company_id}/payment_batches/Z2lkOi8vd2FsbGV0LWFwcC9QYXltZW50QmF0Y2gvMQ" \
-H "Authorization: Bearer {jwt_token}"
Watch the succeeded_count and failed_count fields to track progress. The batch reaches a terminal status when all payments have been processed:
| Terminal Status | Meaning |
|---|---|
completed |
All payments succeeded |
completed_with_failures |
Some payments succeeded, some failed |
failed |
All payments failed |
Handling Failures
When a batch completes with completed_with_failures status, some payments failed while others succeeded. To identify which payments failed:
- List all payments for the batch by querying the payments endpoint
- Check individual payment statuses to find the failed ones
- Create a new batch with only the failed payments to retry
Failure Isolation
Each payment in a batch is processed independently. A single payment failure does not affect other payments in the batch.
Batch Expiry
Batches left in building status for more than 7 days are automatically expired by the system. Once expired, the batch cannot be processed.
To avoid expiry:
- ✅ Process batches promptly after adding all payments
- ✅ Use the
statusfilter on the list endpoint to find stale batches - ✅ Set up monitoring to alert on batches stuck in
buildingstatus
Best Practices
Batch Organization
- ✅ Use meaningful labels (e.g., "March 2026 Payroll", "Vendor Payments Q1")
- ✅ Use idempotency keys to prevent duplicate batches on retries
- ✅ Store metadata for your own tracking (department, period, run ID)
Payment Management
- ✅ Use unique idempotency keys per payment (e.g.,
"payroll-2026-03-employee-{id}") - ✅ Verify all recipients and profiles are active before creating the batch
- ✅ Keep batches under 500 payments — split larger sets into multiple batches
Error Handling
- ✅ Always check the
202 Acceptedresponse before assuming processing started - ✅ Handle
409 Conflictgracefully — it means a concurrent request is already processing - ✅ Implement retry logic for failed payments in a new batch
- ✅ Monitor batch completion via webhooks rather than polling
API Reference
For complete endpoint documentation, see:
- Payment Batches API Reference — Create, list, get, and process batches
- Payments API Reference — Create payments with
payment_batch_id - Webhooks — Set up webhook endpoints
Need Help?
- Check the FAQ for common questions
- Contact support at support@treasurypath.com