# Auto model routing

> sference/auto picks a model per session from the first user message — low, medium, or high tier — and keeps it for the session. Beta, org opt-in.

Source: https://sference.com/docs/sference-code/auto-model-routing

> **Beta**
>
> Auto model routing is in beta and **off by default**. An organization admin turns it on per organization (console → **Members** → the Organization card → **Auto model routing**, or `PATCH /control/v1/teams/me/organization {"auto_routing_enabled": true}`). Until then the model is hidden from every listing and requests for it return **403**.

`sference/auto` picks a model for you, once per session, based on how hard the first message looks. A small classifier reads the first user message and rates it **low**, **medium**, or **high**; that tier's model then serves every later turn of the session.

| Tier | Model | Images |
| --- | --- | --- |
| **low** | `deepseek-ai/DeepSeek-V4.1-Flash` | yes |
| **medium** | `zai-org/GLM-5.3` | no |
| **high** | `moonshotai/Kimi-K3` | yes |

Send it like any other model id on `POST /v1/chat/completions`, `/v1/messages`, or `/v1/responses`:

```bash
curl https://api.sference.com/v1/chat/completions \
  -H "Authorization: Bearer $SFERENCE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"sference/auto","messages":[{"role":"user","content":"Refactor this module to use dependency injection."}]}'
```

## What you get back

The response `model` is the **routed** model, never `sference/auto` — so cost display and logging work without changes. Every response also carries two headers:

| Header | Example | Meaning |
| --- | --- | --- |
| `x-sference-routed-model` | `moonshotai/Kimi-K3` | The model that served the request |
| `x-sference-route-tier` | `high` | The tier it was routed to |

You are billed at the **routed model's** rates. The classification call is not billed to you.

## How a session is identified

The API is stateless and clients send no session id, so the router infers the session from how agent harnesses behave: **they resend the whole conversation on every request**. Turn 1 sends `[system, user1]`; turn 5 sends `[system, user1, …, user5]`. The start of the conversation is identical every time.

A session is therefore every request sharing the same **team + endpoint + system prompt text + first user message text**. The router hashes those four, looks the hash up, and either decides (first time) or reuses the stored tier. The decision expires after **1 hour idle**, refreshed by every request in the session. Only the hash and tier are stored, never content.

> **Where this can surprise you**
>
> - **Weak openers.** A session that starts with "hi", "continue", or `/init` is rated on that text, and the whole session stays on the low tier even if the real task arrives on turn 2. Start a session with the actual task.
> - **System prompt drift.** If your harness puts something that changes into the system prompt (a date, git status, tool list), the session key changes mid-conversation and the session is re-decided — possibly switching models and losing its prompt cache.
> - **Compaction.** `/compact` in Claude Code rewrites the first message, which produces a new decision. The cache is gone at that point anyway.
> - **Subagents** start their own message history, so each gets its own decision. Usually what you want: an exploration subagent can run on the cheap tier.

## Limits

- **Three endpoints only.** `POST /v1/chat/completions`, `/v1/messages`, and `/v1/responses`. Batches reject it at create with **400** — batch rows are not sessions.
- **No cross-tier failover.** If the routed model is at capacity you get the normal 429/503 for that model. Silently changing tier mid-session would hide capacity problems and break the prompt cache.
- **Images never go to the medium tier**, because `GLM-5.3` has no vision. An image on a medium session re-routes it to the high tier once.
- **An org model allowlist still applies.** If it excludes `sference/auto`, requests get **403**; the router only routes to tiers the allowlist permits.

- [SferenceCode](https://sference.com/docs/sference-code): Run your coding harness on open models, one command each.
- [Prompt caching](https://sference.com/docs/guides/prompt-caching): A stable session decision keeps the prefix cache warm.
- [Models](https://sference.com/docs/models): The catalog the router picks from.
