General
Rate limits
Every response tells you how much budget is left, so a well-behaved client never has to guess.
RateLimit-Limit: 600
RateLimit-Remaining: 587
RateLimit-Reset: 42
RateLimit-Reset is seconds until the window refills. Read
these rather than counting your own requests: the budget is shared
across every key in the workspace, so your own count is not the whole
picture.
Two different refusals
| Code | Means | Fix |
|---|---|---|
rate_limited | Too many requests too quickly | Back off for Retry-After and spread the work out |
quota_exceeded | The plan's daily allowance is spent | Wait for details.resets_at, or upgrade. Retrying sooner will not help. |
upstream_rate_limited | A backend refused, not us | Back off. The RateLimit headers do not describe this limit. |
The allowance comes from the plan
Read it from the entitlements endpoint rather than hard-coding a number. An operator can change it without a release, and every plan has a different one.
Backing off well
- Honour
Retry-After. It is a real number, not a suggestion. - Add jitter. Ten workers retrying at the same second reproduce the burst that caused the limit.
- Slow down before you are refused, when
RateLimit-Remaininggets low, rather than after. - Batch where the API offers it. One request for fifty things beats fifty requests.