Reads are
GET. Writes are POST, PATCH and DELETE. The two quotas are independent —
exhausting your writes leaves reads working.
Headers
Every response carries your current standing, including errors:X-RateLimit-Reset is Unix time in seconds. On a 429 you also get:
Staying inside the limits
Use a separate key per integration
Use a separate key per integration
Quotas are per key, so an ATS sync and a nightly report export on separate keys can’t
starve each other. You can also revoke one without disturbing the other.
Poll on a schedule, not in a loop
Poll on a schedule, not in a loop
Grading takes minutes, not seconds. Polling a submission every few seconds burns quota
to no benefit — every 30–60 seconds is plenty, and only for submissions actually
awaiting a report.
Filter server-side
Filter server-side
GET /v1/submissions?assessment_id=…&status=evaluated&since=… costs one request.
Fetching everything and filtering in your code costs many, and gets worse as you grow.Be careful with the event log
Be careful with the event log
A busy attempt produces thousands of events, and a full walk at 500 per page can be
several requests for a single submission. Pull events only when you need the detail,
not as part of a routine sync.
Other limits
Not rate limits, but the other ceilings worth knowing:- Request body: 512 KB. Every documented body is well under a kilobyte; the headroom is
for a large
selected_task_idsarray. - Page size: 100 (500 for events). Over the max is a
400, not a silent clamp. - Active API keys: 20 per organization.
Limits are per key rather than per organization, so more keys means more total quota. That
is not a workaround to lean on — if you need materially more throughput, talk to us rather
than minting keys to farm quota.