Rate limits
Reads and trading calls per second, by plan.
Your team has two budgets, refilled every second: one for reading, one for trading. They are separate, so a dashboard polling hard never stops a bot from closing a position.
| Plan | Reads per second | Read burst | Trading calls per second | Fastest stream | Live sessions | Idle timeout |
|---|---|---|---|---|---|---|
| Starter | 10 | 25 | 10 | 250 ms | 1 | 15 minutes |
| Trader | 30 | 75 | 10 | 100 ms | 3 | 1 hour |
| Prop | no limit | — | 10 | 100 ms | 10 | never |
Trading calls are placing, changing, cancelling and closing. Everything else is a read,
including checkOrder, marginFor and profitFor. The burst is how many reads you
may make at once after a quiet spell; after that you are held to the per-second rate.
The budgets belong to the team, not the key: a second key is a second bot sharing the same allowance. REST and the WebSocket draw on the same budgets.
Every REST response tells you where you stand:
X-RateLimit-Limit: 30
X-RateLimit-Remaining: 27
Over a budget you get 429 rate_limited with Retry-After in seconds (over the
WebSocket, the same code in error.data, with details.retryAfter). The SDKs wait and
retry for you.
Streams
A stream asked to update faster than your plan's fastest interval still works, at that interval. Ticks you subscribe to without an interval arrive at it too.
Idle timeout
An account with no requests for the idle timeout is disconnected, and the next request pays the 20–40 second connect again. A bot that trades in bursts may prefer a stream to keep its view current, rather than polling.
GET /v1/team returns your plan's real numbers, so your code does not have to hard-code this table.
Polling versus streaming
Placing orders is limited by your broker and stays fast under load. Reading data is not: polling prices or positions in a tight loop gets slower as the host gets busy, and burns your read budget. Subscribe instead: one connection, updates as they happen.