Console
Models and routing

Auto router

Let RouterPlus pick the model for each request.

Send the model routerplus/auto, and RouterPlus selects a model for each request. The router reads what the request asks for and stays in the cost tier that you select. It keeps one conversation on one model.

Request

json
{
  "model": "routerplus/auto",
  "messages": [{ "role": "user", "content": "Why does this throw?\n```js\nnull.x\n```" }],
  "auto": { "tier": "economy", "prefer": "cost", "models": ["deepseek/deepseek-v4.1-flash", "claude-haiku-5-5"] }
}

The auto object and all of its fields are optional.

FieldRule
auto.tiereconomy, balanced (default) or premium.
auto.preferquality (default) or cost. With cost, the router can also select models in cheaper tiers, and price counts for more.
auto.modelsThe models that the router can select. Leave it out to use the full list below.

Tiers

TierModels
premiumclaude-opus-5-5, gpt-6-astra
balancedclaude-sonnet-5-5, gpt-6-luna, moonshotai/kimi-k3, z-ai/glm-5.3
economyclaude-haiku-5-5, deepseek/deepseek-v4.1-flash, openai/gpt-oss-120b, z-ai/glm-5.3-flash

The router selects from your tier. When no model in your tier can serve the request, it selects from the next tier up.

How it selects

  1. 01
    The router reads the conversation and names the task:
    • code: code fences, stack traces, file paths or SQL.
    • reasoning: proofs, math or requests for step-by-step work.
    • extraction: response_format with a JSON schema.
    • vision: images in the latest message.
    • long_context: 120,000 or more characters of input.
    • chat or creative otherwise.
  2. 02
    It removes the models that cannot serve the request:
    • models without image input, when you send images
    • models without tools, when you send tools
    • models with a context window too small for your input
  3. 03
    It removes the models that your key's guardrails or auto.models do not allow.
  4. 04
    It ranks the remaining models by how well each one does the task, then by price.

A short follow-up such as "thanks, now make it faster" keeps the conversation's task.

One model per conversation

The router keeps a conversation on the model that it selected first. The router identifies a conversation by your system prompt plus your first user message. It selects again only in these cases:

  • The latest message asks for a different task, for example a code conversation that now asks for a poem.
  • The model can no longer serve the request.

Fallback

The router also ranks up to 4 more models. When the selected model fails before its answer starts, RouterPlus tries the next model, as in Model fallback.

Response

The response is the selected model's answer, and model names that model. Two headers tell what the router did:

HeaderMeaning
x-tm-auto-modelThe model that the router selected.
x-tm-auto-reasonA short reason, for example task code; tier economy; strong at code.

Billing

RouterPlus bills the request as a direct call to the model that answered. The router adds no charge.

Custom routers

Your organization can store its own router and call it as the model routerplus/auto@<slug>. A router has a list of models that it can select, rules that it tries in order, and a default model. In the console, open Build > Routers.

json
{
  "model": "routerplus/auto@support",
  "messages": [{ "role": "user", "content": "Where is my invoice for October?" }]
}

The router selects a model in this order:

  1. 01
    The trained classifier, if the router has one and its prediction is above the threshold. See Training.
  2. 02
    The rules, in order. The first rule that matches selects its model.
  3. 03
    The built-in ranking above, over the router's candidates.
  4. 04
    The default model.
  • The router never selects a model that your key's guardrails or auto.models do not allow. It goes to the next step instead.
  • auto.tier and auto.prefer in the request apply to step 3.
  • In step 3, one conversation keeps its model, as above. The classifier and the rules decide again on each request.

The response has the x-tm-auto-model and x-tm-auto-reason headers. It also has x-tm-router with the router's slug and version, for example support@3. The reason names the step: classifier: claude-haiku-5-5 at 94%, rule 2, a ranking reason, or default. An unknown slug returns 404 model_unavailable.

Spec

