Rate limits
Per-key, per-account and per-IP limits, the rate limit headers and other usage limits.
Requests are counted in fixed windows. When a limit is reached the API answers 429 RATE_LIMIT:
JSON
{
"error": {
"code": "RATE_LIMIT",
"message": "Rate limit exceeded. Retry after the indicated delay.",
"retryable": true,
"retry_after_seconds": 17
}
}The answer also carries a Retry-After header with the same number of seconds. Wait that long, then retry.
#Headers
Answers that went through a limit carry:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed in the current window. |
X-RateLimit-Remaining | Requests left in the current window. |
X-RateLimit-Reset | Seconds until the window resets. |
Several limits apply to each request (below); the headers describe the last one checked.
#The limits
Every /v1 request, polls included, counts against all of these:
| Limit | Window | Notes |
|---|---|---|
| Per key | 60 s | The default per-key allowance, or the lower rate_limit_per_min set on the key under profile menu > API keys. |
| Per account | shared with the AITOPIA MCP server | All keys of the account and its MCP connections share it, so adding keys does not raise the total. |
| Per client IP | 60 s | Checked before the key, at ten times the default per-key allowance. |
The actual numbers are returned in X-RateLimit-Limit; build against the headers rather than a fixed value. GET /v1/openapi.json is not limited.
#Other limits
| Limit | Value | Answer |
|---|---|---|
Waiting calls (?wait=N) per account | 3 at a time, shared with the MCP server | Further waits check once and answer at once (Polling). |
wait | 0 to 60 seconds | 400 INVALID_INPUT |
Edit planning (POST /v1/edit, dry runs included) | 10 per minute, 100 per day | refused; see error.code and retryable |
| Items per batch | 1 to 12 | 400 INVALID_INPUT |
| Active runs per account | a few at once | 429 QUEUE_LIMIT_EXCEEDED: wait for running jobs to finish |
| Account generation limits | set by AITOPIA | 429 RUN_LIMITED: see message and retry_after_seconds |
| JSON request body | 25 MB | 413 FILE_TOO_LARGE |
| Upload link file | 95 MB | see File uploads |
| Monthly credits per key | optional cap | 402 KEY_CREDIT_CAP_REACHED (Billing) |
#Tips
- Prefer webhooks or
?wait=30long-polls to frequent short polls. - Use one
POST /v1/batchfor up to 12 independent generations instead of 12 separate submits. - On
429, honourretry_after_secondsinstead of retrying immediately.