Rate limits
How the API limits inbound request rate, the RATE_LIMITED response, and how to back off.
The API enforces a ceiling on inbound request rate. A caller that exceeds the
allowed rate is rejected with the RATE_LIMITED error and MUST back off before
retrying. This page states how limiting is applied, what a rejected request looks
like, and the backoff a well-behaved client follows.
How limiting is applied
Inbound rate is measured across three independent dimensions. A request is admitted only when every dimension that applies to it is under its ceiling; crossing any one of them rejects the request.
| Dimension | Applies to | Protects against |
|---|---|---|
| Per credential | Every authenticated request, keyed to the calling credential. | One credential issuing requests faster than allowed, from any source. |
| Per merchant | Every request attributable to a single merchant_id. | The combined traffic of all credentials acting on one merchant monopolising the surface. |
| Per source IP | Every request, authenticated or not. The only ceiling on tokenless surfaces (hosted checkout, public Proof-of-Payment reads). | Unauthenticated floods from a single origin. |
A request that is denied by one dimension does not consume quota on the dimensions it did not exceed. Limiting is global to the API — it is not scoped to a single endpoint, and read and command endpoints share the same dimensions.
When a limit is exceeded
A rejected request returns the standard error envelope
with HTTP status 429 and error.code RATE_LIMITED:
{
"ok": false,
"data": null,
"error": {
"code": "RATE_LIMITED",
"message": "Rate limit exceeded; retry after the indicated interval",
"details": null
},
"meta": { "result_type": "error" }
}The response carries a Retry-After header whose value is the number of
whole seconds to wait before retrying:
HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/jsonRetry-Afteris the soonest a retry can be admitted. When more than one dimension is exceeded, it reflects the longest of their waits.- Branch on
okfirst, then onerror.code— never on the HTTP status alone. See Errors. - The response body does not disclose which dimension was exceeded or the
configured ceiling. Use
Retry-Afterto pace retries; do not infer limits from the response.
Backing off
Always honour Retry-After. Retrying before it elapses will be rejected again and
counts against the per-source-IP ceiling.
A well-behaved client:
- Waits for
Retry-Afterbefore the first retry of a rejected request. - Applies exponential backoff with jitter if a retry is itself rejected — double the base wait each attempt and add a random offset so concurrent clients do not retry in lockstep.
- Caps total retries and surfaces a durable failure rather than retrying indefinitely.
- Carries an
idempotency_keyon retried commands where the endpoint offers one, so a retry after a429cannot create a duplicate resource. See Idempotency.
Reads are naturally repeatable and may simply be re-issued after the indicated
wait. Smoothing request rate on the client — rather than bursting and absorbing
429s — is the reliable way to stay under the ceilings.
Ceilings and windows
Each dimension admits a fixed number of requests per rolling window. The values below are the defaults the API enforces out of the box:
| Dimension | Ceiling | Window |
|---|---|---|
| Per credential | 600 requests | 60 seconds |
| Per merchant | 1,200 requests | 60 seconds |
| Per source IP | 300 requests | 60 seconds |
These ceilings are tunable per deployment. A managed or dedicated environment may
be provisioned with different values to match its expected traffic — if your
environment has been tuned, contact support for its exact limits. The
RATE_LIMITED response and the Retry-After contract above are identical
regardless of the configured numbers, so a client that paces off Retry-After
stays correct even where the ceilings differ.
Pace your client off Retry-After, not off these numbers. The header always
reflects the limits actually in force for the environment you are calling.
Adjacent limits
Two related limits are referenced elsewhere in this documentation and are collected here.
Idempotency
- Deduplication window — 24 hours. Within 24 hours of first use, a repeated
idempotency_key(same merchant, same key) replays the original result under the rules in Idempotency. After the window, the same key may create a new resource. - Key length. An
idempotency_keyis an opaque string and the API does not enforce a fixed maximum length. Use a compact, collision-free token — a UUID or your own order identifier is ideal.
Pagination
The collection limit parameter applies to paginated endpoints. Endpoints that do not paginate return all matching results in a single response. See Pagination and filtering.