Limit & Window
The API allows 600 requests per minute per API key, measured on a sliding window. The counter resets continuously as the window slides, not at a fixed clock boundary.The rate limit counter is tracked per API key, not per IP address or per
team. Two keys that belong to the same team each have their own independent
600 req/min budget.
429 Response
When you exceed the limit, the API responds immediately with HTTP429 and the following body:
429 — rate_limited response
Best Practices
Batch instead of looping
Batch instead of looping
The Batch where possible across all endpoints that support it.
POST /exams/{examId}/copies endpoint accepts up to 50 copies in a
single call. If you’re creating copies one by one in a loop, you’re
spending 50× more of your rate-limit budget than necessary.Batch copy creation — request body (abridged)
Exponential backoff on 429
Exponential backoff on 429
When you receive a A reasonable schedule: 1 s → 2 s → 4 s → 8 s → 16 s, with ±20 % jitter
applied to each value. Most backpressure clears within the first one or two
retries.
429, wait before retrying. Start with a 1-second delay
and double on each subsequent failure, adding random jitter to avoid
thundering-herd problems:Don't poll in tight loops
Don't poll in tight loops
AI correction is an asynchronous process that typically takes several
minutes per copy. Polling the Corrections endpoint every second burns your
rate-limit budget with no benefit.Poll at a 15–30 second interval instead. If your infrastructure
supports it, use webhook notifications to eliminate polling entirely and
receive results the moment they are ready.
Separate keys by use case
Separate keys by use case
Because each key has its own independent budget, you can prevent a burst of
write traffic from starving your read traffic by assigning different keys to
different workloads:
A bulk import job that hits its limit will not affect a concurrent dashboard
query running under a different key.
Request Logs
Every API call is logged server-side with the following details:- API key used (by name, not secret)
- HTTP method and path
- Response status code
- Response duration
- Error code (if applicable)
requestId values with entries in your own application logs.