# Rate limits

> How many requests a key may make, what the headers mean, and how to back off without losing work.

Every key has a request limit per 60-second sliding window, set by the owning account's plan. OAuth tokens, which have no key, are limited per user. For a member of a Team or Enterprise organisation the higher of their own plan's figure and the organisation's applies; an Enterprise agreement can set the organisation's figure for its members' keys.

| Plan | Requests per minute |
| --- | --- |
| Hobby | 20 |
| Creator | 120 |
| Studio | 600 |
| Team | 600 |
| Enterprise | By contract (600 unless your agreement sets another figure) |
| An app we have throttled | 6 |

Some endpoints have their own limit on top:

| Endpoint | Extra limit |
| --- | --- |
| Preview frames (`GET /v1/projects/{id}/preview` with `format=image` or `at`) | 10 a minute per key |
| `PATCH /v1/telegram/users/{user}` | 120 a minute per app |

## Headers

Every response that passes authentication carries:

| Header | Meaning |
| --- | --- |
| `X-RateLimit-Limit` | Requests allowed per window. |
| `X-RateLimit-Remaining` | How many are left in the current window. |
| `X-RateLimit-Reset` | The window length in seconds (normally `60`). It is a duration, not a timestamp. |
| `Retry-After` | On `429` and `503`: seconds to wait before trying again. |

Requests refused before the limit is checked (`401` and `403`) do not carry these headers.

## When you hit the limit

You get `429 rate_limited` with `Retry-After`. Refused requests do **not** count against the window, so a client that backs off recovers cleanly instead of digging itself deeper. The two endpoint-specific limits answer `429` too; the preview one says how long to wait in `retryAfterSec` in the error body.

If the limiter itself cannot be reached, the API refuses rather than letting requests through unmetered: you get `503 unavailable` with `Retry-After: 30`, and nothing was run or charged.

> **Tip: Do not poll fast.** The limiter cannot tell an eager poller from an attack, and a tight loop against a three-minute render uses your budget before the video exists. Poll a render every five seconds at most, or better, use [webhooks](https://developer.vidmoat.com/developer/docs/webhooks).

## Other limits that are not the rate limit

- **Credits** bound what generation can spend: see [credits and plans](https://developer.vidmoat.com/developer/docs/concepts/credits-and-plans).
- **Renders at once** are limited per plan. A burst of render requests over that limit is refused with `402 quota_exceeded`; nothing is queued.
- **One video generation job** runs at a time per account.
- **Batch size**: at most 200 commands per request.

---

Source: https://developer.vidmoat.com/developer/docs/rate-limits
Previous: [Errors and retries](https://developer.vidmoat.com/developer/docs/errors.md)
Next: [Build your own video platform](https://developer.vidmoat.com/developer/docs/build.md)
All documentation: https://developer.vidmoat.com/llms-full.txt
