Idempotent Requests

Rate Limits, Retries, and Idempotency

The MassPay API supports idempotency so you can safely retry requests without
accidentally performing the same operation twice. This is useful when an API call is
disrupted in transit and you do not receive a response. For example, if a request to
create a payout does not respond due to a network connection error, you can retry the
request with the same idempotency key and be guaranteed that no more than one payout is
created.


Rate limits

EnvironmentLimit
Sandbox100 requests / second
Production1,000 requests / second

Limits are applied per account, not per credential, IP address, endpoint, or user.
All credentials belonging to the same account draw from the same budget, so distributing
traffic across multiple API keys or source IPs will not increase your throughput.

Throttling responses

StatusMeaningRetry?
429 Too Many RequestsRate limit exceededYes — back off, then retry
500 / 502 / 503 / 504Server-side or transient failureYes — with an idempotency key
4xx (other)Request problem (validation, auth, permissions)No — fix the request first

429 is the only status code that indicates throttling.


Retry strategy

MassPay does not require a specific backoff algorithm. We recommend exponential backoff
with jitter
: wait roughly 1s, 2s, 4s, 8s, 16s between attempts, plus a small random
offset so that retries from many clients do not arrive in lockstep. Cap the number of
attempts (5 is a reasonable default) and surface a failure to your own system rather than
retrying indefinitely.

Always send an idempotency key on retried write requests. With a key attached, a retry is
safe on every endpoint — there are no endpoints where automatic retries must be
avoided. Without a key, a retry after a timeout may create a duplicate operation, because
your original request may have succeeded even though you never received the response.


Idempotency

Which endpoints support it

All endpoints accept the Idempotency-Key header. It is most meaningful on write
operations (POST, PUT, PATCH, DELETE) — including payout initiate and commit —
since reads are naturally idempotent.

Making an idempotent request

Provide an additional header on the request:

Idempotency-Key: 8f14e45f-ea0d-4a1b-9d1c-2c1b6a7f9e33

An idempotency key is a unique value generated by the client that the server uses to
recognize subsequent retries of the same request. How you create unique keys is up to you,
but we suggest V4 UUIDs, or another random string with enough entropy to avoid collisions.

Generate the key once, before the first attempt, and reuse that same value for every
retry of that operation. Generating a new key per attempt defeats the purpose.

How it works

MassPay saves the resulting status code and response body of the first request made for
any given idempotency key, regardless of whether it succeeded or failed. Subsequent
requests with the same key return that same saved result — including 500 errors.

Reusing a key

With the same request data: the original saved response is replayed, including its
original status code. The response carries an Idempotency-Key header echoing the key so
you can confirm you received a replayed result rather than a freshly executed one.

With different request data: the request is rejected. The idempotency layer compares
the incoming parameters, body, and URL against the original request and errors unless they
match, to prevent accidental misuse.

{"reason":"Parameters, body or url does not match for the same idempotency-key"}

Retention

Idempotency records are retained for 24 hours. After that, the key expires and a
reused key is treated as a brand-new request that will execute normally. Do not rely on a
key to deduplicate an operation more than 24 hours after the first attempt.

When no result is saved

Results are only saved if an API endpoint started executing. No idempotent result is
recorded when:

  • Incoming parameters failed validation.
  • The request conflicted with another request executing concurrently under the same key.

These requests are safe to retry — nothing was persisted and no operation was performed.


Putting it together

  1. Generate one idempotency key per logical operation, before the first attempt.
  2. Send it on the request as Idempotency-Key.
  3. On a 429 or 5xx, or on a timeout with no response, retry the same request with
    the same key, using exponential backoff with jitter.
  4. Treat a response bearing the Idempotency-Key header as a replay of your earlier
    attempt — the operation was already performed and was not duplicated.
  5. On {"reason":"Parameters, body or url does not match for the same idempotency-key"},
    stop and inspect your client: you have reused a key for a different operation.