Skip to main content
All /v1 endpoints share two independent per-minute rate limits: Both are fixed one-minute windows. Whichever limit you hit first applies. The defaults are well above normal create-and-poll traffic and may be tuned over time — read the response headers rather than hard-coding these numbers.
POST /v1/uploads has an additional, tighter cap of 60 uploads / minute per account — a rolling window — because it’s free and unmetered. It applies on top of the per-key and per-IP limits above and returns the same 429 + Retry-After. Regular generation and polling traffic isn’t affected.
Generation jobs also have a separate per-plan concurrency cap — the number of jobs you can have in flight at once, the same cap as the web workshop. That cap is independent of the request limits on this page: polling status never counts against concurrency, and concurrency never shows up in the X-RateLimit-* headers.

Response headers

Every API response reports your current standing:

When you exceed a limit

Requests over the limit receive HTTP 429 with a Retry-After header (seconds) and this body:
Rejected requests still count against the window. A tight retry loop keeps the window full and you stay rate limited indefinitely. On a 429, stop and wait the full Retry-After before sending anything else.

Staying under the limits

  • Poll gently. Poll job status every few seconds (images) to every 10–30 seconds (video) — not in a tight loop. See Async jobs.
  • Respect Retry-After. On 429, sleep for the advertised seconds, then resume. Add jitter if multiple workers share a key or IP.
  • Cache stable resources. GET /v1/models changes rarely — cache it for minutes to hours instead of fetching it per request.
  • Watch X-RateLimit-Remaining. If it trends toward zero, slow down before you hit the wall instead of after.