# Errors & limits

```json
{"error":{"code":"KEY_BUDGET_EXCEEDED","message":"This key has insufficient spending allowance.","request_id":"req_demo_error"}}
```

| HTTP | Code | Recovery |
|---|---|---|
| 422 | `INVALID_INPUT` | Correct the input before resubmitting. |
| 401 | `INVALID_API_KEY`, `API_KEY_INACTIVE` | Use a valid credential. |
| 403 | `MODEL_NOT_ALLOWED`, `IP_NOT_ALLOWED` | Review key restrictions in the console. |
| 402 | `INSUFFICIENT_BALANCE`, `KEY_BUDGET_EXCEEDED` | Top up or change the authorized budget. |
| 404 | `MODEL_NOT_FOUND`, `REQUEST_NOT_FOUND` | Check the ID and ownership. |
| 409 | `IDEMPOTENCY_CONFLICT` | Use the original payload or a new logical request. |
| 409 | In-progress request record or `RESPONSE_CACHE_EXPIRED` | Wait/reconcile; do not buy a duplicate generation. |
| 422 | `UNSUPPORTED_PARAMETER` | Correct the model/input choice. |
| 429 | `RATE_LIMITED` | Respect Retry-After and reduce traffic. |
| 502/503 | `MODEL_UNAVAILABLE` | Inspect request status before retrying a submission. |

Messages are sanitized; supplier balance, merchant secrets, and raw upstream stack traces are never shown. `X-Request-ID` supports troubleshooting. Unknown provider errors must not be falsely labeled as content-policy violations. After SSE headers are sent, an error is an SSE error event followed by closure, not a second HTTP response.

[Idempotency](/docs?page=tasks&lang=en) · [Production](/docs?page=production&lang=en)
