rate limits
Limits are per key, per minute, by class
Writes are limited harder than reads because they cost more to serve, and pipeline runs hardest of all because they cost real money.
The classes#
| Class | Applies to | Limit |
|---|---|---|
| read | every GET | 600 per minute |
| write | POST, PATCH and DELETE on content, taxonomy, keys and webhooks | 120 per minute |
| upload | POST /media/upload-url | 60 per minute |
| pipeline | POST /pipeline/runs | 10 per minute |
Every operation in the reference states its class, so you can work out a budget before you write the loop rather than after it is refused.
The headers#
Every response carries the state of your window, so you can slow down before you are refused rather than after.
RateLimit-Limit: 600
RateLimit-Remaining: 587
RateLimit-Reset: 1786000860RateLimit-Limitis what your key is permitted in the current window for this endpoint class.RateLimit-Remainingis what is left in it.RateLimit-Resetis the Unix second at which the window resets.Retry-After, in seconds, is added to every 429. Honour it.
When you are limited#
RATE_LIMIT_EXCEEDED. Back off and honour Retry-After.
Limits are per key, per minute, by endpoint class. Writes are limited harder than reads because they cost more to serve, and pipeline runs hardest of all because they cost real money.
| Class | Endpoints | Limit |
|---|---|---|
| read | every GET | 600 per minute |
| write | POST, PATCH and DELETE on content, taxonomy, keys and webhooks | 120 per minute |
| upload | POST /media/upload-url | 60 per minute |
| pipeline | POST /pipeline/runs | 10 per minute |
Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset, so you can slow down before you are refused rather than after.
- Back off exponentially, starting from
Retry-After, and add jitter. A fleet of workers that all retry after exactly the same delay recreates the burst that limited them. - Batch reads with `limit` and `fields` rather than fetching one article at a time. One request for 100 projected rows costs one unit; 100 requests cost 100.
- Do not poll `GET /pipeline/runs` in a tight loop. Subscribe to
pipeline.run.completedinstead. - A 429 is not a spend gate. If you are looking for the thing that stops runaway cost, that is the 402 family on the errors page.
Higher limits#
Some plans raise the ceiling. It applies automatically to the keys on the Site and needs no change to your code; the first request of a session runs at the standard rate and the elevated rate applies from the next one.
If you are hitting a limit with a legitimate workload, that is worth a conversation rather than a retry loop. Contact support.