# Models & catalog

The catalog is one flat list of model ids. Every **chat** model works with one key on both APIs: OpenAI-compatible `/v1/chat/completions` and Anthropic-compatible `/v1/messages`. Image models answer only on `POST /v1/images/generations`, and decision models only on `POST /v1/decisions`. You pay the per-token prices in the catalog, and every billed response has `usage.cost`.

| Surface | URL | Auth | For |
|---|---|---|---|
| Model directory | `https://demo.routerplus.com/` | none | Browsing, filters, featured model order |
| Per-model pages | `https://demo.routerplus.com/models/<id>` | none | Providers with prices, latency, uptime and data policy; snippets to copy |
| Machine-readable JSON | `https://demo.routerplus.com/api/models.json` | none | Scripts, dashboards, price checks |
| SDK-shaped list | `https://demo-api.routerplus.com/v1/models` | API key | `client.models.list()`. See [GET /v1/models](/docs/api-models) |

## Model ids

Ids are exact strings. RouterPlus does no fuzzy matching and no substitution. An id that is not in the catalog is a 404 that names the id you sent.

The table shows the catalog at the time of writing. The live list is [`/api/models.json`](https://demo.routerplus.com/api/models.json).

| Model id | Providers | Context | Input /1M | Cached /1M | Cache write /1M | Output /1M |
|---|---|---|---|---|---|---|
| `claude-opus-5-5` | anthropic, deepinfra-labs, inference-net-chat | 1M | $4 | $0.2 | $5 | $20 |
| `claude-fable-5-1` | anthropic | 1M | $10 | $0.25 | $12.5 | $50 |
| `claude-sonnet-5-5` | anthropic, deepinfra-labs | 1M | $2 | $0.1 | $2.5 | $10 |
| `claude-haiku-5-5` | anthropic | 1M | $0.1 | $0.01 | $0.125 | $0.5 |
| `gpt-6-astra` | openai, inference-net-chat | 1.05M | $10 | $1 | $12.5 | $50 |
| `gpt-6.1-sol` | openai | 1.05M | $2 | $0.1 | $2.5 | $10 |
| `gpt-6-luna` | openai, inference-net-chat | 1.05M | $0.1 | $0.01 | $0.125 | $0.5 |
| `gpt-5.6-terra` | openai, inference-net-chat | 1.05M | $2 | $0.2 | $2.5 | $12 |
| `gpt-6-sol` | openai | 1.05M | $2 | $0.2 | $2.5 | $10 |
| `gpt-5.6-sol` | openai, inference-net-chat | 1.05M | $4 | $0.4 | $5 | $20 |
| `gpt-5.6-luna` | openai, inference-net-chat | 1.05M | $0.2 | $0.02 | $0.25 | $1.2 |
| `claude-sonnet-5` | anthropic | 1M | $2 | $0.2 | $2.5 | $10 |
| `claude-opus-5` | anthropic, deepinfra-labs, inference-net-chat | 1M | $5 | $0.5 | $6.25 | $25 |
| `claude-fable-5` | anthropic, deepinfra-labs, inference-net-chat | 1M | $10 | $1 | $12.5 | $50 |
| `claude-sonnet-4-5` | anthropic | 200K | $3 | $0.3 | $3.75 | $15 |
| `claude-haiku-4-5` | anthropic, deepinfra-labs, inference-net-chat | 200K | $1 | $0.1 | $1.25 | $5 |
| `gpt-4o-mini` | openai, inference-net-chat | 128K | $0.15 | $0.075 | – | $0.6 |
| `gpt-4.1-mini` | openai, inference-net-chat | 1.05M | $0.4 | $0.1 | – | $1.6 |
| `gpt-4o` | openai, inference-net-chat | 128K | $2.5 | $1.25 | – | $10 |
| `deepseek/deepseek-v4.1-flash` | runinfra-chat, doubleword-chat, wafer, inference-net-chat, morphllm, deepinfra-chat, nebius-chat, novita-chat | 1.05M | $0.3 | $0.006 | – | $1.2 |
| `tencent/hy4-preview` | deepinfra-chat, novita-chat | 1.05M | $0.834 | $0.042 | – | $2.501 |
| `z-ai/glm-5.3-flash` | wafer, sail-research-chat, inference-net-chat, runinfra-chat, morphllm, deepinfra-chat, nebius-chat, novita-chat | 1.05M | $0.15 | $0.015 | – | $0.5 |
| `z-ai/glm-5.3` | wafer, inference-net-chat, sail-research-chat, runinfra-chat, morphllm, deepinfra-chat, mistral-ai, nebius-chat | 1.05M | $1.4 | $0.06 | – | $4.4 |
| `deepseek/deepseek-v4-flash-0731` | sail-research-chat, doubleword-chat, deepinfra-chat, nebius-chat, streamlake, chutes-chat, inference-net-chat | 1.05M | $0.14 | $0.015 | – | $0.28 |
| `moonshotai/kimi-k3` | chutes-chat, sail-research-chat, wafer, morphllm, deepinfra-chat, nebius-chat, novita-chat, inference-net-chat | 1.05M | $3 | $0.285 | – | $15 |
| `z-ai/glm-5.2` | doubleword-chat, wafer, chutes-chat, inference-net-chat, morphllm, deepinfra-chat, novita-chat, streamlake | 1.05M | $1.4 | $0.26 | – | $4.4 |
| `minimax/minimax-m3` | deepinfra-chat, nebius-chat, streamlake | 524K | $0.3 | $0.056 | – | $1.2 |
| `minimax/minimax-m3.1-flash` | streamlake | 1M | $0.15 | $0.015 | – | $0.6 |
| `deepseek/deepseek-v4-pro` | deepinfra-chat, novita-chat, streamlake, inference-net-chat | 1.05M | $1.6 | $0.135 | – | $3.2 |
| `deepseek/deepseek-v4-pro-0813` | sail-research-chat, deepinfra-chat, nebius-chat, novita-chat, streamlake, doubleword-chat | 1.05M | $1.32 | $0.1 | – | $3.96 |
| `google/gemma-4-31b-it` | deepinfra-chat, novita-chat, sail-research-chat, doubleword-chat | 262K | $0.2 | – | – | $0.4 |
| `qwen/qwen3.6-27b` | chutes-chat, deepinfra-chat, streamlake | 262K | $0.32 | – | – | $3.2 |
| `qwen/qwen3.6-35b-a3b` | deepinfra-chat, doubleword-chat, streamlake | 262K | $0.1 | $0.1 | – | $0.95 |
| `xiaomi/mimo-v2.6-pro` | deepinfra-chat, novita-chat | 1.05M | $0.435 | $0.0036 | – | $0.87 |
| `xiaomi/mimo-v2.6-flash` | deepinfra-chat, novita-chat | 1.05M | $0.14 | $0.0028 | – | $0.28 |
| `tencent/hy3` | novita-chat | 262K | $0.14 | $0.035 | – | $0.58 |
| `claude-opus-4-8` | deepinfra-labs, inference-net-chat | 1M | $5 | – | – | $25 |
| `claude-opus-4-7` | deepinfra-labs, inference-net-chat | 1M | $5 | – | – | $25 |
| `claude-sonnet-4-6` | deepinfra-labs, inference-net-chat | 1M | $3 | – | – | $15 |
| `google/gemini-3.7-flash` | deepinfra-labs, inference-net-chat | 1M | $0.75 | – | – | $3.75 |
| `google/gemini-3.5-flash` | deepinfra-labs, inference-net-chat | 1M | $1.5 | – | – | $9 |
| `google/gemini-3.1-pro` | deepinfra-labs | 1M | $2 | – | – | $12 |
| `google/gemini-3.1-flash-lite` | deepinfra-labs, inference-net-chat | 1M | $0.25 | – | – | $1.5 |
| `google/gemini-2.5-pro` | deepinfra-labs, inference-net-chat | 1M | $1.25 | – | – | $10 |
| `google/gemini-2.5-flash` | deepinfra-labs, inference-net-chat | 1M | $0.3 | – | – | $2.5 |
| `openai/gpt-oss-120b` | deepinfra-chat | 131K | $0.037 | – | – | $0.17 |
| `openai/gpt-oss-20b` | deepinfra-chat | 131K | $0.03 | – | – | $0.14 |
| `morph/morph-v3-fast` | morphllm | 262K | $0.8 | – | – | $1.2 |
| `morph/morph-v3-large` | morphllm | 262K | $0.9 | – | – | $1.9 |
| `morph/kimi-k3-fast` | morphllm | 1.05M | $6 | $0.6 | – | $22.5 |
| `mistral-large-4` | mistral-ai | 1.05M | $1.36 | $0.14 | – | $4.18 |
| `mistral-medium-2604` | mistral-ai | 262K | $1.5 | $1.5 | – | $7.5 |
| `mistral-small-2603` | mistral-ai | 262K | $0.15 | $0.15 | – | $0.6 |
| `mistral-large-2512` | mistral-ai | 262K | $0.5 | $0.5 | – | $1.5 |
| `ministral-14b-2512` | mistral-ai | 262K | $0.2 | $0.2 | – | $0.2 |
| `ministral-8b-2512` | mistral-ai | 262K | $0.15 | $0.15 | – | $0.15 |
| `ministral-3b-2512` | mistral-ai | 131K | $0.1 | $0.1 | – | $0.1 |
| `codestral-2508` | mistral-ai | 256K | $0.3 | $0.3 | – | $0.9 |
| `qwen/qwen3.5-397b-a17b` | chutes-chat, nebius-chat, streamlake | 262K | $0.6 | $0.6 | – | $3.6 |
| `qwen/qwen3-235b-a22b-2507` | nebius-chat | 262K | $0.2 | $0.2 | – | $0.6 |
| `qwen/qwen3.8-27b` | runinfra-chat, chutes-chat, wafer, nebius-chat, doubleword-chat, streamlake | 262K | $0.45 | $0.45 | – | $3 |
| `nvidia/nemotron-3-ultra-550b-a55b` | nebius-chat, doubleword-chat | 1.05M | $1 | $1 | – | $3 |
| `nvidia/nemotron-3.5-lightning` | nebius-chat, runinfra-chat | 1.05M | $0.06 | $0.06 | – | $0.24 |
| `moonshotai/kimi-k2.6` | chutes-chat, nebius-chat, streamlake, inference-net-chat | 262K | $0.95 | $0.95 | – | $4 |
| `claude-opus-4-6` | inference-net-chat | 1M | $5 | $0.5 | – | $25 |
| `deepseek/deepseek-v4-flash` | streamlake, inference-net-chat | 1M | $0.23 | $0.0028 | – | $0.62 |
| `google/gemini-2.5-flash-lite` | inference-net-chat | 1.05M | $0.1 | $0.01 | – | $0.4 |
| `google/gemini-3-flash-preview` | inference-net-chat | 1.05M | $0.5 | $0.05 | – | $3 |
| `google/gemini-3.1-pro-preview` | inference-net-chat | 1.05M | $2 | $0.2 | – | $12 |
| `google/gemini-3.5-flash-lite` | inference-net-chat | 1.05M | $0.3 | $0.03 | – | $2.5 |
| `google/gemini-3.6-flash` | inference-net-chat | 1.05M | $1.5 | $0.15 | – | $7.5 |
| `google/gemma-3-4b-it` | inference-net-chat | 131K | $0.05 | – | – | $0.1 |
| `z-ai/glm-5` | inference-net-chat, streamlake | 205K | $0.95 | $0.2 | – | $2.55 |
| `z-ai/glm-5.2-fast` | inference-net-chat | 1M | $2.6 | $0.4 | – | $8.8 |
| `gpt-4.1` | inference-net-chat | 1.05M | $2 | $0.5 | – | $8 |
| `gpt-4.1-nano` | inference-net-chat | 1.05M | $0.1 | $0.025 | – | $0.4 |
| `gpt-5-mini` | inference-net-chat | 400K | $0.25 | $0.025 | – | $2 |
| `gpt-5-nano` | inference-net-chat | 400K | $0.05 | $0.005 | – | $0.4 |
| `gpt-5.4` | inference-net-chat | 1.05M | $2.5 | $0.25 | – | $15 |
| `gpt-5.5` | inference-net-chat | 1.05M | $5 | $0.5 | – | $30 |
| `x-ai/grok-4.5` | inference-net-chat | 500K | $2 | $0.3 | – | $6 |
| `x-ai/grok-4.6` | inference-net-chat | 500K | $2 | $0.5 | – | $6 |
| `moonshotai/kimi-k2.5` | inference-net-chat | 262K | $0.8 | $0.13 | – | $3.95 |
| `moonshotai/kimi-k3-fast` | inference-net-chat | 1.05M | $4.5 | $0.45 | – | $22.5 |
| `meta-llama/llama-3.2-1b-instruct` | inference-net-chat | 60K | $0.027 | – | – | $0.201 |
| `meta-llama/llama-3.2-3b-instruct` | inference-net-chat | 131K | $0.05 | – | – | $0.33 |
| `meta-llama/llama-3.3-70b-instruct` | inference-net-chat | 131K | $0.13 | – | – | $0.4 |
| `nvidia/nemotron-3-super-120b-a12b` | inference-net-chat | 262K | $0.102 | – | – | $0.48 |
| `qwen/qwen3-14b` | inference-net-chat | 131K | $0.2275 | – | – | $0.91 |
| `qwen/qwen3-30b-a3b` | inference-net-chat | 41K | $0.12 | – | – | $0.5 |
| `qwen/qwen3.7-plus` | inference-net-chat | 1M | $0.4 | $0.08 | – | $1.6 |
| `inference-net/schematron-v2-small` | inference-net-chat | 128K | $0.05 | $0.05 | – | $0.23 |
| `inference-net/schematron-v2-turbo` | inference-net-chat | 128K | $0.03 | $0.03 | – | $0.15 |
| `deepseek/deepseek-v4.1-flash-1017` | sail-research-chat, wafer, runinfra-chat, doubleword-chat, particle | 1.05M | $0.15 | $0.01 | – | $0.6 |
| `ornith-ai/ornith-1.5-122b` | runinfra-chat | 262K | $0.26 | $0.07 | – | $2.08 |
| `ornith-ai/ornith-1.5-35b-a3b` | runinfra-chat | 262K | $0.1 | $0.01 | – | $0.4 |
| `google/gemma-4-31b-it-nvfp4` | chutes-chat, sail-research-chat | 262K | $0.14 | $0.07 | – | $0.4 |
| `google/gemma-4-12b-it` | sail-research-chat | 16K | $0.3 | $0.15 | – | $2 |
| `deepseek/deepseek-v3.2` | chutes-chat | 131K | $1 | $0.1 | – | $1 |
| `z-ai/glm-5.1` | chutes-chat | 203K | $0.9 | $0.09 | – | $2.9 |
| `qwen/qwen3-vl-235b-a22b-instruct` | doubleword-chat | 262K | $0.21 | $0.1155 | $0.2625 | $1.9 |
| `qwen/qwen3.5-35b-a3b-dottxt` | doubleword-chat | 262K | $0.35 | $0.19999 | $0.4375 | $1.2 |
| `particle-ai/particle-1` | particle | 1.05M | $0.25 | $0.03 | – | $1 |

### Provider order

The Providers column lists, cheapest first, the routes that a request with no provider named can use. It has at most eight routes. [Provider routing](/docs/provider-routing) describes how RouterPlus picks among them.

- A provider past those eight can still be chosen with `provider.only` or `provider.order`. These providers are past the eight: `novita-chat`, `streamlake` and `doubleword-chat` on `z-ai/glm-5.3`; `streamlake`, `doubleword-chat` and `particle` on `z-ai/glm-5.3-flash`; `streamlake` on `deepseek/deepseek-v4.1-flash`; `doubleword-chat` on `moonshotai/kimi-k3`.
- The column order is not the order RouterPlus tries. By default RouterPlus orders a model's providers by Routing Cost, the lowest cost per good answer, and providers inside the competitive band share traffic. Before a provider has measurements, the order is cheapest first. `provider.order` or `provider.sort` in the request overrides the default. See [Provider routing](/docs/provider-routing#default-order-lowest-cost-per-good-answer).
- The Claude models have two providers at the same price: Anthropic and DeepInfra (`deepinfra-labs`).
- On the open models that Morph and DeepInfra both serve, Morph comes before DeepInfra when their prices are equal. On GLM 5.3, Mistral follows both at that same price.
- Chutes (`chutes-chat`) is first on Gemma 4 31B NVFP4, Kimi K2.6, Kimi K3, Qwen3.5 397B A17B and Qwen3.6 27B. It is second on GLM 5.2 (after `doubleword-chat`) and Qwen3.8 27B (after `runinfra-chat`). A request routed to Chutes is billed Chutes's own price, which on those seven is below the row's list price.
- On DeepSeek V4 Flash 0731, Chutes costs more than the row and is sixth, after `streamlake` at the same price.
- On DeepSeek V4 Flash, `streamlake` is first, at its own price, below the row's.

[`/api/models.json`](https://demo.routerplus.com/api/models.json) lists every provider of a model and its price.

### Model notes

- **Featured order.** The first eleven rows lead the Models page and the playground in this order.
- **MiniMax on StreamLake.** On StreamLake, `minimax/minimax-m3` and `minimax/minimax-m3.1-flash` accept text only. Those routes also refuse requests above 512,000 bytes of encoded JSON, because larger inputs can need a different rate. MiniMax M3 image requests can use its other providers. M3.1 Flash has no other provider, so an image request returns a 400 before RouterPlus calls the provider.
- **Qwen3.6 35B A3B on StreamLake.** StreamLake serves `qwen/qwen3.6-35b-a3b` with internal reasoning off, to keep output within the requested token limit. A requested reasoning effort other than `none` appears in `x-tm-dropped-params`. With `provider.require_parameters: true`, that request cannot use this route.
- **Gemma 4 31B NVFP4.** `google/gemma-4-31b-it-nvfp4` has the same weights as `google/gemma-4-31b-it`, quantized to NVFP4 (NVIDIA's 4-bit floating-point format), so it has its own row. Its 262K context is the largest of its routes. Chutes, tried first, holds 131,072 tokens. A longer prompt goes to `sail-research-chat`, which holds 262,144.
- **GPT-6 and GPT-5.6.** RouterPlus calls OpenAI's seven GPT-6 and GPT-5.6 models on OpenAI's Responses API, where they take function tools and custom (free-form) tools. You can call them on either chat API, or on [POST /v1/responses](/docs/api-responses). On these seven, the chat APIs drop `stop`, `n`, `seed`, `logprobs`, `logit_bias` and the penalties. An output limit under 16 tokens is sent as 16.
- **Default sampling only.** The Claude 5 models (Opus, Fable, Sonnet and Haiku) and OpenAI's GPT-6 and GPT-5.6 models take only their default sampling. Their providers refuse `temperature` other than 1, and any `top_p` or `top_k`, with a 400. RouterPlus leaves these out for those models on every route. `x-tm-dropped-params` names each drop, except `temperature: 1` and `top_p: 1`, which change nothing. Under `require_parameters`, a drop is a 400.
- **Long prompts.** OpenAI bills a prompt over 272K input tokens at twice the input rate and 1.5 times the output rate. Anthropic bills a Claude Haiku 5.5 prompt over 100K tokens at five times its rate. The catalog lists the base rate.
- **Your deployed models.** A model or mix you deploy from [Optimize](/docs/model-search) gets its own id, `tm/<name>-v<n>`. Call it on `POST /v1/chat/completions` with a key of the organization that owns it. It is not listed in the catalog.

### Fast Apply (code merge)

`morph/morph-v3-fast` and `morph/morph-v3-large` merge an edit into a file. They are chat models on `POST /v1/chat/completions` that take one user message with the instruction, the original file and the edit, each in its own tag. The edit can skip unchanged lines with `// ... existing code ...` (or `# ...` in Python). The reply's `content` is the complete merged file.

```bash
curl https://demo-api.routerplus.com/v1/chat/completions \
  -H "Authorization: Bearer $TM_API_KEY" -H "content-type: application/json" \
  -d '{"model":"morph/morph-v3-fast",
       "messages":[{"role":"user","content":"<instruction>Add an optional third number</instruction>\n<code>def total(a, b):\n    return a + b</code>\n<update>def total(a, b, c=0):\n    # ... existing code ...\n    return a + b + c</update>"}]}'
```

### Image models

Image models bill in tokens and answer only on [POST /v1/images/generations](/docs/api-images). The per-image ceiling is the most output tokens one image can bill. The balance hold is `n` times the ceiling.

| Model id | Sizes | Qualities | Per-image ceiling | Text in /1M | Image out /1M |
|---|---|---|---|---|---|
| `gpt-image-1` | `1024x1024 · 1536x1024 · 1024x1536` | `low · medium · high` | 6,240 | $5 | $40 |
| `gpt-image-1-mini` | `1024x1024 · 1536x1024 · 1024x1536` | `low · medium · high` | 6,500 | $2 | $8 |
| `gpt-image-1.5` | `1024x1024 · 1536x1024 · 1024x1536` | `low · medium · high` | 6,500 | $5 | $32 |
| `gpt-image-2` | `1024x1024 · 1536x1024 · 1024x1536` | `low · medium · high` | 8,232 | $5 | $30 |
| `gpt-image-2.5-flare` | `1024x1024 · 1536x1024 · 1024x1536` | `low · medium · high · xhigh · max` | 8,232 | $5 | $30 |
| `gpt-image-2.5-sunburst` | `1024x1024 · 1536x1024 · 1024x1536` | `low · medium · high · xhigh · max` | 8,232 | $5 | $30 |

`size` and `quality` also accept `auto`, which lets the provider choose. Each model's full descriptor map is in `/api/models.json` under `supported_parameters`.

### Decision models

Decision models answer only on [POST /v1/decisions](/docs/api-decisions). They write no text. They return one typed answer for each question about a state. Each model takes its own question format.

| Model id | Made by | Providers | Question kinds | Input /1M | Cached /1M |
|---|---|---|---|---|---|
| `typesafe/jev-1.13` | TypeSafe | `typesafe` | choice, score, yes/no (System One) | $0.042 | – |
| `bespokelabs/nimble-v4` | Bespoke Labs | `bespokelabs` | choice, score, yes/no (System One, the same as Jev) | $0.04 | – |
| `bespokelabs/nimble-v4-max` | Bespoke Labs | `bespokelabs` | choice, score, yes/no (System One, the same as Jev) | $0.09 | – |
| `cloudflare/clef` | Cloudflare | `workers-ai` | choice, score, yes/no (System One, the same as Jev) | $0.24 | – |
| `cloudflare/clef-flash` | Cloudflare | `workers-ai` | choice, score, yes/no (System One, the same as Jev) | $0.09 | – |
| `routerplus/decider-2b` | RouterPlus | `routerplus` | choice, score, yes/no (System One, the same as Jev) | $0 | $0 |
| `routerplus/kev-4b` | RouterPlus | `routerplus` | choice, score, yes/no (System One, the same as Jev) | $0 | $0 |
| `perplexity/pplx-decider-v1-27b` | Perplexity | `perplexity-decisions` | choice, score, yes/no (System One, the same as Jev) | $0.04 | – |
| `openai/gpt-6-luna-decisions` | OpenAI | `openai-decisions` | choice, score, yes/no (System One, the same as Jev) | $0.10 | – |
| `levanto/sage-1.2` | Levanto | `levanto` | choice, score, yes/no (System One, the same as Jev) | $0.05 | – |
| `scaledown/classify-1` | ScaleDown | `scaledown` | choice, score, yes/no (System One, the same as Jev) | $0.05 | – |
| `fastino/gliner-2.5-decide` | Fastino | `fastino` | classifications (single- and multi-label), entities, structures, relations | $0.03 | – |

Output is free on every decision model. A discount can apply to decision models: see [Pricing](/docs/pricing).

**Bespoke Nimble v4 and v4 Max**

- Nimble v4 is $0.04 per million input tokens, and Nimble v4 Max is $0.09. These are Bespoke's own prices with no markup.
- Nimble v4 is the faster, lower-cost model. v4 Max is Bespoke's most accurate model.
- Both have a 262,144-token context for each question's prompt, including the state, and take 1 to 64 questions per call.
- They share one pool, which takes 7 requests at once (5 per organization). Bespoke allows the RouterPlus account 8, and RouterPlus keeps one for its test environment.
- The gateway also accepts `bespokelabs/nimble-latest`, which the table does not list. Bespoke picks the model that answers it (Nimble v4 at the time of writing), at $0.04 per million input tokens.

**Clef and Clef-flash**

- Cloudflare's own decision models. Cloudflare Workers AI serves them at Cloudflare's own price with no markup: $0.24 and $0.09 per million input tokens.
- They take 1 to 64 questions per call, each question id 1 to 100 letters, digits, `_`, `.` or `-`, and a context of 65,536 tokens.
- They share one pool: 200 requests a minute (150 per organization) and at most 8 at a time (6 per organization).

**Decider 2B and Kev 4B**

- RouterPlus's own models, on RouterPlus GPUs in the United States, and free: $0 in and out.
- They share one pool. Their contexts are 25,600 and 8,192 tokens.
- RouterPlus answers an identical request from its cache for 600 s.

**Perplexity Decider v1 27B**

- Perplexity's own decision model, served by Perplexity's API at Perplexity's own price with no markup: $0.04 per million input tokens.
- Perplexity bills the state once per question, so the cost grows with the number of questions.
- It takes 1 to 128 questions per call, and 262,144 tokens for each question's prompt.
- Its pool takes 540 requests a minute (405 per organization) and 8 at once (6 per organization).

**GPT-6 Luna Decisions**

- OpenAI's own decision model, served by OpenAI's API at OpenAI's own price with no markup: $0.10 per million input tokens.
- OpenAI's API uses its own format. RouterPlus translates your System One body to it, and translates the answers back.
- OpenAI bills the state once per call, and each question adds about 150 input tokens.
- It takes 1 to 200 questions per call, 2 to 255 options in a choice, and a context of 272,000 tokens.
- Its pool takes 24,000 requests a minute (18,000 per organization) and 64 in flight at once (48 per organization), so your organization's own limits apply first.
- OpenAI's own name for it, `gpt-6-luna`, is the RouterPlus id of OpenAI's chat model GPT-6 Luna.

OpenAI can decline one question and answer the rest: that answer's `type` is
`refusal`.

**Sage** bills the state once per question, as Perplexity Decider does.

**ScaleDown Classify-1**

- ScaleDown's Jev-compatible decision model on its `/v1/scaledown` endpoint.
- It costs ScaleDown's own price with no markup: $0.05 per million input tokens, output free, the price of every ScaleDown model.
- It runs each question as its own call, so input grows with the number of questions.
- Its `state` can also carry `document` (a base64 image or PDF) with `document_mime_type`, which ScaleDown reads by OCR.
- Its context is 1,000,000 tokens.

### Cache pricing

Most models also have cache pricing: `cached_prompt` (the Cached column above), and `cache_write` where the provider bills it (the Cache write column). Each model's page and `/api/models.json` have the full prices per SKU. A model with no separate cache or reasoning price bills those tokens **at the base rate**. A missing SKU never means free.

### Task models (ScaleDown)

ScaleDown's two chat models each do one task. Call them on `POST /v1/chat/completions` (or `POST /v1/messages`). The answer's content is a JSON string with the task's result:

| Model id | Task | Input /1M | Cached /1M | Output /1M | Context |
|---|---|---|---|---|---|
| `scaledown/extract-1` | Fields and entities from the last user message, defined by a `response_format` of type `json_schema` (each property is a field; its `description` is the hint) | $0.05 | – | $0 | 1M |
| `scaledown/summarize-1` | An abstractive summary of the last user message; the system message holds instructions, and `max_tokens` is honored | $0.05 | – | $0 | 1M |

- Output is free. These models bill input tokens only, and report 0 output tokens.
- ScaleDown answers in one piece. With `stream: true` you still get a stream (role and content, the finish, usage with its cost, `[DONE]`). The stream starts when the complete answer is ready.
- To classify with ScaleDown, use `scaledown/classify-1` on [POST /v1/decisions](/docs/api-decisions).
- Both models also read an image or a PDF. On `/v1/chat/completions`, put one `image_url` part (a base64 `data:` URL) or one `file` part (base64 `file_data`) in the last user message, with a text part next to it. ScaleDown reads the attachment by OCR. A web URL, more than one attachment, or an attachment with no text is a 400 that says which.

### One model, several providers

More than one provider can serve a model id. The catalog shows one card. The model page lists every provider with its own uptime and TTFB.

**Routing**

- By default, RouterPlus orders providers by the estimated cost of one good answer. Until providers have measurements, the cheapest goes first. See [Provider routing](/docs/provider-routing).
- `provider.order` comes first. `provider.sort: "price"` orders providers by input price plus output price per million, at each live price, and also overrides a routing policy's saved order. `provider.max_price` leaves out a provider above your limit.
- RouterPlus fails over **before the first byte** only, never in the middle of an answer.
- A provider that fails twice in a row, or leaves two requests in a row without an answer, rests for 30 seconds (see [Routing](/docs/routing#health-circuits-and-cooldowns)).

**What you pay**

You pay the price of the provider that serves your request: the one you name with `provider.only`, else the one routing picks, failover included.

- Providers that do not set their own price share the model's list price. The catalog build enforces this.
- A provider reached through an aggregator is charged at the aggregator's listing price, which is the model's list price. Its row on the model page can also show the host's own published price, labelled "Host's list price". You do not pay that price.

**Prices on the pages**

- The pages use only the prices that you pay.
- The model page shows each provider's live price, the price in force now, without scheduled changes. Its bold cells mark the lowest input, cached input and output price, each in its own column.
- The model page's Cheapest sort ranks providers by input price plus output price, the same rule as `provider.sort: "price"`.
- `/api/models.json` also lists each provider's scheduled changes in `scheduled_pricing`, at most 20 per provider. A revision that leaves the price unchanged is not listed.
- In the directory, a decision model's price is the cheapest price you can get by naming a provider. It is labelled "from" when it is below the price of the provider that the page lists first. The model page's "from" price names the same provider.
- The directory's price sort, price filter and "from" price rank providers by input price, then by output price. On one model page, the "from" price can therefore name a provider that the Cheapest sort does not put first.

#### Self-serve price changes

A self-serve provider sets its own price and can change it without a release.

- Every price change starts at a 5-minute mark (10:00, 10:05, 10:10 UTC), at least 2 minutes after the change is written. A change written at 10:02:30 starts at 10:05. All gateways switch at the same time.
- A decrease starts at the next mark. An increase starts only after notice.
- A turn-off of a model, or a lower limit, applies at once. The pages hide the model at that provider and show the lower limits. Only a limit that the listing declares, on a chat model, can be lowered.
- A turn-off has no price, so it is never an increase and needs no notice.
- A turn-on is compared with the last price you could pay while the model was on. When it is higher, it is an increase, and the provider must schedule the turn-on at least the notice period ahead.
- A model that no provider serves now, but that one provider turns back on later, has a page that says it is not served now. It is not in the directory until it is back.

An operator can freeze a self-serve provider. While it is frozen:

- You pay its listing's own price from the manifest files, and the pages show that price.
- `/api/models.json` lists its scheduled turn-offs and turn-ons, but not its scheduled price changes.
- A model that it turned off stays hidden, and lower limits stay in force.
- When an operator unfreezes it and accepts its increases, they can apply at once.

Other exceptions:

- For a provider with a price feed, the site schedules a fed increase at the earliest for the notice period plus 5 minutes after it reads the feed. That can be later than the time the provider publishes.
- An operator can apply an increase without notice. Each such change is audited.

**How fresh the pages are**

| What | Delay |
|---|---|
| Pushed prices | The site reads them every 30 s |
| A page with a self-serve provider | Cached at the edge for up to 60 s (`s-maxage=60`), plus up to 60 s while it refreshes (`stale-while-revalidate=60`), never past the next 5-minute mark |
| A pushed change in `/api/models.json` | Listed as scheduled within about 2.5 minutes. The pages switch at its mark |
| A pushed increase in `/api/models.json` | Listed for its full notice period before it starts, also with a turn-on |
| Manifest files (a release) | Up to 60 s more, because the site reads them once a minute. A changed list price starts at the next 5-minute mark and shows as scheduled until then |
| Any other page | Changes only with a release. The edge can serve a copy up to about 11 minutes old |

After the site starts, no page is cached until its first read.

The gateway charges the price in force when your request arrives, whatever a cached page says. A price change applies at its 5-minute mark. A turn-off or a lower limit applies within about 30 s, when the gateway next reads the prices.

#### Who served the request

- `x-tm-provider` names the provider that served you.
- `x-tm-upstream-model` has the id sent to the provider, when it knows the model under its own id. The response's `model` field still names the model you asked for.
- `x-tm-served-by` names the provider that ran the request, when a route reports one.

**Inference.net.** `inference-net-chat` is an ordinary provider at its own price, also on models other providers serve. Routing tries it first where it is the cheapest (GLM 5.3 Flash, for example), else as a fallback. Name it in `provider.only` or `provider.order` (`"inference-net"` works too) to send a request there first. You pay Inference.net's price, which the model page shows on its row.

```json
{ "model": "moonshotai/kimi-k2.6", "messages": [...], "provider": { "only": ["inference-net-chat"] } }
```

### Date-pinned ids

The catalog lists **one id per model** (`claude-haiku-4-5`). Vendors also ship dated snapshots (`claude-haiku-4-5-20251001`, `gpt-4o-2024-08-06`) and `-latest` spellings, and tools such as Claude Code send them.

- A snapshot or `-latest` id of a catalog model works without being listed. RouterPlus resolves it to its family **for routing and pricing only**.
- RouterPlus forwards your original id to the provider unchanged. It never moves a snapshot pin to a newer version.
- The response's `model` field shows the snapshot that served you.
- If a vendor retires a pinned snapshot, you get the vendor's own error. RouterPlus does not upgrade the pin.
- Unknown ids, dated or not, return a 404 that names the id.
- A key bound to your own provider connection matches ids literally, so list the exact ids you send there.

### Claude names for Cursor

Cursor sends a model name that starts with `claude-` to Anthropic, never to a custom base URL. Each Claude model therefore also answers to a second name: `rp-` and its id without `claude-`.

| Name | Model |
|---|---|
| `rp-opus-5-5` | `claude-opus-5-5` |
| `rp-sonnet-5-5` | `claude-sonnet-5-5` |
| `rp-haiku-5-5` | `claude-haiku-5-5` |
| `rp-fable-5-1` | `claude-fable-5-1` |
| `rp-opus-5` | `claude-opus-5` |
| `rp-sonnet-5` | `claude-sonnet-5` |
| `rp-fable-5` | `claude-fable-5` |
| `rp-sonnet-4-5` | `claude-sonnet-4-5` |
| `rp-haiku-4-5` | `claude-haiku-4-5` |

- Each name is one model, billed at the price of the provider that serves it, as for the model's own id.
- A name takes no date pin. `rp-sonnet-4-5-20250929` is a 404.
- The provider receives the model's own id.
- The answer's `model` field has the name you sent. A Claude stream on `/v1/messages` is relayed as Anthropic sent it, so its first event names the model's own id.
- Billing, `/v1/usage` and `/v1/generation` record the model's own id.
- `GET /v1/models` lists each name right after its model, with `canonical_slug` set to the model's id, so model pickers that read it show the names.
- A key bound to your own provider connection or to a routing policy takes ids literally, so these names do not work on it.

In your own code, use the catalog ids.

### Id grammar

Ids match `[a-zA-Z0-9][a-zA-Z0-9._/-]{0,127}`: letters, digits, `.` `_` `/` `-`, at most 128 characters. `:` is not allowed, so an id has no suffix.

## Providers are manifests

A provider lists its models in a JSON manifest: its endpoint, wire format, settlement terms, data policy, and a model list with prices. [List your models](/docs/for-providers) is the full reference.

```json
{
  "provider": { "id": "anthropic", "name": "Anthropic (direct API)", "prompt_logging": "retained" },
  "endpoint": { "base_url": "https://api.anthropic.com/v1", "dialect": "anthropic" },
  "models": [{
    "id": "claude-haiku-4-5",
    "context_length": 200000,
    "max_output_tokens": 64000,
    "pricing": [
      { "type": "prompt", "unit": "token", "cost_usd_per_million": "1" },
      { "type": "completion", "unit": "token", "cost_usd_per_million": "5" }
    ]
  }]
}
```

What this means for you as a buyer:

- A model is listed only after it passes a live conformance suite against the provider's endpoint. The suite checks real usage, well-formed streams, non-empty answers, a 4xx with no fallback for an unknown model, and that the response names the model you asked for. A dated snapshot of the same id, or a target the manifest declares in `resolves_to`, passes. `gpt-4o` answered by `gpt-4o-mini` fails.
- `is_ready: false` stages a model: it is never routed or listed. After its `deprecation_date`, a model leaves the catalog and the public pages.
- Providers that are neither self-serve nor opt-in (`"routing": "opt_in"`) must agree on a shared model id's price and kind, or the catalog build fails. They share the model's list price. Self-serve and opt-in providers each charge their own price.
- When other providers also serve a model, an opt-in provider serves it only to a request that names that provider.
- Prices are stored as effective-dated, append-only rows. Old requests keep the price they were dispatched at. A changed list price starts at the first 5-minute mark (UTC) at least 2 minutes after the release writes it. A new model's first price applies at once.

## The directory

[`https://demo.routerplus.com/`](https://demo.routerplus.com/) lists every live model in three sections: chat, image and decision. Each kind is called on a different route.

- A row shows the model's context length and max output (for a chat model), or its sizes and qualities (for an image model).
- Directory rows and model pages show no request counts for any model, including newly added models.
- The default decision order starts with Jev 1.13, GPT-6 Luna Decisions, Nimble v4 Max, ScaleDown Classify-1 and Nimble v4.
- Search with `/?q=haiku`. It matches model, lab and provider names.
- Filter by kind, context length, supported parameters, zero data retention, input price, lab and provider.
- Sort by use, name, price or context.

Each model's page at `/models/<id>` shows the values that depend on the provider. It has one row per provider, with prices per SKU, latency, uptime and the provider's prompt-retention policy, and snippets to copy. See [Data policy](/docs/data-policy) for how RouterPlus handles request data.

### Uptime

Uptime and latency come from the last 24 hours of routed traffic. When a provider has fewer than 100 counted attempts in that window, the model page shows a dash (**-**) in place of a percentage. Failures you cause (your 400s, your cancelled streams) do not count against a provider.

## Machine-readable: /api/models.json

The catalog as JSON, with no auth:

```bash
curl -s https://demo.routerplus.com/api/models.json
```

```json
{
  "models": [
    {
      "id": "claude-haiku-4-5",
      "display_name": "Claude Haiku 4.5",
      "output_modalities": ["text"],
      "providers": [
        { "id": "anthropic", "name": "Anthropic (direct API)", "dialect": "anthropic", "prompt_logging": "retained",
          "pricing_usd_per_million": { "prompt": "1", "cached_prompt": "0.10", "cache_write": "1.25", "completion": "5" } }
      ],
      "served_by": [
        { "id": "anthropic", "name": "Anthropic", "zdr": false,
          "routes": [ { "via": "anthropic", "direct": true } ] }
      ],
      "context_length": 200000,
      "max_output_tokens": 64000,
      "pricing_usd_per_million": {
        "prompt": "1", "cached_prompt": "0.10",
        "cache_write": "1.25", "completion": "5"
      },
      "lab": { "id": "anthropic", "name": "Anthropic" },
      "weights": "proprietary"
    }
  ],
  "gateway": "https://demo-api.routerplus.com/v1",
  "docs": "https://demo.routerplus.com/docs"
}
```

| Field | Meaning |
|---|---|
| `id` | The exact string to put in your request's `model` field |
| `output_modalities` | `["text"]`, `["image"]` or `["decisions"]`: which route serves this model. Filter on it. Never guess from the id |
| `providers` | Every deployment serving this id, primary first, each with `id`, `name`, `dialect`, `prompt_logging`, its price, and `upstream_id` when the provider knows the model under its own name |
| `pricing_usd_per_million` (per provider) | What you pay when this provider serves the request, live: decimal-string USD per 1M tokens, keyed by SKU type. Absent for a `reported_cost` listing (see `price_card`) |
| `price_revision` / `price_effective_from` (per provider) | Only for a self-serve provider with a pushed price in force for this model: the revision number and when it took effect (ISO 8601, UTC). Absent when the revision in force does not have this model, and while the provider is frozen: the listing's own price from the manifest files applies then |
| `scheduled_pricing` (per provider) | Only when a change is scheduled: `[{effective_from, rises, pricing_usd_per_million}]` in time order. `rises` is `true` when any SKU goes up against the last price you could pay before it. An entry with `enabled: false` turns the model off: it has no `pricing_usd_per_million`, and its `rises` is always `false`. A later entry without `enabled` turns the model on again at its price. Its `rises` compares that price with the last one you could pay while the model was on, and the notice period applies when it rises. While the provider is frozen, only turn-offs and turn-ons are listed, at the price you pay then |
| `enabled` (per provider) | Only `false`: the provider has the model off now, and a turn-on is in its `scheduled_pricing`. Such an entry comes after the providers that serve the model, has no price, `price_revision` or `opt_in`, and is not in `served_by`. A provider that has the model off with no turn-on scheduled is not listed |
| `enabled` | Only `false`: no provider serves the model now, but one turns it back on later (see its `providers` entries). A request for it now that no BYOK route serves is answered as for an unknown model. Such an entry has no top-level `pricing_usd_per_million`, and `served_by` is empty |
| `dialect` (per provider) | The provider's **native** wire format, for information. Every chat model answers on both APIs |
| `prompt_logging` (per provider) | Provider's prompt retention: `none` or `retained` |
| `served_by` | The providers that run the model, one entry per provider. `routes[].via` is the `providers` entry the request goes to; `direct: true` means the request goes to the provider's own API. `zdr` is `true` when the provider offers Zero Data Retention for this model |
| `context_length` / `max_output_tokens` | Token limits; `max_output_tokens` may be `null`, and `context_length` is `null` for image models |
| `supported_parameters` | Image models only: the descriptor map the route enforces (`size`, `quality`, `n`, and the rest) |
| `pricing_usd_per_million` | The primary provider's live price (what a request that names no provider pays first): decimal-string USD per 1M tokens, keyed by SKU type. Other providers can charge another price: see each `providers[]` entry |
| `lab` | Who made the model, which can differ from who serves it. `null` when unknown |
| `weights` | `"open"` when the lab publishes the model's weights, `"proprietary"` when it never has, `null` when RouterPlus is not certain |

For an image model, `max_output_tokens` is the **per-image ceiling**. It does not cap a completion.

Prices are decimal **strings**, so float rounding loses nothing. Parse them with a decimal type. For the authenticated, SDK-shaped list (what `client.models.list()` calls), see [GET /v1/models](/docs/api-models).
