> ## Documentation Index
> Fetch the complete documentation index at: https://developers.reflection.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors

> Error responses, error codes, and when to retry

When a request fails, the API returns an HTTP status code and a JSON body with an `error` object:

```json theme={null}
{
  "error": {
    "message": "Invalid value for 'temperature': number must be at most 2.",
    "type": "invalid_request_error",
    "param": "temperature",
    "code": "invalid_value"
  }
}
```

| Field | Description |
| - | - |
| `message` | A human-readable description. Log it, but don't parse it; its wording can change. |
| `type` | The error category, such as `invalid_request_error`. |
| `param` | The request parameter the error relates to, in dotted notation such as `messages[0].content`, or `null`. |
| `code` | A machine-readable code, or `null`. Use this in your error handling. |

## Status codes

| Status | Meaning | Retry? |
| - | - | - |
| `400` | The request is invalid. Check `param` and `message`. | No. Fix the request. |
| `401` | The API key is missing, malformed, or not valid. | No. Fix the credential. |
| `402` | The organization has no credit or prepaid balance left. | No. Add credit or top up first. |
| `403` | The key is valid, but the caller isn't allowed to make the request. | No. Resolve the access issue. |
| `404` | The requested model doesn't exist or isn't available to you. | No. See [Models](/models). |
| `409` | The organization's billing isn't ready to serve requests. | Only `tier_switch_pending`, after `Retry-After`. |
| `413` | The request body is too large. | No. Shorten the request. |
| `415` | The request body isn't sent as JSON. | No. Set `Content-Type: application/json`. |
| `429` | A rate limit was exceeded. | Yes, after `Retry-After`. See [Rate limits](/rate-limits). |
| `502` | The model failed to produce a response. | Yes, with backoff. |
| `503` | The service is temporarily unavailable. | Yes, after `Retry-After` when present, otherwise with backoff. |

## Error codes

### 400: invalid request

These have `error.type` `invalid_request_error`.

