Skip to main content
Limits are applied per endpoint class rather than as one global budget, so a burst of order placement cannot exhaust the allowance you need to sign in, and a scripted retry loop on one endpoint cannot lock you out of the rest of the API. Every limit below is enforced server-side and is not configurable per account.

What you get back

A throttled request returns 429 Too Many Requests. Identity endpoints tag the body with the error code identity.too_many_requests.
Several identity limits block for longer than the window they measure. Ten failed sign-in attempts in a minute does not free up after that minute — it blocks for five. Retrying at the window boundary re-arms the block; see Backing off.

Sign-in and account creation

Keyed per IP address, so these apply before anyone is authenticated. Note the asymmetry between requesting a code and submitting one: requesting is capped at 5/minute because each request sends an email, while submitting is capped at 10/minute with a longer block, because that endpoint is where a token would be brute-forced.

Two-factor and phone verification

Keyed per user, and enforced after authentication.
The 2FA budget is shared across all three sign-in paths — email, social and wallet. Alternating between them does not give you three separate allowances.
Sending an SMS costs money and reaching a real handset, so 3 per hour is deliberately tight. Build the “resend code” button to respect it: a user who taps resend three times in a minute is locked out of SMS for the rest of the hour.

Trading and wallet

Keyed per member. Order placement is the loosest limit on the API at two per second sustained, because it is the one endpoint where a legitimate client is genuinely fast. The relay limit is tighter than it looks because the operator pays the gas for every relayed transaction — it is a spend limit as much as a rate limit. The 5-per-hour class covers enrolment and one-off setup actions, which no correct client repeats in a loop.

Market data

Public market-data reads are not currently rate-limited, but they are cached — see the Cache-Control table in the API overview. Polling inside the TTL returns the same bytes and gains you nothing.
Do not treat “no limit today” as a guarantee. Use the WebSocket for anything live; it is both cheaper for you and the reason this endpoint class has not needed a limit.

Backing off

Retry with exponential backoff and jitter, and treat the block duration — not the measurement window — as your floor.
Three rules that matter more than the curve:
  • Add jitter. Without it, every client that failed together retries together, and the retry storm is worse than the original burst.
  • Never retry a 429 immediately, even once. On the endpoints with a block, an immediate retry lands inside the block and can extend it.
  • Do not retry a 422 at all. It is a validation failure; the same body will fail every time. Only 429, 5xx and network errors are worth retrying.

If you need more

Order placement at 120/minute is sized for a normal trading client. If you are building something that genuinely needs more — a market maker quoting across many markets — raise a support ticket at support.calibri.io/contact. Do not shard across accounts to get around a limit. That reads as abuse, and the outcome is every one of those accounts limited rather than one of them raised.