Errors
Status codes
Section titled “Status codes”| Code | Meaning | Retry? |
|---|---|---|
| 401 | Missing or invalid API key | No — fix credentials |
| 403 | Valid key, request rejected (balance, whitelist, quota, IP) | After resolving the cause |
| 413 | Request body too large | Reduce size and retry |
| 429 | Rate limited | Yes — exponential backoff, no Retry-After |
| 500 | Gateway or upstream failure | Yes — safe to retry idempotent requests |
Insufficient balance is rejected with 403.
Response envelopes
Section titled “Response envelopes”OpenAI-compatible endpoints
Section titled “OpenAI-compatible endpoints”Errors use the OpenAI envelope:
{ "error": { "message": "…", "type": "new_api_error", "param": null, "code": null }}error.type distinguishes the failure source:
new_api_error— the MirAPI gateway rejected the request (auth, balance, quota, validation).upstream_error— the upstream model provider failed; the message is sanitized so vendor internals never leak.
Anthropic (/v1/messages)
Section titled “Anthropic (/v1/messages)”The same failure uses the Anthropic error shape:
{ "type": "error", "error": { "type": "permission_error", "message": "…" }}Request IDs
Section titled “Request IDs”Every error message ends with a request ID suffix so you can find the exact call in the logs (console, GET /api/usage/token, GET /api/log/token). Include it when opening a billing or support ticket.
Sanitization
Section titled “Sanitization”Upstream responses are sanitized before reaching you: provider-internal details (hosts, tokens, stack traces, model IDs) are stripped and replaced with a stable message. Log the sanitized message and don’t guess at the underlying provider.
Retry guidance
Section titled “Retry guidance”- MirAPI does not retry on your behalf.
- 429 responses carry no
Retry-Afterheader — use exponential backoff with jitter (1s → 2s → 4s, capped at ~30s). - 500s are safe to retry for idempotent requests; do not blindly replay non-idempotent ones (generation, tool side effects).