# API reference

The base URL, how to authenticate, and every endpoint and error code the gateway serves.

*ProxyLLM docs · https://proxyllm.ai/docs/api*

Everything lives on one base URL:

```
https://api.proxyllm.ai
```

Authenticate with the `Authorization` header:

```
Authorization: <token>
```

The `Bearer` prefix is optional; both forms work. Two kinds of token exist: a **routing key** (`pllm_…`) for inference and an **account token** (`sk_…` read+write, `rk_…` read-only) for management. [Authentication](/docs/api/authentication) covers both, including read-only scopes and what happens when you mix them up.

## Inference

OpenAI-compatible, authed by a routing key. Point any OpenAI SDK at `https://api.proxyllm.ai/v1`.

- [`POST /v1/chat/completions`](/docs/api/chat-completions) - Chat Completions, including streaming and tool calls.
- [`POST /v1/responses`](/docs/api/responses) - Responses API.
- [`GET /v1/models`](/docs/api/models) - the model catalog, including the `flagship` and `mini` tiers.
- [`GET /v1/key`](/docs/api/key) - introspect the routing key: lanes, budget, Codex status.
- [`POST /blitz`](/docs/api/blitz) - run up to 50 prompts through the key's routing in one request.

## Account management

Account endpoints live under `/v1/organizations/`, the same shape OpenAI and Anthropic use for their admin APIs. Authed by an account token.

- [`GET /v1/organizations/me`](/docs/api/me) - who this token belongs to and its scope.
- [`GET /v1/organizations/usage`](/docs/api/usage) - 30-day usage summary.
- [`GET | POST /v1/organizations/routing-keys`](/docs/api/routing-keys) - list or create routing keys.
- [`GET | POST /v1/organizations/bridges`](/docs/api/bridges) - list or register Claude Code bridges.
- [`GET | POST | DELETE /v1/organizations/codex-session`](/docs/api/codex-session) - Codex connection status, connect, disconnect.

The older `/v1/routing-keys`, `/v1/bridges`, and `/api/codex?action=…` paths still work as legacy aliases; new integrations should use `/v1/organizations/…`.

## Error shapes

Inference endpoints return OpenAI-shaped errors:

```json
{
  "error": {
    "message": "Routing key monthly budget exhausted",
    "type": "budget_exceeded",
    "code": "budget_exceeded"
  }
}
```

Management endpoints and `POST /blitz` return a flat shape:

```json
{
  "error": "This account token is read-only. Use a read and write token (sk_...) from Settings for this action.",
  "code": "read_only_token"
}
```

Messages are plain sentences that say what to do next. A few validation errors (missing `model`, `messages`, or `input` on inference) return the OpenAI shape with no `code`.

## Error codes

Every code the gateway returns, across all documented endpoints:

| Status | Code                    | When                                                                                                                                                     |
| ------ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | `bad_request`           | A management request body failed validation. The message names the field.                                                                                |
| 400    | `no_providers`          | The routing key has no lanes configured. Add lanes in the dashboard.                                                                                     |
| 400    | `no_credential`         | A streaming request landed on a lane whose provider has no saved API key.                                                                                |
| 400    | `unsupported_feature`   | A Responses API parameter the gateway does not support (`previous_response_id`).                                                                         |
| 401    | `signup_required`       | No key was sent on an inference endpoint, or the key is a raw provider key (`sk-…`) where a routing key belongs.                                         |
| 401    | `invalid_api_key`       | The routing key does not exist or was revoked. Also returned, with an explanatory message, when an account token was pasted where a routing key belongs. |
| 401    | `invalid_account_token` | The account token does not exist or was revoked.                                                                                                         |
| 401    | `auth_required`         | No token was sent to `/blitz`.                                                                                                                           |
| 401    | (none)                  | No token in the Authorization header, on a management endpoint.                                                                                          |
| 402    | `budget_exceeded`       | The routing key's monthly budget is exhausted.                                                                                                           |
| 403    | `read_only_token`       | A read-only (`rk_`) token called a write endpoint.                                                                                                       |
| 405    | `method_not_allowed`    | Wrong HTTP method on a management endpoint.                                                                                                              |
| 405    | (none)                  | Wrong HTTP method on an inference endpoint or `/blitz`.                                                                                                  |
| 500    | `env_missing`           | The gateway is misconfigured. Not your fault; contact support.                                                                                           |
| 500    | `server_error`          | A database operation failed. Details stay server-side.                                                                                                   |
| 500    | `encrypt_failed`        | Encrypting an uploaded Codex sign-in failed.                                                                                                             |
| 500    | `unhandled`             | Unexpected crash. Contact support if it repeats.                                                                                                         |
| 502    | `upstream_error`        | Every lane failed, or the upstream provider broke mid-request. The message carries the last provider error.                                              |
