Errors
Every error is an OpenAI-shaped error object, so existing error-handling code that checks error.type or error.code keeps working unmodified.
Error shape
{
"error": {
"message": "Human-readable description of what went wrong.",
"type": "invalid_request_error",
"code": "model_not_allowed"
}
}
The response also carries an x-tempr-request-id header — include it when contacting support about a specific failed request.
Common errors
| Status | Code | Meaning |
|---|---|---|
401 | invalid_api_key | The virtual key is missing, malformed, or revoked. |
403 | model_not_allowed | The requested model isn't on this key's allowlist. |
429 | rate_limited | Key-level or plan-level RPM/TPM ceiling exceeded. Check the x-tempr-quota header and back off. |
402 / 429 | quota_exceeded | Monthly request quota reached (Free hard block, or a paid plan's overage cap hit). Upgrade or wait for the next billing cycle. |
402 | budget_exceeded | The virtual key's configured spend budget has been reached. |
4xx/5xx | upstream_error | The provider itself returned an error; Tempr passes the upstream status through where possible. |
500 | stream_truncated | An in-progress streaming response was cut off before completion. Safe to retry. |
Retries & fallback
Tempr already retries transient upstream 429/5xx errors against the same provider before giving up, and — if you've configured a fallback chain on the key — falls back to the next candidate model automatically. A client-visible error means Tempr's own retry and fallback logic was exhausted, so treat it as a real failure rather than immediately retrying in a tight loop.