> ## Documentation index
> Fetch the complete documentation index at: https://rolter-ai-rolter.docs7.io/llms.txt
> Ask it with GET https://rolter-ai-rolter.docs7.io/ask?q=<keywords or question>. Short keywords rank best.
> Use these to discover all available pages before exploring further.

# GET /v1/models: List the Models Your Key Can Access

> List the route names, provider-pinned addresses and provider-group addresses your Rolter virtual key is authorized to use, filtered by the key allow-list.

The `/v1/models` endpoint returns the public model names that are configured in your `rolter.toml` and accessible to the authenticated virtual key. You can use this endpoint to discover which model names to pass in the `model` field of chat, completion, or messages requests.

## What is returned

The response lists every model name this gateway accepts in a `model` field, in three forms:

| Id                   | `owned_by`          | What it is                                                                                                                                                                                                            |
| -------------------- | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gpt-4o`             | `rolter`            | a **route name** from your configuration. A route configured with `model = "gpt-4o"` that targets the upstream model `gpt-4o-2024-11-20` appears as `gpt-4o` — the upstream id stays an internal concern of the route |
| `openai-edge/gpt-4o` | the provider's name | a **provider-pinned address**: this provider, this upstream model, no cross-provider fan-out                                                                                                                          |
| `edge-fleet/gpt-4o`  | the group's name    | a **provider-group address**, balanced across the group's members                                                                                                                                                     |

When virtual keys are configured, the list is filtered to the models that the authenticated key's `models` allow-list permits. A key configured with `models = []` (empty) can see all of them. A key created in the dashboard or through the API only ever sees its own organization's routes, providers and provider groups, and a route an admin narrowed to one project is listed only for that project's keys.

### How the provider-pinned list is built

A provider-pinned address works for any model the provider actually serves, not only the ones your routes mention. To list them, Rolter periodically reads the model catalogue each provider returns to its free model-list request and caches it.

<Note>
  The refresh runs by default, every 15 minutes, and does not need active health checks. Set `[health] catalogue_interval_secs = 0` to turn it off; the provider-pinned entries are then derived from your route targets alone, so a provider that serves more models than your routes name will under-report them. A newly added provider is listed within about half a minute. This changes only what is *listed*: `provider-slug/model` routes either way, so an address you know works even when it is not in the list.
</Note>

At most 200 catalogued models are listed per provider, so one aggregator with a
several-hundred-model catalogue cannot bury the rest of your fleet. Models named
by a route target are always listed, regardless of that cap.

<Note>
  Rolter also exposes a built-in `fake-llm` model that responds locally without forwarding to any upstream. It appears in the model list unless a route your key can use shadows it with the same name. A route another organization owns never hides it, and the dashboard and API refuse `fake-llm` as a route name; only the operator can replace it, from `rolter.toml`. It is useful for testing authentication and connectivity without incurring upstream costs.
</Note>

## Request

**`GET /v1/models`**

### Headers

<ParamField header="Authorization" type="string">
  `Bearer <virtual-key>` — your Rolter virtual key. Required when virtual keys are configured. Omit only when the gateway is running open (no keys configured).
</ParamField>

## Example

<CodeGroup>

```bash curl
curl http://localhost:4000/v1/models \
  -H "Authorization: Bearer sk-rolter-dev"
```

```python OpenAI SDK
from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:4000/v1",
    api_key="sk-rolter-dev",
)

models = client.models.list()
for model in models:
    print(model.id)
```

</CodeGroup>

## Response

```json
{
  "object": "list",
  "data": [
    {
      "id": "gpt-4o",
      "object": "model",
      "owned_by": "rolter"
    },
    {
      "id": "claude",
      "object": "model",
      "owned_by": "rolter"
    },
    {
      "id": "llama",
      "object": "model",
      "owned_by": "rolter"
    },
    {
      "id": "openai-edge/gpt-4o",
      "object": "model",
      "owned_by": "openai-edge"
    },
    {
      "id": "openai-edge/o3-mini",
      "object": "model",
      "owned_by": "openai-edge"
    }
  ]
}
```

<ResponseField name="object" type="string">
  Always `"list"`.
</ResponseField>

<ResponseField name="data" type="array">
  Array of model objects, one per accessible model name.

  <Expandable title="Model object fields">
    <ResponseField name="id" type="string">
      The name you pass as `model` in request bodies: a route name (e.g. `"gpt-4o"`), a provider-pinned address (`"openai-edge/gpt-4o"`), or a provider-group address (`"edge-fleet/gpt-4o"`).
    </ResponseField>

    <ResponseField name="object" type="string">
      Always `"model"`.
    </ResponseField>

    <ResponseField name="owned_by" type="string">
      `"rolter"` for a route name, otherwise the name of the provider or provider group the address pins — so a client can group the list by where each model comes from.
    </ResponseField>

    <ResponseField name="capabilities" type="string[]">
      What the model supports, such as `["vision", "tools"]`. Present on a route name when the route sets `capabilities` in its [advanced settings](/concepts/providers-and-routes#per-model-advanced-settings); omitted otherwise. A label, not a gate: Rolter forwards a request whether or not a capability is listed.
    </ResponseField>

    <ResponseField name="model_type" type="string">
      The model family, such as `"chat"` or `"embedding"`. Present on a route name when the route sets `model_type`.
    </ResponseField>

    <ResponseField name="context_length" type="integer">
      The model's context window in tokens. Present on a route name when the route sets `context_length`. Advertised, not enforced.
    </ResponseField>

  </Expandable>
</ResponseField>

A route's `description` is never listed: it is a free-text note for your team and may hold internal routing notes. Provider-pinned and group addresses carry no metadata, because the gateway does not know their upstream model's properties.

## Virtual key filtering

If your key is scoped to a subset of models, only those appear in the response. For example, a key configured as:

```toml
[[virtual_keys]]
key = "sk-gpt-only"
models = ["gpt-4o"]
```

returns only the `gpt-4o` entry, even if `claude` and `llama` routes are defined. Requesting a model outside the key's allow-list on an inference endpoint returns `403 Forbidden`.

<Tip>
  Use this endpoint from your application at startup to validate that the expected model routes are reachable with the configured key before serving user traffic.
</Tip>
