Errors & Limits
Rate limits & quotas
Every request is admitted against your plan's limits. Responses carry
x-ratelimit-* headers so you can back off proactively.
| Plan | Concurrent streams | Requests / min | Monthly characters |
|---|---|---|---|
| Free | 2 | 30 | 10,000 |
| Starter | 3 | 60 | 250,000 |
| Pro | 10 | 300 | 2,000,000 |
| Scale | 15 | 600 | 10,000,000 |
Error semantics
| Status | Code | Meaning |
|---|---|---|
401 | invalid_api_key | Missing or invalid key. |
429 | too_many_requests | Requests-per-minute exceeded. Retry after retry-after. |
429 | too_many_concurrent_requests | Concurrent-stream cap reached. |
429 | insufficient_quota | Monthly character quota exhausted. |
5xx | internal_error | Transient server error — retry with backoff. |
Handling 429
import time, httpx
def synth(payload, key):
while True:
r = httpx.post(URL, json=payload, headers={"Authorization": f"Bearer {key}"})
if r.status_code == 429:
time.sleep(int(r.headers.get("retry-after", "1")))
continue
r.raise_for_status()
return r.content