Rate limits & errors
Plan limits, 429 semantics, and every error shape you can receive.
Plan limits
Limits attach to each API key, on three independent axes: concurrent streams, requests per minute, and characters per calendar month. Your key’s exact limits are shown in the console settings.
| Plan | Concurrent streams | Requests / min | Characters / month |
|---|---|---|---|
| Free | 25 | 3,000 | 5,000,000 |
| Starter | 50 | 10,000 | 50,000,000 |
| Pro | 100 | 30,000 | 500,000,000 |
| Scale | 250 | 100,000 | unlimited |
| Internal | 1,000 | 500,000 | unlimited |
- Concurrent streams: in-flight requests at once. Each open connection (including a WebSocket) holds one slot; slots free on completion, and a crashed connection’s slot self-frees on a short TTL.
- Requests per minute: fixed 60-second window, counted per key.
- Characters per month: summed
inputlength over the calendar month (UTC).unlimitedplans aren’t metered against a quota.
Handling 429s
When a limit is hit you get 429 with a machine-readable status and, where applicable, a Retry-After header (seconds). Successful responses also carry your remaining budget:
| Parameter | Type | Default | Description |
|---|---|---|---|
| x-ratelimit-remaining-requests | header | - | Requests left in the current minute window. |
| x-ratelimit-remaining-streams | header | - | Concurrency slots free for this key right now. |
| x-ratelimit-remaining-characters | header | - | Characters left this month (absent on unlimited plans). |
Back off and retry on rate_limit_exceeded and too_many_concurrent_requests (retry after ~1 s for concurrency). Treat insufficient_quota as terminal until the month rolls over or your plan changes; don’t retry-storm it.
Error catalogue
All errors share one shape, so a single handler covers them: { "detail": { "status": "...", "message": "..." } }.
| Parameter | Type | Default | Description |
|---|---|---|---|
| rate_limit_exceeded | 429 | - | Too many requests this minute. Respect Retry-After. |
| too_many_concurrent_requests | 429 | - | All concurrency slots for this key are in use. Retry in ~1 s. |
| insufficient_quota | 429 | - | Monthly character quota exhausted. Terminal until reset/upgrade. |
| missing_api_key / invalid_api_key | 401 | - | Auth problem; see Authentication. |
status values intentionally match the OpenAI and ElevenLabs error vocabularies, so those SDKs’ built-in retry logic works against Svara unchanged.