API rate limits
Three separate limits apply, one per surface: 240 requests a minute on the public API, 120 on the MCP endpoint and 60 on the A2A endpoint, each counted per calling address over a rolling sixty seconds. No rate-limit headers are sent — no Retry-After, no X-RateLimit-* — so a client must carry its own backoff.
The limits#
| Surface | Limit | Window | Response when exceeded |
|---|---|---|---|
/api/public/… | 240 requests | 60 seconds, rolling | HTTP 429, {"error": {"code": "rate_limited", …}} |
POST /mcp | 120 requests | 60 seconds, rolling | HTTP 429, JSON-RPC code -32603 |
POST /a2a | 60 requests | 60 seconds, rolling | HTTP 429, JSON-RPC code -32603 |
The public API's allowance is the most generous on purpose: these are cheap in-memory reads, and a documentation API that throttles a crawler into failure defeats what it is for. The limit is there to stop a loop, not to ration access. The A2A allowance is the smallest because one call there does more work — a skill searches, fetches and formats a page.
Counting is per calling address and the window slides: requests older than sixty seconds fall out of the count by themselves, so an allowance recovers gradually rather than resetting on a clock boundary. The counter lives in the serving process, which means it is not a global quota you can reason about across every instance — treat the number as the ceiling for a single well-behaved client, not as a budget to spend exactly.
The headers that are not there#
None of the three surfaces sends a rate-limit header. There is no Retry-After on a 429, no X-RateLimit-Limit, -Remaining or -Reset, and no RateLimit field of any kind. A client that reads one will read nothing, and a library that requires one to compute a delay will have to be given a default.
So the only signal you get is the 429 itself, plus the limit quoted in the message text. Do not parse the message: it is prose for a human reading a log. Configure the numbers from this page and treat a 429 as the instruction to wait.
Staying comfortably under#
- Cache on
updated. Every page carries a date that moves only when the page is regenerated, and successful public API responses ask you to cache for five minutes. - Fetch a manifest instead of a hundred pages.
/docs-manifest.jsonis every public page in one document;/docs-data/status.jsonis every capability's status. One request replaces a walk. - Search once, fetch once. The summary in a search result is the page's answer-first paragraph and often answers the question without a fetch at all.
- Widen the delay, and add jitter. Several clients that all wait exactly one second arrive together and re-trip the limit.
- Remember the address is shared. Everything behind one gateway shares a counter, so a fan-out design spends the allowance far faster than its per-worker rate suggests.
Other ceilings that are not rate limits#
- Request body size
- 256 KiB on
/mcpand 128 KiB on/a2a; over that the answer is413, immediately and regardless of your rate. - Result count
- Search returns at most 25 results however large a
limityou ask for; listing caps at 1,000 items. - Body length
- A fetched page body is capped at 60,000 characters, and an A2A skill truncates further — 6,000 or 8,000 characters depending on the skill.
- Argument bounds
qis 2–200 characters andrefat most 300; exceeding one is a validation failure, not a limit.
None of these move with usage or with an account, because there are no accounts. They are the same for every caller and they are the same on every request.
Questions#
Can I ask for a higher limit?
There is no mechanism to raise one, because there is no identity to raise it for. If a use case genuinely needs more than 240 documentation reads a minute, the static manifests are the right answer — they are one request and they contain the corpus.
Do the three limits share a counter?
No. Each surface counts its own requests, so a client using the public API and the MCP endpoint together has both allowances rather than one shared between them.
How do I know how much of the allowance I have left?
You cannot, from the response — nothing is reported back. Count on your own side if it matters, or design so it does not: a cache and a manifest fetch make the question moot.