Diagnose an API error response.

Check the HTTP status and error body together; a 200 can still contain an error.

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
HTTP 200 with a provider 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 changeCheck 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 helpChanging the prompt, output-token limit or JSON schema, or retrying with the same rejected credential.
View synthetic JSON body
401 response 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 changeCheck 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 helpRepeating the same request or changing JSON formatting when the server has denied access.
View synthetic JSON body
403 response 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 changeCheck 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 helpImmediate repeated retries, raising max_tokens or changing the requested JSON fields.
View synthetic JSON body
429 response 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 changeCheck 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 helpRotating a valid key or rewriting the prompt when the provider reports a temporary service failure; avoid rapid unbounded retries.
View synthetic JSON body
503 response 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.

SignalNext step
400, 401, 403, 404, 422Fix the request fields, credential, permission or resource first. Repeating an unchanged rejected request will not repair it.
408, 500, 502, 503, 504Retry 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 errorSeparate 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 private

Sources 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.