Errors & limits
All errors use a consistent JSON envelope with a machine-readable code and request_id for support.
Error envelope
{
"error": {
"code": "insufficient_credits",
"message": "Insufficient credits",
"request_id": "uuid"
}
}Error codes
| Code | Status | Meaning |
|---|---|---|
unauthorized | 401 | Missing Authorization header |
invalid_key | 401 | Key does not start with oo_live_ |
key_not_found | 401 | Revoked or unknown API key |
org_inactive | 403 | Organization suspended or closed |
scope_denied | 403 | Key lacks the required scope |
model_not_allowed | 403 | Model outside your plan or key allowlist |
insufficient_credits | 402 | Org pool cannot cover the request |
rate_limit_exceeded | 429 | Per-key per-minute limit hit — retry after 60s |
validation_error | 400 | Malformed body or unsupported model for endpoint |
internal_error | 500 | Unexpected server error — include request_id with support |
Rate limits
Limits are enforced per API key per rolling minute. Exceeded limits return HTTP 429 with rate_limit_exceeded.
| Tier | Limit |
|---|---|
standard | 60 requests / minute / key |
elevated | 300 requests / minute / key |
Request IDs
Every successful response includes request_id; errors include it in the error object. Log these when contacting support or correlating with usage reporting.