Check both the HTTP status recorded by your client and the response body or stream event. Status is a transport signal; an error envelope or SSE error can still report a failed generation after HTTP 200. The body is not an assistant answer.
Missing the complete body or status? Follow the raw response capture guide first. If the body arrived but JSON is incomplete, use the JSON troubleshooting guide.
Inspect the response body locally
The checker can identify an error envelope, but it cannot infer the HTTP status from JSON alone. Enter the status recorded by your client separately. The local tool does not contact the endpoint.
A 200 can still contain an error
OpenRouter documents that a provider failure after the response starts can arrive as HTTP 200 with an error body and no choices, or as an SSE error event. This synthetic body illustrates the difference: the transport status is 200, while error.code describes the provider error. Check the body and the stream ending before treating a response as complete.
View the synthetic HTTP 200 error body
{
"id": "gen-example-midstream-error",
"error": {
"code": 429,
"message": "Rate limit exceeded",
"metadata": {
"error_type": "rate_limit_exceeded"
}
}
}Download this HTTP 200 error-body fixture. The transport status is recorded separately in the README because it is not part of the JSON body.
Downloadable synthetic response fixtures
These examples use OpenRouter’s documented error-object shape. They are hand-written fixtures, not captured provider responses. OpenAI documents its own status categories and recovery steps, but compatible APIs can use different body fields and codes.
401 Unauthorized
The documented OpenRouter-style example uses its authentication error category.
| What to change | Check which provider key your client sent, the Authorization header, and the account or project that owns the key. Replace a key only after confirming that it is invalid, expired or revoked. |
|---|---|
| What will not help | Changing the prompt, output-token limit or JSON schema, or retrying with the same rejected credential. |
View synthetic JSON body
{
"error": {
"code": 401,
"message": "Invalid credentials",
"metadata": {
"error_type": "authentication"
}
}
}Download the 401 JSON fixture · HTTP 401 Unauthorized
403 Forbidden
The documented OpenRouter-style example uses its permission-denied category; a provider may also use 403 for a policy or region restriction.
| What to change | Check the key's permissions, project access and any policy, budget, region or allowlist condition named by the provider. Ask the account owner to change access when required. |
|---|---|
| What will not help | Repeating the same request or changing JSON formatting when the server has denied access. |
View synthetic JSON body
{
"error": {
"code": 403,
"message": "Forbidden",
"metadata": {
"error_type": "permission_denied"
}
}
}Download the 403 JSON fixture · HTTP 403 Forbidden
429 Too Many Requests
This fixture follows OpenRouter's documented rate-limit response. A 429 can also come from the upstream provider, so inspect the provider-specific metadata and response headers.
| What to change | Check whether this is a request/token rate limit or an exhausted credit, daily-usage or spend limit. For a rate limit, honor Retry-After; if it is absent, use exponential backoff with jitter and a retry cap. Fix a depleted allowance before retrying. |
|---|---|
| What will not help | Immediate repeated retries, raising max_tokens or changing the requested JSON fields. |
View synthetic JSON body
{
"error": {
"code": 429,
"message": "Rate limit exceeded",
"metadata": {
"error_type": "rate_limit_exceeded"
}
}
}Download the 429 JSON fixture · HTTP 429 Too Many Requests
503 Service Unavailable (5xx example)
This OpenRouter-style example represents temporary provider overload. Other 5xx responses can have different server or routing causes.
| What to change | Check whether a provider is temporarily overloaded or your routing requirements have no available match. For a transient failure, honor Retry-After and retry with a bounded delay; change the route or model when the provider cannot satisfy it. |
|---|---|
| What will not help | Rotating a valid key or rewriting the prompt when the provider reports a temporary service failure; avoid rapid unbounded retries. |
View synthetic JSON body
{
"error": {
"code": 503,
"message": "Provider temporarily overloaded",
"metadata": {
"error_type": "provider_overloaded"
}
}
}Download the 503 JSON fixture · HTTP 503 Service Unavailable
When to retry—and when to fix the cause first
These are starting points drawn from the linked OpenAI and OpenRouter guidance, not universal rules for every compatible API. Read the provider's error code, headers and account details before retrying.
| Signal | Next step |
|---|---|
400, 401, 403, 404, 422 | Fix the request fields, credential, permission or resource first. Repeating an unchanged rejected request will not repair it. |
408, 500, 502, 503, 504 | Retry only when the provider describes a transient timeout or availability problem and the request is safe to repeat. Use a bounded delay and retry count; if the route or model is unavailable, adjust it instead of looping. |
429 or a provider-specific quota error | Separate rate limiting from exhausted credits, usage or spend limits. For rate limiting, wait at least the Retry-After value when present. If absent, use exponential backoff with jitter and cap attempts. Restore an exhausted allowance before retrying. |
Do not retry a 429 just because of its number: OpenAI documents both temporary rate limits and exhausted credit or spend limits under 429. OpenRouter documents 429 and 503 Retry-After behavior and a special in-flight-budget case; inspect its error metadata before assuming a delay will help. An SDK may already retry eligible failures, so avoid stacking retry loops.
Do not classify an error from error.type, error.code or metadata without the provider’s documentation. The same HTTP status can represent different causes.
Official references
OpenAI API error codes and recovery guidanceOpenRouter rate limits, 429 responses and streaming errorsOpenRouter error response shape and typed error categoriesOpenAI guidance on keeping API keys privateSources checked 20 October 2026. The fixture metadata follows OpenRouter’s documented vocabulary only; it is not a universal error-code list.
Free API access and limits
Check the site free API access and limits before trying to obtain a site key. Read the current status and request limits before using a site key. It is not a source of official provider keys.
ChinaGenAI is not affiliated with the providers named here. This release contains setup guidance and explicitly labeled fictional examples, not claimed live model benchmarks.