json
{
  "candidates": [
    { "model": "claude-haiku-5-5", "tier": "economy" },
    { "model": "claude-sonnet-5-5", "strengths": ["code", "creative"] }
  ],
  "rules": [
    { "when": { "contains": ["\\binvoice\\b", "\\brefund\\b"] }, "use": "claude-haiku-5-5" },
    { "when": { "task": ["code"], "min_input_chars": 20000 }, "use": "claude-sonnet-5-5" }
  ],
  "default": "claude-haiku-5-5",
  "prefer": "cost"
}
FieldRule
candidatesUp to 20 models for step 3. tier and strengths are optional. A model from the tiers table keeps its tier, strengths and context window. Any other model is balanced, and the router assumes that it takes images and tools.
rulesUp to 50 rules. Each rule has when and use (a model id).
defaultThe model for step 4. Required.
prefercost or quality, for step 3. auto.prefer in the request wins.

Every condition in when must be true. A rule with an empty when always matches.

ConditionMatches when
taskThe task is one of these: code, reasoning, extraction, chat, creative, vision, long_context.
containsOne of these regular expressions matches the first 20,000 characters of the latest user message. Case is ignored. 1 to 10 patterns of up to 512 characters.
min_input_charsThe input, with the system prompt and the tool definitions, has at least this many characters.
has_imagesThe conversation has an image (true), or has none (false).
has_toolsThe request sends tools (true), or sends none (false).

contains patterns follow the same safety rules as guardrail regex rules. RouterPlus refuses these patterns with 400 invalid_router:

  • a lookahead or a lookbehind
  • a backreference
  • a repeated group that holds a quantifier or an alternation, such as (a+)+

Manage routers

Use a management key, under https://demo-api.routerplus.com/v1 or https://demo-api.routerplus.com/api/v1.

Method and pathBodyResult
GET /v1/routersThe latest version of each router.
POST /v1/routers{ "slug": "support", "spec": { ... } }201. A slug that exists returns 409.
GET /v1/routers/:slugThe latest version. ?version=2 reads an older version.
PUT /v1/routers/:slug{ "spec": { ... }, "expected_version": 3 }A new version. expected_version is optional. When it is not the latest version, the response is 409.
DELETE /v1/routers/:slugThe router stops working.
POST /v1/routers/:slug/train{ "examples": [ ... ], "threshold": 0.7 }A new version with a trained classifier.

A slug is 1 to 80 characters from a-z, 0-9, _ and -, and starts with a letter or a digit. Each change writes a new version. Requests use the latest version within 5 seconds.

bash
curl -s https://dev2-api.routerplus.com/v1/routers \
  -H "Authorization: Bearer $TM_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"slug":"support","spec":{"rules":[{"when":{"contains":["\\binvoice\\b"]},"use":"claude-haiku-5-5"}],"default":"claude-sonnet-5-5"}}'

Training

A router can learn from your labeled requests. Send examples of text, each with the model that must answer it:

bash
curl -s https://dev2-api.routerplus.com/v1/routers/support/train \
  -H "Authorization: Bearer $TM_MANAGEMENT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"threshold":0.8,"examples":[
        {"text":"I was charged twice this month","model":"claude-haiku-5-5"},
        {"text":"The export to CSV crashes with error 500","model":"claude-sonnet-5-5"}
      ]}'
  • Send 10 to 5,000 examples. Each text has up to 10,000 characters.
  • Label at least two models. Each label must be a candidate or the router's default.
  • The gateway fits a naive Bayes text classifier on words and word pairs. It keeps the 20,000 most frequent features.
  • threshold is optional, above 0 and below 1. Default 0.7.

At request time, the classifier reads the latest user message. When its top model has a probability above the threshold, that model answers, before the rules. Otherwise the rules decide.

The response has the new version and a training object with these fields: examples, labels, features, threshold and training_accuracy. training_accuracy is the share of your examples that the classifier labels correctly. Router objects show a summary of the classifier: its labels, feature count, example count, threshold and training time.

To replace the classifier, train again. A PUT without model_classifier keeps the current classifier. To remove it, send "model_classifier": null.

Errors

StatusCause
400 invalid_requestThe auto object is invalid. The message names the field.
400 invalid_requestNo allowed model can serve the request. The message names the need: image input, tools or context length.
400 invalid_routerA custom router's spec or training request is invalid. The message names the field.
400 invalid_requestNo step of a custom router can select an allowed model.
404 model_unavailableThe custom router slug is unknown.

For agents: /docs/auto-router.md and /llms.txt