Rate limits
Request rate limits per API key, the concurrent task limit per account, request size limits and task time limits.
Limits keep the service responsive for everyone. When you go over one, you get 429 rate_limited with a Retry-After header (seconds).
Request limits
| Scope | Limit | Applies to |
|---|---|---|
| Per API key | 5 requests / second | POST /v1/tasks |
| Per API key | 20 requests / second | GET /v1/tasks, GET /v1/tasks/{id}, GET /v1/balance |
| Per IP address | 50 requests / second | All /v1 endpoints, including GET /v1/models |
Limits are counted in one-second windows.
Concurrent tasks
An account can have at most 20 tasks in progress (queued or processing) at once, across all of its API keys and the Playground. Creating another returns 429 rate_limited with Retry-After: 10. Wait for some tasks to finish, then retry.
If you need higher limits, contact support.
Size limits
| Item | Limit |
|---|---|
| Request body | 64 KB |
metadata | 16 keys, 2 KB as JSON |
Idempotency-Key | 255 characters |
URLs (callback_url, image_urls) | 2,048 characters each |
image_urls count | Depends on the model, see Models |
| Prompt length | Depends on the model, see Models |
Time limits
| Item | Limit |
|---|---|
| Image task | 15 minutes from created_at, then it fails with timeout and is refunded |
| Video task | 45 minutes from created_at, then it fails with timeout and is refunded |
| Result files | Kept 30 days after completion (expires_at) |
| Webhook response | 10 seconds; then retried, 5 attempts in total |
Idempotency-Key window | 24 hours |
Handling 429
Node.js
async function withRetry(fn, attempts = 5) {
for (let i = 0; ; i++) {
const resp = await fn();
if (resp.status !== 429 && resp.status !== 503) return resp;
if (i >= attempts - 1) return resp;
const wait = Number(resp.headers.get('retry-after')) || 2 ** i;
await new Promise((r) => setTimeout(r, wait * 1000 + Math.random() * 250));
}
}Combine this with an Idempotency-Key on task creation so retries never create duplicate tasks.