Manage rate limits
01In a nutshell #sec_56b85c74
Three independent counters govern the rate — data, evidence, tokens — and some calls consume two at once.
02The three limits #sec_0a236919
| Counter | Default limit | What it counts |
|---|---|---|
| Standard | 600 per minute | All API calls |
| Evidence | 60 per minute | Calls to evidence, in addition to the standard |
| Tokens | 60 per minute | Calls to /connect/token |
These are default values, not constants: your subscription may have a raised limit. A raise granted by the publisher takes effect with the next request, without restart or propagation delay.
03The evidence counter adds up, it doesn't replace #sec_4b9c7978
This is the most surprising point. A call to evidence decrements both counters: the evidence one and the standard one. A client that only makes evidence calls would therefore be stopped at sixty per minute, not six hundred.
The reason is measurable: each evidence call produces a PDF and signs it, which takes about 325 ms of CPU and cryptography. At the common limit, a single client would have consumed nearly 40% of the machine; at sixty per minute, about 4%. The separate limit exists so that the slowness of one integrator does not become everyone's slowness.
04What is counted, and for whom #sec_f6c8dcbb
The counter is attached to the authenticated client, not to the IP address. Two processes that share a client_id share its limit, wherever they run; two distinct clients on the same machine each have their own.
The token call point is an exception before authentication: having no client yet, it counts by IP address.
Practical consequence: if several integrations must live side by side, give each its own client rather than sharing a secret. They will stop interfering with each other, and an overrun will designate the culprit.
05The refusal #sec_7af04e67
An overrun returns 429 Too Many Requests, with a Retry-After header and an application/problem+json body.
HTTP/1.1 429 Too Many Requests
Retry-After: 60
{
"type": "https://docs.reviewit.example/problems/rate-limit",
"title": "Too many requests",
"status": 429,
"detail": "The rate limit for this client has been exceeded. Retry after the indicated delay.",
"instance": "/api/v1/evidence/4821"
}
instance carries the refused path: on an integration that calls several domains, this field indicates which one has exceeded.
06Retry #sec_41e4809f
The limit is a fixed one-minute window, not a smoothed rate. The counter starts over at zero at the beginning of each minute, it does not recharge progressively.
Wait for the delay indicated by Retry-After. Trying again before then only consumes the next window, and a client that loops without waiting remains blocked indefinitely while giving the impression of a breakdown.
There is no queue. A call beyond the limit is refused immediately, it is not put on hold. This is deliberate: a quick response that says no is more useful than a slow response that eventually says yes, because it leaves the client the choice to slow down.
07Staying Under the Ceiling #sec_767baf63
Three actions, in the order of their importance.
The first: keep the token. A token lasts one hour; requesting a new one with each call exhausts the token ceiling—the lowest of the three—well before the data ceiling.
The second: increase the page size rather than multiplying calls. Five hundred elements in one request cost one debit token; the same five hundred in five requests cost five.
The third: space out the proofs. They have their own ceiling and also consume the standard; grouping them in bursts is the fastest way to hit both.
08To Remember #sec_2dde19f8
Six hundred calls per minute, sixty for proofs which add to the standard, sixty for tokens. One counter per authenticated client. Immediate refusal, never a queue. And Retry-After which says exactly how long to wait.