Mass payment API: limits, retries, and idempotency
September 17, 2026

A mass payment API is an endpoint your own system calls to pay a long recipient list without anyone opening a dashboard. What the endpoint accepts differs by provider. Some providers accept a whole recipient list in a single call. EukaPay's Payout API creates one payout per request, so a mass payment on EukaPay is either a loop your code runs against that endpoint, or a CSV upload in the merchant dashboard.
EukaPay ships both routes on the same account, and the choice between them is not really about how many people you pay. It is about what your code has to do when a request does not come back. This guide covers the limits that shape a EukaPay payout loop, the idempotency key that makes a retry safe, and the webhooks that tell your system what happened.
In this guide, you'll learn:
What a mass payment API is, and what one EukaPay Payout API request creates
Which limits shape a payout loop, including cursor pagination and the 429 response
How the x-idempotent-key header lets you retry a payout request without paying twice
Which identifiers and webhooks tell your system whether a payout was sent
What a mass payment API is, and what one request creates
The term covers two different shapes of endpoint, and the difference decides how much work your integration carries. One shape takes a recipient list and creates the payouts for you. The other takes a single destination and creates one payout, leaving the sequencing to the caller.
One payout per request - the unit EukaPay's Payout API works in
With EukaPay, one request creates one payout. The request carries the destination, the amount, the asset, and the network. Asset and network are set per payout, so one recipient can be paid in USDC on Ethereum and the next in USDT on Tron. Payouts are sent in USDC, USDT, ETH, and BTC, on Ethereum, Tron, and Bitcoin.
That unit is the thing to design around. A loop over your own recipient table gives you the failure handling, the ordering, and the logging, because all three sit in your code, not in ours. For the wider shape of the endpoint, read our guide to
what a payout API sends and what it returns
.
The CSV upload in the merchant dashboard - the no-code route for a recipient list
Paying a whole recipient list at once is a separate route. You upload the list as a CSV file in the merchant dashboard, and it needs no code. A company can use the file for the regular cycle and the endpoint for individual payout requests in between.
Does a mass payment API pay more than one recipient in one request?
With EukaPay, no. The Payout API creates one payout per request, and there is no endpoint that accepts a list of recipients. Scope the integration around that unit before your developer (or coding agent) writes the loop. Code written on the assumption that the endpoint takes a list of people has to be rewritten later.
The practical effect is smaller than it sounds. Your system already holds the recipient table, the amounts, and the trigger, so it is already the thing deciding who gets paid. What it gains is a per-request result instead of a single result for the whole list. For the recurring version of this work, see
how to automate crypto payouts through the API
.
Mass payment API limits: the payout balance, cursor pagination, and the 429 response
The limits that shape a payout loop on EukaPay are not discovered by reading the payout endpoint alone.
Funding the payout balance - the transfer that happens before the loop starts
Fund the payout balance before you create payouts. You do that by transferring from the account's main balance, which is a documented step of its own. Treat it as step one of the run, not something the loop handles.
Cursor pagination on reads - limit, starting_after, and ending_before
Reads are cursor-based. The API accepts a limit parameter, which defaults to 100 records, plus either starting_after or ending_before. The two cursor parameters are mutually exclusive, so a request may carry one of them and not both. Responses come back with a data array and a has_more boolean, which is what your pagination loop should check instead of counting records yourself.
429 Too Many Requests - exponential backoff is the documented response
EukaPay returns conventional HTTP status codes. A 429 means too many requests arrived too quickly, and the documented guidance is an exponential backoff on your side. A 402 means the parameters were valid but the request failed, and a 409 means the request conflicts with another request. Error responses carry a statusCode, a message, and a type, where the type is api_error, idempotency_error, or invalid_request_error.
Idempotency: the x-idempotent-key header that makes a retried payout request safe
A payout loop fails in the middle sometimes. The connection drops after the request left your server and before the response came back, and your code cannot tell whether the payout was created. Retrying blind can pay someone twice. That is the problem idempotency keys exist for.
Generating the key - one unique value per payout line
Send an x-idempotent-key header on the request. The key is a value your client generates. It has to be unique per payout, and EukaPay suggests V4 UUIDs. Keys can be up to 255 characters long. Sending one on every POST and PUT request is the recommended pattern, and it is unnecessary on GET and DELETE, which are idempotent by definition.
Derive the key from your own record instead of generating a fresh one on each attempt. A key tied to the commission line or the payout row means the retry carries the same key the first attempt did, which is the whole point.
The 24-hour window - what a stored key still answers for
EukaPay stores the request body and the resulting status code against the key, whether the request succeeded or failed. A later request with the same key returns that same result instead of creating a second payout. Stored keys become eligible for automatic removal once they are 24 hours old, so a key is a retry mechanism for a run in progress and not a permanent deduplication record. Your own ledger is where the permanent record belongs.
Retries and status: request IDs, error types, and crypto payout webhooks
An idempotency key makes a retry safe. It does not tell you what happened, and a payout loop needs both.
x-request-id - the identifier your logs and support share
Every API response carries an x-request-id header. Your request history is also available in the merchant dashboard under Integration Logs. Store the request id against the payout line your loop was working on, so a support ticket starts from an identifier instead of a timestamp. Each payout also has its own reference that can be looked up, and that reference is what your accounting records should carry.
cryptoPayoutSent and cryptoPayoutError - status arriving without polling
EukaPay sends webhooks as HTTPS POST requests to a URL you set in Settings, Integrations, Webhooks. Four of the event types cover payouts. cryptoPayoutCreated fires when the request is created, and cryptoPayoutSent fires once the payout has been broadcast to the blockchain network. cryptoPayoutError fires when something goes wrong, and cryptoPayoutRevoked fires when a created payout is canceled before it is processed. The cryptoPayoutSent payload carries the transaction hash, which is what your reconciliation can match on.
If a delivery fails, EukaPay retries the event every 20 minutes for up to 2 hours before removing it from the retry queue. Verify the sender before you act on a payload: compute an HMAC SHA-512 hex digest over the raw body with your secret key, and compare it against the x-eukapay-signature header.
How to choose
Payout API loop | CSV upload in the merchant dashboard | |
|---|---|---|
Who sends it? | Your own system | A person in the merchant dashboard |
What one action creates | One payout | Payouts for a recipient list in one file |
Coding required? | Yes | No |
Typical user | Platforms paying recipients on their own trigger | Finance teams running a periodic payout run |
Build the loop if the payout is triggered by something your software already knows about, such as a commission clearing a holding period or a creator crossing an earnings threshold. Use the file when a person decides the run. Choosing one now does not lock you out of the other, because both sit on the same EukaPay account. If you are still deciding how the run itself should work, read our guide to
mass payments and how a payment run works
, and for the vendor-category view,
mass payment solutions compared
.
One platform for crypto pay-ins, payouts, and fiat settlement
The Payout API sits on the same EukaPay account as the collection side, so money in and money out share one integration and one set of records. That account gives you instant crypto-to-fiat conversion at a locked exchange rate to remove your exposure to crypto price swings, support for most major cryptocurrencies, and settlement in USD, EUR, GBP, and CAD to your bank account. The locked rate is applied on every conversion by default, on pay-ins and on payouts. A crypto payment confirms on-chain, so protection against chargebacks is a property of the payment method.
Payouts created through the API are not tied to banking hours or the banking calendar. For a platform paying recipients across many markets, that is the argument for moving the run into code: your software sets the schedule, and the correspondent banking chain does not.
Get started with EukaPay
Create an account at
, complete verification, provide your legal business information, then generate an API key. The endpoint reference for payouts, balance transfer, invoices, subscriptions, and customers lives at
, and the
covers the dashboard side. Build the error handling against the staging environment first, as we describe in
testing payments in a sandbox before going live
. For the wider setup, see
how EukaPay's API integration works for developers
.
Frequently asked questions
What is a mass payment API?
A mass payment API is an endpoint your own system calls to pay a long recipient list without anyone working in a dashboard. What one request covers differs by provider. EukaPay's Payout API creates one payout per request.
Can one mass payment API request pay a whole recipient list?
Not with EukaPay. The Payout API creates one payout per request, and there is no endpoint that accepts a list of recipients. To pay a list at once, upload it as a CSV file in the merchant dashboard.
How do I retry a payout request without paying twice?
Send an x-idempotent-key header with a unique value per payout, and reuse that same value on the retry. EukaPay stores the request body and the status code against the key, so the retry returns the original result.
How long does an idempotency key last?
Stored keys become eligible for automatic removal once they are 24 hours old. Treat the key as a retry mechanism for a run in progress, and keep the permanent record in your own ledger.
What does a 429 response from the API mean?
It means too many requests arrived too quickly. The documented guidance is an exponential backoff on your side before the request is sent again.
Which cryptocurrencies can EukaPay's Payout API send?
USDC, USDT, ETH, and BTC, on Ethereum, Tron, and Bitcoin. The asset and network are set per payout, so different recipients can receive different assets.
How does my system find out whether a payout was sent?
Through webhooks. cryptoPayoutSent fires when a payout has been broadcast to the blockchain network and carries the transaction hash, and cryptoPayoutError fires when something goes wrong.
Do I need the API to pay a large recipient list at all?
No. A CSV upload in the merchant dashboard needs no code, and the API can be added later without changing accounts.
Related articles
Payout API: what one request sends and what comes back
- the endpoint surface behind a mass payment loop.
Mass payments and how a payment run works
- what a payment run is, and the steps one moves through.
Crypto mass payouts for contractors and affiliates
- paying a large recipient list on a recurring cycle.
Products
Use Cases
© 2026 EukaPay. All rights reserved.
FINTRAC: M22233887