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

# Model roster

> Every model warpllm can route to, with its published limits.

These tables are generated from
[`crates/warpllm/src/registry/specs.yaml`](https://github.com/warpllm/warpllm/blob/main/crates/warpllm/src/registry/specs.yaml),
the registry compiled into the shipped binary. What you see here is what
warpllm will route.

<Info>
  The roster is **closed**. A name that is not below is an error, not a guess —
  see [Model routing](/concepts/model-routing).
</Info>

<Warning>
  These tables are generated from `main`, so they can be ahead of the package
  you installed. A provider or model added since the last release routes only
  once the next release ships — until then the string resolves on a build from
  source and is rejected by the published packages. The
  [changelog](https://github.com/warpllm/warpllm/blob/main/CHANGELOG.md) says
  what landed in which version.
</Warning>

## Reading the columns

<ResponseField name="Model string" type="what you send">
  The full `provider/model` value for the request's `model` field.
</ResponseField>

<ResponseField name="Sent upstream as" type="what the provider sees">
  Usually the same as the last segment. It differs when warpllm's routing alias
  differs from the provider's own name — every OpenRouter entry, for instance,
  where the provider's identifier is a two-segment slug.
</ResponseField>

<ResponseField name="Context window" type="tokens">
  The provider's published context window, recorded verbatim. Note this is the
  **window**, not the provider's "maximum input tokens" figure, which is
  usually the window minus the output ceiling.
</ResponseField>

<ResponseField name="Max output" type="tokens">
  The provider's published output ceiling.
</ResponseField>

<Warning>
  A dash means the provider **publishes no figure** — never that the limit is
  unlimited. The registry omits a number rather than guessing one.
</Warning>

### anthropic

Base URL `https://api.anthropic.com/v1` · API key `ANTHROPIC_API_KEY`

| Model string | Sent upstream as | Context window | Max output | Streaming |
| - | - | - | - | - |
| `anthropic/claude-fable-5` | `claude-fable-5` | 1,000,000 | 128,000 | Yes |
| `anthropic/claude-fable-5-1` | `claude-fable-5-1` | 1,000,000 | 128,000 | Yes |
| `anthropic/claude-haiku-4-5` | `claude-haiku-4-5-20251001` | 200,000 | 64,000 | Yes |
| `anthropic/claude-haiku-5-5` | `claude-haiku-5-5` | 1,000,000 | 128,000 | Yes |
| `anthropic/claude-opus-4-5` | `claude-opus-4-5-20251101` | 200,000 | 64,000 | Yes |
| `anthropic/claude-opus-4-6` | `claude-opus-4-6` | 1,000,000 | 128,000 | Yes |
| `anthropic/claude-opus-4-7` | `claude-opus-4-7` | 1,000,000 | 128,000 | Yes |
| `anthropic/claude-opus-4-8` | `claude-opus-4-8` | 1,000,000 | 128,000 | Yes |
| `anthropic/claude-opus-5` | `claude-opus-5` | 1,000,000 | 128,000 | Yes |
| `anthropic/claude-opus-5-5` | `claude-opus-5-5` | 1,000,000 | 128,000 | Yes |
| `anthropic/claude-sonnet-4-5` | `claude-sonnet-4-5-20250929` | 200,000 | 64,000 | Yes |
| `anthropic/claude-sonnet-4-6` | `claude-sonnet-4-6` | 1,000,000 | 128,000 | Yes |
| `anthropic/claude-sonnet-5` | `claude-sonnet-5` | 1,000,000 | 128,000 | Yes |
| `anthropic/claude-sonnet-5-5` | `claude-sonnet-5-5` | 1,000,000 | 128,000 | Yes |

### deepseek

Base URL `https://api.deepseek.com` · API key `DEEPSEEK_API_KEY`

| Model string | Sent upstream as | Context window | Max output | Streaming |
| - | - | - | - | - |
| `deepseek/deepseek-flash` | `deepseek-flash` | 1,000,000 | 384,000 | Yes |
| `deepseek/deepseek-v4-flash` | `deepseek-v4-flash` | 1,000,000 | 384,000 | Yes |
| `deepseek/deepseek-v4-pro` | `deepseek-v4-pro` | 1,000,000 | 384,000 | Yes |

### kimi

Base URL `https://api.moonshot.ai/v1` · API key `MOONSHOT_API_KEY`

| Model string | Sent upstream as | Context window | Max output | Streaming |
| - | - | - | - | - |
| `kimi/kimi-k2.6` | `kimi-k2.6` | 262,144 | — | Yes |
| `kimi/kimi-k2.7-code` | `kimi-k2.7-code` | 262,144 | — | Yes |
| `kimi/kimi-k2.7-code-highspeed` | `kimi-k2.7-code-highspeed` | 262,144 | — | Yes |
| `kimi/kimi-k3` | `kimi-k3` | 1,048,576 | — | Yes |

### mistral

Base URL `https://api.mistral.ai/v1` · API key `MISTRAL_API_KEY`

| Model string | Sent upstream as | Context window | Max output | Streaming |
| - | - | - | - | - |
| `mistral/codestral-2508` | `codestral-2508` | 128,000 | — | Yes |
| `mistral/ministral-14b-2512` | `ministral-14b-2512` | 256,000 | — | Yes |
| `mistral/ministral-3b-2512` | `ministral-3b-2512` | 256,000 | — | Yes |
| `mistral/ministral-8b-2512` | `ministral-8b-2512` | 256,000 | — | Yes |
| `mistral/mistral-large-2512` | `mistral-large-2512` | 256,000 | — | Yes |
| `mistral/mistral-small-2603` | `mistral-small-2603` | 256,000 | — | Yes |

### openai

Base URL `https://api.openai.com/v1` · API key `OPENAI_API_KEY`

| Model string | Sent upstream as | Context window | Max output | Streaming |
| - | - | - | - | - |
| `openai/gpt-4.1` | `gpt-4.1` | 1,047,576 | 32,768 | Yes |
| `openai/gpt-4.1-mini` | `gpt-4.1-mini` | 1,047,576 | 32,768 | Yes |
| `openai/gpt-4o` | `gpt-4o` | 128,000 | 16,384 | Yes |
| `openai/gpt-4o-mini` | `gpt-4o-mini` | 128,000 | 16,384 | Yes |
| `openai/gpt-5` | `gpt-5` | 400,000 | 128,000 | Yes |
| `openai/gpt-5-mini` | `gpt-5-mini` | 400,000 | 128,000 | Yes |
| `openai/gpt-5-nano` | `gpt-5-nano` | 400,000 | 128,000 | Yes |
| `openai/gpt-5.1` | `gpt-5.1` | 400,000 | 128,000 | Yes |
| `openai/gpt-5.2` | `gpt-5.2` | 400,000 | 128,000 | Yes |
| `openai/gpt-5.4` | `gpt-5.4` | 1,050,000 | 128,000 | Yes |
| `openai/gpt-5.4-mini` | `gpt-5.4-mini` | 400,000 | 128,000 | Yes |
| `openai/gpt-5.4-nano` | `gpt-5.4-nano` | 400,000 | 128,000 | Yes |
| `openai/gpt-5.5` | `gpt-5.5` | 1,050,000 | 128,000 | Yes |
| `openai/gpt-5.6` | `gpt-5.6` | 1,050,000 | 128,000 | Yes |
| `openai/gpt-5.6-luna` | `gpt-5.6-luna` | 1,050,000 | 128,000 | Yes |
| `openai/gpt-5.6-sol` | `gpt-5.6-sol` | 1,050,000 | 128,000 | Yes |
| `openai/gpt-5.6-terra` | `gpt-5.6-terra` | 1,050,000 | 128,000 | Yes |
| `openai/gpt-6-astra` | `gpt-6-astra` | 1,050,000 | 128,000 | Yes |
| `openai/gpt-6-luna` | `gpt-6-luna` | 1,050,000 | 128,000 | Yes |
| `openai/gpt-6-sol` | `gpt-6-sol` | 1,050,000 | 128,000 | Yes |
| `openai/gpt-6.1-sol` | `gpt-6.1-sol` | 1,050,000 | 128,000 | Yes |
| `openai/o3` | `o3` | 200,000 | 100,000 | Yes |

### opencode

Base URL `https://opencode.ai/zen/v1` · API key `OPENCODE_API_KEY`

| Model string | Sent upstream as | Context window | Max output | Streaming |
| - | - | - | - | - |
| `opencode/big-pickle` | `big-pickle` | — | — | Yes |
| `opencode/deepseek-v4-flash` | `deepseek-v4-flash` | — | — | Yes |
| `opencode/deepseek-v4-flash-vision-exp` | `deepseek-v4-flash-vision-exp` | — | — | Yes |
| `opencode/deepseek-v4-pro` | `deepseek-v4-pro` | — | — | Yes |
| `opencode/deepseek-v4.1-flash` | `deepseek-v4.1-flash` | — | — | Yes |
| `opencode/exo-free` | `exo-free` | — | — | Yes |
| `opencode/glm-5.1` | `glm-5.1` | — | — | Yes |
| `opencode/glm-5.2` | `glm-5.2` | — | — | Yes |
| `opencode/glm-5.3` | `glm-5.3` | — | — | Yes |
| `opencode/glm-5.3-flash` | `glm-5.3-flash` | — | — | Yes |
| `opencode/kimi-k2.6` | `kimi-k2.6` | — | — | Yes |
| `opencode/kimi-k2.7-code` | `kimi-k2.7-code` | — | — | Yes |
| `opencode/kimi-k3` | `kimi-k3` | — | — | Yes |
| `opencode/ling-3.0-flash-fin-free` | `ling-3.0-flash-fin-free` | — | — | Yes |
| `opencode/ling-3.1-flash-free` | `ling-3.1-flash-free` | — | — | Yes |
| `opencode/longcat-2.5-preview-free` | `longcat-2.5-preview-free` | — | — | Yes |
| `opencode/mimo-v2.5-free` | `mimo-v2.5-free` | — | — | Yes |
| `opencode/mimo-v2.6-flash-free` | `mimo-v2.6-flash-free` | — | — | Yes |
| `opencode/minimax-m2.7` | `minimax-m2.7` | — | — | Yes |
| `opencode/minimax-m3` | `minimax-m3` | — | — | Yes |
| `opencode/mistral-large-4` | `mistral-large-4` | — | — | Yes |
| `opencode/nemotron-3-ultra-free` | `nemotron-3-ultra-free` | — | — | Yes |
| `opencode/nemotron-3.5-lightning-free` | `nemotron-3.5-lightning-free` | — | — | Yes |
| `opencode/qwen3.8-max` | `qwen3.8-max` | — | — | Yes |
| `opencode/space-bunny-free` | `space-bunny-free` | — | — | Yes |
| `opencode/step-5-preview-free` | `step-5-preview-free` | — | — | Yes |

### openrouter

Base URL `https://openrouter.ai/api/v1` · API key `OPENROUTER_API_KEY`

| Model string | Sent upstream as | Context window | Max output | Streaming |
| - | - | - | - | - |
| `openrouter/anthropic/claude-opus-4` | `anthropic/claude-opus-4` | 200,000 | 32,000 | Yes |
| `openrouter/anthropic/claude-opus-5.5` | `anthropic/claude-opus-5.5` | 1,000,000 | 128,000 | Yes |
| `openrouter/anthropic/claude-sonnet-4` | `anthropic/claude-sonnet-4` | 200,000 | 64,000 | Yes |
| `openrouter/anthropic/claude-sonnet-5.5` | `anthropic/claude-sonnet-5.5` | 1,000,000 | 128,000 | Yes |
| `openrouter/auto` | `auto` | — | — | Yes |
| `openrouter/google/gemini-2.5-pro` | `google/gemini-2.5-pro` | 1,048,576 | 65,536 | Yes |
| `openrouter/google/gemini-3.1-pro-preview` | `google/gemini-3.1-pro-preview` | 1,048,576 | 65,536 | Yes |
| `openrouter/moonshotai/kimi-k2.6` | `moonshotai/kimi-k2.6` | 256,000 | — | Yes |
| `openrouter/moonshotai/kimi-k2.7-code` | `moonshotai/kimi-k2.7-code` | 256,000 | — | Yes |
| `openrouter/moonshotai/kimi-k3` | `moonshotai/kimi-k3` | 974,842 | — | Yes |
| `openrouter/openai/gpt-5.6` | `openai/gpt-5.6` | 1,050,000 | 128,000 | Yes |
| `openrouter/openai/gpt-6.1-sol` | `openai/gpt-6.1-sol` | 1,050,000 | 128,000 | Yes |
| `openrouter/~deepseek/deepseek-v4-flash-latest` | `~deepseek/deepseek-v4-flash-latest` | 1,048,576 | — | Yes |

## About the OpenRouter entries

OpenRouter is an aggregator, so each entry is a curated pick from its catalog
rather than a catch-all. One slug is not one model on one host: it fans out
across every provider serving those weights, and they disagree about limits.

The registry records the **narrowest** figure any endpoint offers, because an
unpinned request may land on any of them. Where the spread is too wide to
promise anything — `moonshotai/kimi-k2.6` runs across 21 endpoints whose max
output spans 16,384 to 262,144 — the limit is omitted instead.

`openrouter/auto` is OpenRouter's alias for letting it pick the model per
request, so it carries no limits at all.

## About the OpenCode Zen entries

Zen re-hosts other people's models, and it is the first provider here that does
not serve its whole catalog over one protocol — it publishes an endpoint **per
model**. Only `/chat/completions` is a surface warpllm implements, so that is
what the `opencode` provider is.

Its GPT, Grok, and Muse models are absent because they sit on the Responses
API; its Claude and Qwen models speak Anthropic's `/messages`, and its Gemini
models Google's own shape. None of those have an `api:` here yet, and
registering them would hand back a model string that resolves and then fails
upstream on every request.

`anthropic_messages` is now implemented and routable — the `anthropic` provider
uses it — so Zen's Claude models are a data entry rather than a blocked one.
What is missing is the endpoint mapping: Zen serves them at `/zen/v1/messages`
and a provider entry carries ONE `base_url`, so registering them needs a second
`anthropic`-speaking provider entry pointed at that path. Its GPT, Grok, Muse
and Gemini models still wait on
[#41](https://github.com/warpllm/warpllm/issues/41) and
[#35](https://github.com/warpllm/warpllm/issues/35).

No entry carries `capabilities`: Zen publishes a price per model and no context
window, output ceiling, or concurrency figure. Every model is re-hosted, so the
original provider's numbers are not Zen's to promise.

## What is deliberately absent

The registry leaves out more than it includes, and each omission is recorded
with a reason in `specs.yaml`. The recurring ones:

<AccordionGroup>
  <Accordion title="Models on a surface warpllm does not serve" icon="ban">
    Embeddings, moderation, images, audio, realtime, and legacy completions.
    Also OpenAI's `-pro` models, which serve the Responses API rather than chat
    completions.
  </Accordion>

  <Accordion title="Models with a near retirement date" icon="calendar-xmark">
    Registering a name that breaks within the quarter would hand callers a
    migration. Where a provider names a replacement, the replacement is on the
    roster instead.
  </Accordion>

  <Accordion title="Moving aliases" icon="shuffle">
    OpenAI's `chat-latest` serves chat completions, but the snapshot underneath
    it moves — so any limits recorded for it would go stale without the file
    changing.
  </Accordion>

  <Accordion title="Dated snapshots" icon="clock">
    `gpt-5-2025-08-07` and its kind. The aliases are what callers name.
  </Accordion>
</AccordionGroup>

## Keeping this page honest

The tables are regenerated from the registry rather than maintained by hand:

```bash theme={null}
uv run --with pyyaml docs/scripts/gen_model_roster.py
```

Add `--check` to fail instead of rewriting, which is what CI should run so a
registry change cannot ship without the docs following.

## Next

<CardGroup cols={2}>
  <Card title="Add a model" icon="plus" href="/models/add-a-model">
    The registry edit and the rules its tests enforce.
  </Card>

  <Card title="Model routing" icon="route" href="/concepts/model-routing">
    How these strings resolve at request time.
  </Card>
</CardGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.