Limits and quotas
Limits are enforced per API ID per route and class, with a five-times account aggregate. A daily quota applies to each call class. All counters are shared across API replicas, so a retry that lands on another node sees the same budget.
GET /v1/capabilities returns the live limit object. GET /v1/usage returns usage for
the current period. Response headers are the per-request source of truth.
Current limits
| Class | Sustained | Burst / aggregate | Daily quota |
|---|---|---|---|
| Capabilities, manifest, usage | 120/min | 5x account aggregate | 20,000 |
| Catalogue and offer reads | 120/min | 5x account aggregate | 20,000 |
| Quote creation | 60/min | 5x account aggregate | 2,000 |
| Order creation | 30/min | 5x account aggregate | 1,000 |
| Order reads | 120/min | 5x account aggregate | 20,000 |
| Redemption | 20/min | 5x account aggregate | 1,000 |
| Wallet funding | 5/min | 5x account aggregate | 20 |
| Agent and key management | 10/min | 5x account aggregate | 50 |
Windows are fixed and aligned to the clock: per-minute windows start at the top of each UTC minute, daily quotas reset at 00:00 UTC. A limit does not roll continuously.
POST /v1/quotes and POST /v1/orders share the same wallet and stock checks, but they
have separate counters. A quote that is rate limited creates no quote row. An order that is rate
limited creates no purchase and no debit.
Bulk limits
| Limit | Principal | Agent default |
|---|---|---|
| Lines per quote or order | 200 | 50 |
| Units per quote or order | 5,000 | 500 |
The principal limit is enforced by the current quote and order handlers. Agent-specific line and unit caps are recorded on the agent identity and are part of the target contract. Until order-time enforcement is enabled, an agent must enforce its own cap client-side and keep the principal's mandate explicit. See Agent payment.
Response headers
Every limited response includes:
Code
X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset carry the same
values for older clients. RateLimit-Reset is a Unix timestamp in seconds.
A 429 adds:
Code
Throttled responses
Code
A daily quota returns 429 quota_exceeded:
Code
Neither response creates a quote, order, redemption or funding operation.
Retry policy
- Read
Retry-After. If it is missing, use theresetvalue or a one-second start. - Wait at least that long. Add jitter of 10 to 30 percent to avoid synchronised retries.
- For a mutation, reuse the same
Idempotency-Keyand the same body. Never use a new key for a retry of the same logical request. - For a read, retry with a fresh nonce.
- Cap automatic retries at three for
429. If the limit persists, reduce concurrency instead of extending the retry loop. - On
500 internal_error, confirm whether the mutation had an effect before retrying. PollGET /v1/orders/{id}orGET /v1/walletfirst.
Retry-After is authoritative. Do not use a shorter fixed sleep.
Capacity planning
- Quote, order and redeem limits are intentionally lower than read limits. A batch integration should queue writes rather than fan them out.
- A single large order consumes one order-creation token but up to 5,000 units. It does not multiply the request count.
- Daily quotas are per credential and call class. Multiple keys under the same partner still consume the account aggregate.
- Use webhooks and
GET /v1/orders/{id}for status. Do not poll faster than the order-read limit.
Contract status
The limit table above matches the running v1 service and the values returned by
GET /v1/capabilities. The older five-language guide still contains a per-second limit
table; treat this page and the capabilities response as current. The quota_exceeded envelope is
served today. The agent default line and unit caps are part of the target agent contract and are
not enforced by the current order handler.
If a limit response seems wrong, capture X-Request-Id, RateLimit-Limit,
RateLimit-Remaining, RateLimit-Reset and the UTC time, then contact partner support.