Errors
The API uses conventional HTTP status codes and returns a JSON body with a stable error code plus a human-readable message.
| Status | error | When |
|---|---|---|
| 400 | bad_request | Malformed JSON body. |
| 401 | unauthorized | Missing, invalid, or revoked API key. |
| 403 | forbidden | Key is valid but lacks the required scope for this endpoint. |
| 422 | unprocessable | Body failed validation (e.g. 'message' missing or empty). |
| 429 | rate_limited | A rate or quota limit was hit. See the reason field and Retry-After header. |
| 500 | misconfigured / internal | Server-side error. Safe to retry with backoff. |
429 shape
The reason distinguishes a per-key limit from the workspace ceiling: key_rate, key_quota, or tenant_cap. When a reset time is known, a Retry-After header (seconds) is included.
JSON
{ "error": "rate_limited", "reason": "tenant_cap" }Retries
Retry 429 and 5xx with exponential backoff. Do not retry 4xx other than 429 — fix the request first.