Concepts
Rate limits
Each key may make 120 calls a minute, the REST API and the MCP server together. Every answer says how many are left.
The limit
Each key may make 120 calls a minute. The REST API and the MCP server count in the same window, so an AI assistant and a sync sharing one key share its limit; give them a key each.
A sync that reads 500 attendees a page reads 60,000 attendees within the limit, so a well-made integration rarely meets it. A loop that asks for the same thing over and over meets it within a minute, which is what it is for.
Where you stand
Every answer, refusals included, carries the limit in two forms: the IETF's RateLimit headers and the X-RateLimit-* headers most client libraries read.
HTTP/1.1 200 OK
RateLimit-Policy: "default";q=120;w=60
RateLimit: "default";r=117;t=42
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 117
X-RateLimit-Reset: 42r (remaining) is the calls left in this window and t the seconds until a new window starts.
When you go over
The call is refused with 429 Too Many Requests, a Retry-After header in seconds, and a problem with "code": "rateLimited". Nothing was done: wait, then send it again. A refused call counts in the activity of keys, so you can see when it happened.
HTTP/1.1 429 Too Many Requests
Retry-After: 18
Content-Type: application/problem+json
{ "status": 429, "code": "rateLimited", "detail": "This key made more than 120 calls in a minute. Try again in 18 seconds; the RateLimit header says what is left." }Staying well within it
- Ask for big pages:
limit=500is fine. - Sync with
updatedSinceinstead of reading everything every time (Pagination and sync). - Use webhooks instead of polling for what just happened.
- Send
If-None-Matchwith the ETag you have: a304is quick, though it still counts. - Pause when
RateLimit'srgets low, rather than waiting to be refused.
The window is counted per server, so on a busy day a key may now and then get a little more than the limit. Do not build on that: treat the headers as the truth.