Rate limits
Each API key may send a set number of requests a minute, by plan. Every response says where the key stands, and a 429 says how long to wait.
Each API key may send a set number of requests a minute. The number comes from your plan. Every response tells you where the key stands, so you can slow down before you are refused, and a request over the limit answers 429 with the number of seconds to wait.
X-RateLimit-Limit: 1500
X-RateLimit-Remaining: 1499
X-RateLimit-Reset: 1791450240| Limit | Free | Starter | Growth | Business |
|---|---|---|---|---|
| Requests a minute, per API key | 60 | 300 | 600 | 1,500 |
| Objects in one batch request | 10 | 50 | 100 | 100 |
A change of plan applies from the next request. The same numbers are on Billing and under Plan limits in Settings, Organisation.
How requests are counted
- Per key. Every key has its own count. Two keys of one project have two budgets, and a live key and a test key get the same number.
- By the clock minute. A window is a minute of the clock, from second 0 to second 59 in UTC. It is not the 60 seconds after your first request.
- Across the whole API. One count covers every endpoint. A batch of 100 objects is one request.
- Whatever the answer. A request that is refused with 403, 404, 422 or 429 still counts, and so does an idempotent replay. A request refused with 401 does not, because no key was recognised.
Because windows follow the clock, a burst at the end of one minute and another at the start of the next can both pass. Read X-RateLimit-Remaining in place of counting on your side.
The headers
X-RateLimit-LimitintegerThe key's requests a minute.
X-RateLimit-RemainingintegerWhat is left in this window after this request. It never goes below 0.
X-RateLimit-ResetintegerWhen the next window starts, in seconds since the Unix epoch.
Over the limit
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1500
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1791450240
Retry-After: 43
{
"error": {
"code": "rate_limited",
"message": "Rate limit exceeded for this API key",
"details": [],
"request_id": "req_a58d9c4fb7ac4fcfb891295a5560a52e"
}
}Retry-After is the number of seconds until the next window, from 1 to 60. Wait that long and send the request again. Requests sent while you are over the limit are refused and counted, but they do not push the window back.
async function send(url, options) {
for (;;) {
const response = await fetch(url, options);
if (response.status !== 429) return response;
// Retry-After is the number of seconds until the next window.
const seconds = Number(response.headers.get("Retry-After")) || 1;
await new Promise((resolve) => setTimeout(resolve, seconds * 1000));
}
}import time
import requests
def send(method, url, **kwargs):
while True:
response = requests.request(method, url, **kwargs)
if response.status_code != 429:
return response
# Retry-After is the number of seconds until the next window.
time.sleep(int(response.headers.get("Retry-After", 1)))Batch size
POST /v1/moderations/batch takes 1 to 100 objects, and the plan can set a lower ceiling: the second row of the table above. A batch larger than the plan takes answers 403 plan_limit before anything runs. One with more than 100 objects answers 422.
Batches says when a batch answers in the same response and when it is queued.
Rate and checks are two budgets
The rate limit counts requests. Checks count what was screened. A batch of 100 objects is one request against the first and up to 100 moderations against the second, and running out of checks answers 402 quota_exceeded, not 429.
When the headers are missing
- On a 401. The key was not recognised, so there is no count to report.
- On a body that could not be read. A 400
invalid_jsonand a 413payload_too_largeare answered before the key is looked at. They are not counted. - When the limiter cannot be reached. A request never fails because of that. In that rare moment requests are not limited and the three headers are absent.
Next
- Plans and limitsWhat each plan includes, what is counted per organisation and what per project, and what happens to your setup when the plan changes.
- Batch checksSend up to 100 objects in one request. A small batch of text answers in the same response, anything else is queued, and one bad item never fails the rest.
- ErrorsEvery error has one JSON shape. Branch on its code, show its details and quote its request id. The table lists each code the API returns and when.
Something missing or unclear on this page? Write to support@useinfrared.com.