> ## Documentation Index
> Fetch the complete documentation index at: https://docs.transcriptmagic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rate limits

> One hundred twenty requests per minute, per key.

Every API key is allowed **120 requests per minute**. The window is fixed (not a sliding window): the first request opens a 60-second bucket, and the counter resets when that bucket expires. The limit is enforced per-key — so you can scale horizontally by issuing additional keys to separate workers.

## Headers

Every response from an API-key-authenticated request includes the rate-limit state, so you can self-throttle without waiting to hit a 429.

| Header                  | Description                                                         |
| ----------------------- | ------------------------------------------------------------------- |
| `X-RateLimit-Limit`     | Your per-minute cap. `120` for all standard accounts.               |
| `X-RateLimit-Remaining` | Requests left in the current window after this call.                |
| `X-RateLimit-Reset`     | Unix timestamp (seconds) when the window resets.                    |
| `Retry-After`           | Seconds to wait before retrying. **Only present on 429 responses.** |

The headers fire on every status code — `200`, `400`, `404`, `429`, `502`, etc. — as long as the request authenticated via API key. Anonymous (web-form) and Google-session-token requests do not receive these headers because they're not subject to the same per-key quota.

## Handling 429

When you exceed the limit, the API returns:

```json theme={null}
{ "error": "Rate limit exceeded. Try again later." }
```

…with a `Retry-After` header. Wait that many seconds before your next request. Don't poll faster — repeated 429s won't shorten the wait, they just waste sockets.

```python theme={null}
import time, requests

def call_with_retry(url, payload, headers):
    while True:
        r = requests.post(url, json=payload, headers=headers)
        if r.status_code != 429:
            return r
        wait = int(r.headers.get("Retry-After", "1"))
        time.sleep(wait)
```

## Self-throttling

Watch `X-RateLimit-Remaining` on normal traffic and slow down before you hit the wall. A small headroom (e.g. pause when remaining drops below 10) absorbs the slop from in-flight requests that haven't decremented yet. For higher concurrency, issue a separate key per worker — each key has its own independent 120/min bucket.

## Higher limits

Need more than 120/min? Email [hello@transcriptmagic.com](mailto:hello@transcriptmagic.com) — we lift caps to **600/min** for verified production accounts.
