# Routing keys

GET | POST /v1/organizations/routing-keys - list your routing keys or create one.

*ProxyLLM docs · https://proxyllm.ai/docs/api/routing-keys*

```
GET  /v1/organizations/routing-keys
POST /v1/organizations/routing-keys
```

Auth: **[account token](/docs/api/authentication)**. `rk_` or `sk_` can list; creating needs `sk_`.

## List

```bash
curl https://api.proxyllm.ai/v1/organizations/routing-keys \
  -H "Authorization: Bearer rk_your_readonly_token"
```

```json
{
  "routing_keys": [
    {
      "id": "5e2f8c1a-...",
      "label": "client-acme",
      "key_prefix": "pllm_h3Xk9aQ…1a2b",
      "mode": "fallback",
      "classifier_provider": null,
      "classifier_model": null,
      "classifier_instructions": null,
      "monthly_budget_usd": 50,
      "budget_excludes_seats": true,
      "current_month_spend_usd": 12.4,
      "current_month": "2026-07",
      "last_used_at": "2026-07-03T09:12:00.000Z",
      "revoked_at": null,
      "created_at": "2026-06-01T10:00:00.000Z",
      "updated_at": "2026-07-01T10:00:00.000Z",
      "providers": [
        {
          "provider": "codex",
          "model": null,
          "credential_id": null,
          "codex_session_id": "8a1b...",
          "bridge_instance_id": null,
          "category_key": null,
          "category_description": null
        }
      ]
    }
  ]
}
```

`providers` is the key's lane list in order. The raw key is never returned here; only its display prefix.

## Create

```bash
curl -X POST https://api.proxyllm.ai/v1/organizations/routing-keys \
  -H "Authorization: Bearer sk_your_account_token" \
  -H "Content-Type: application/json" \
  -d '{"label": "client-acme", "monthly_budget_usd": 50}'
```

Request body:

| Field                     | Type                           | Notes                                                                       |
| ------------------------- | ------------------------------ | --------------------------------------------------------------------------- |
| `label`                   | string                         | Up to 60 characters. Defaults to `"default"`.                               |
| `mode`                    | `"fallback"` or `"classifier"` | Defaults to `fallback`.                                                     |
| `monthly_budget_usd`      | number                         | Optional cap; omit or send a non-positive number for no budget.             |
| `budget_excludes_seats`   | boolean                        | Default `true`: subscription-seat traffic does not count toward the budget. |
| `classifier_provider`     | string                         | Required in classifier mode; a provider you have a saved API key for.       |
| `classifier_model`        | string                         | Required in classifier mode.                                                |
| `classifier_instructions` | string                         | Required in classifier mode, at least 10 characters.                        |

Response: the created key in the same shape as the list, plus the raw key, returned **once**:

```json
{
  "routing_key": {
    "id": "5e2f8c1a-...",
    "label": "client-acme",
    "key_prefix": "pllm_h3Xk9aQ…1a2b",
    "mode": "fallback",
    "monthly_budget_usd": 50,
    "budget_excludes_seats": true,
    "current_month_spend_usd": 0,
    "providers": []
  },
  "raw_key": "pllm_h3Xk9aQm2vL8pTw4rYc6nB0dFgJ5sZq1"
}
```

Store `raw_key` immediately; it cannot be fetched again. A key created without `providers` has no lanes yet; wire them over this API (below) or under [Routing keys](https://proxyllm.ai/dashboard/routing-keys) in the dashboard.

## Wiring lanes

Pass `mode` and a `providers` array (up to 5) on POST to create and wire in one call, or rewire an existing key:

```
PATCH https://api.proxyllm.ai/v1/organizations/routing-keys?id=<routing_key_id>
```

```json
{
  "mode": "fallback",
  "providers": [
    { "provider": "codex", "model": "flagship", "codex_session_id": "..." },
    { "provider": "openai", "model": "gpt-5", "credential_id": "..." }
  ]
}
```

`codex` lanes name one of your connected [Codex sessions](/docs/api/codex-session), `bridge` lanes name a registered [bridge](/docs/api/bridges), and API-key providers (`openai`, `anthropic`, `openrouter`, ...) name a saved provider key. Every referenced id must belong to you. Find the ids with:

```
GET https://api.proxyllm.ai/v1/organizations/routing-keys?include=lanes
```

which adds a `lanes` object (`codex_sessions`, `bridges`, `credentials`) to the list response. PATCH also accepts `label`, `monthly_budget_usd`, `revoked` (true/false), and `regenerate: true` (returns a fresh `raw_key` once).

## Errors

| Status | Code                    | When                                                                          |
| ------ | ----------------------- | ----------------------------------------------------------------------------- |
| 400    | `bad_request`           | Invalid config, a referenced lane is not yours, or classifier fields missing. |
| 401    | (none)                  | No token sent.                                                                |
| 401    | `invalid_account_token` | Unknown or revoked token.                                                     |
| 402    | `payment_required`      | No active membership yet ([agent signup](/docs/api/agent-signup)).            |
| 403    | `read_only_token`       | POST or PATCH with an `rk_` token.                                            |
| 405    | `method_not_allowed`    | Method other than GET, POST, or PATCH.                                        |
| 500    | `server_error`          | The database write failed.                                                    |