| `error.code` | Meaning |
| - | - |
| `invalid_json` | The body isn't valid JSON. |
| `invalid_type` | A parameter has the wrong type. |
| `missing_required_parameter` | A required parameter or field is missing, such as `tool_call_id` on a `tool` message. |
| `invalid_value` | A parameter's value is out of range or not allowed, or the conversation is out of order, such as a tool call without a result. |
| `context_length_exceeded` | The request is longer than the model accepts. The API doesn't truncate it; shorten `messages` or lower `max_completion_tokens`. |
| `unsupported_value` | The parameter is supported only at a fixed value. See [OpenAI compatibility](/openai-compatibility#parameters-with-fixed-values). |
| `unsupported_parameter` | The parameter isn't supported, or isn't allowed in this context, such as `response_format.json_schema` with `type: "json_object"`. |

### 401: authentication

These have `error.type` `authentication_error`.

| `error.code` | Meaning |
| - | - |
| `missing_credentials` | No `Authorization` header was sent. |
| `invalid_authorization_header` | The header isn't of the form `Bearer <key>`. |
| `invalid_api_key` | The key is incorrect, disabled, or revoked. |
| `missing_project_scope` | The credential isn't associated with a project. |
| `invalid_session` | The credential's session isn't valid. |

### 402: payment required

These have `error.type` `permission_error`. Resolve them in the billing settings of the [Reflection platform](https://platform.reflection.ai), then retry.

| `error.code` | Meaning |
| - | - |
| `insufficient_credits` | The organization has no remaining credits. |
| `prepaid_balance_exhausted` | The organization's prepaid balance is used up. Top it up to resume requests. |

A used-up [daily token allowance](/rate-limits#how-limits-apply) can also return `insufficient_credits` instead of a `429`. The allowance renews at 00:00 UTC.

### 403: permission

These have `error.type` `permission_error`.

| `error.code` | Meaning |
| - | - |
| `organization_membership_required` | The key's user isn't a member of the organization. |
| `account_restricted` | The user, organization, or API key is restricted. Contact support. |
| `payment_method_required` | The organization must verify a credit card in Billing on the [Reflection platform](https://platform.reflection.ai) before using API keys. |
| `plan_access_denied` | The organization's plan doesn't include the kind of credential used. |

### 404: not found

| `error.code` | Meaning |
| - | - |
| `model_not_found` | The model doesn't exist or isn't available to you. [List models](/models) to see the ones you can use. |

### 409: billing conflict

These have `error.type` `permission_error`.

| `error.code` | Meaning |
| - | - |
| `tier_switch_pending` | The organization's billing tier is changing. Wait for the number of seconds in `Retry-After`, then retry. |
| `billing_setup_required` | The organization's billing setup is incomplete. Finish setup in Billing on the [Reflection platform](https://platform.reflection.ai) before retrying. The response includes `x-should-retry: false`. |

### 413: request too large

| `error.code` | Meaning |
| - | - |
| `request_too_large` | The request body exceeds the maximum size. |

### 415: unsupported media type

| `error.code` | Meaning |
| - | - |
| `unsupported_media_type` | The request has a body but no `Content-Type: application/json` header. The OpenAI SDKs set it for you. |

### 429: rate limit

These have `error.type` `rate_limit_error` and code `rate_limit_exceeded`, whichever limit was exceeded; `message` says which one. See [Rate limits](/rate-limits).

Wait for `Retry-After`, when present, then retry. When a daily limit or allowance is spent, the response also includes `x-should-retry: false`, because retrying can't succeed until it renews at 00:00 UTC. Responses can also report your remaining capacity in [rate limit headers](/rate-limits#rate-limit-headers).

### 502: bad gateway

The model failed to produce a response. These have `error.type` `upstream_unavailable_error` and a `null` code.

### 503: unavailable

These have `error.type` `api_error`.

| `error.code` | Meaning |
| - | - |
| `infrastructure_rate_limit_exceeded` | Inference capacity is temporarily exhausted. The response includes `Retry-After`. |
| `inference_capacity_unavailable` | The model's capacity is temporarily unavailable. The response includes `Retry-After`. |
| `billing_provisioning_pending` | The organization's billing setup is still in progress. The response includes `Retry-After`. |
| `authentication_unavailable`, `enforcement_unavailable`, `rate_limit_unavailable`, `payment_readiness_unavailable` | A service needed to accept the request is temporarily unavailable. |

## Request IDs

Every response, except a CORS preflight response, has an `x-request-id` header that identifies the request, and an `x-server-request-id` header with the same value. The server generates the ID; it is independent of any request ID you send. Log it with errors, and include it when you contact support.

The OpenAI SDKs read the header for you:

<CodeGroup>
  ```python Python theme={null}
  import openai

  try:
      completion = client.chat.completions.create(
          model="Beam-501B-A23B",
          messages=[{"role": "user", "content": "Hello"}],
      )
      print(completion._request_id)
  except openai.APIStatusError as e:
      print(e.status_code, e.request_id)
  ```

  ```typescript TypeScript theme={null}
  import OpenAI from "openai";

  try {
    const completion = await client.chat.completions.create({
      model: "Beam-501B-A23B",
      messages: [{ role: "user", content: "Hello" }],
    });
    console.log(completion._request_id);
  } catch (err) {
    if (err instanceof OpenAI.APIError) console.log(err.status, err.requestID);
    else throw err;
  }
  ```
</CodeGroup>

With cURL, add `-i` to print the response headers.

## Retrying

Retry `429`, `502`, and `503` responses, `409` responses with code `tier_switch_pending`, and network errors, with exponential backoff and jitter. When a response has a `Retry-After` header, wait at least that many seconds. Don't retry a response that has an `x-should-retry: false` header, and don't retry other `4xx` responses without changing the request.

The OpenAI SDKs retry these errors automatically, twice by default, and don't retry a response with `x-should-retry: false`. To change that, set `max_retries`:

<CodeGroup>
  ```python Python theme={null}
  client = OpenAI(
      base_url="https://api.reflection.ai/openai/v1",
      api_key=os.environ["REFLECTION_API_KEY"],
      max_retries=5,
  )
  ```

  ```typescript TypeScript theme={null}
  const client = new OpenAI({
    baseURL: "https://api.reflection.ai/openai/v1",
    apiKey: process.env.REFLECTION_API_KEY,
    maxRetries: 5,
  });
  ```
</CodeGroup>
