Concepts

Smart Router

Automatic model selection based on request complexity across 15 dimensions

The smart router classifies each request's complexity and routes it to the most appropriate model based on a routing profile you specify. This saves cost on simple requests while ensuring complex ones get capable models.

The router is pure rule-based logic with no external calls. Classification takes under 1 microsecond.

How to use it

Set model to a routing profile name instead of a specific model ID:

{
  "model": "auto",
  "messages": [{"role": "user", "content": "Explain recursion."}]
}
ProfileAliasesBehavior
autobalanced, defaultBalanced cost and quality. Recommended default.
ecocheap, budgetCheapest capable model per tier.
premiumbest, qualityBest available model regardless of cost.
freeoss, openFree-tier models only (gpt-oss-120b).

You can also use model aliases as shortcuts to specific models:

AliasResolves to
gpt5openai/gpt-5.2
sonnetanthropic/claude-sonnet-4-20250514
opusanthropic/claude-opus-4-20250514
geminigoogle/gemini-3.1-pro
flashgoogle/gemini-2.5-flash
grokxai/grok-4-fast-reasoning
deepseekdeepseek/deepseek-chat

Complexity tiers

The router classifies each request into one of four tiers based on a weighted score:

TierScore rangeDescription
Simplescore < 0.0Short, factual, conversational
Medium0.0 – 0.2Moderate complexity, some technical content
Complex0.2 – 0.4Multi-step, technical, or domain-specific
Reasoningscore ≥ 0.4Deep reasoning, proofs, multi-question

The 15 scoring dimensions

The scorer analyzes user message content across 15 weighted dimensions. Higher score = more complex request.

#DimensionWeightWhat it checks
1Token count0.08Short messages score lower; long messages score higher
2Code presence0.15Backticks, code keywords (fn, class, async, etc.)
3Reasoning markers0.18Words like "prove", "analyze", "step by step", "explain why"
4Technical terms0.10"algorithm", "kubernetes", "distributed", "concurrent"
5Creative markers0.05"story", "poem", "brainstorm", "narrative"
6Simple indicators0.02"hello", "what is", "translate" — negative signal
7Multi-step patterns0.12"first", "then", "next", "step 1", numbered lists
8Question complexity0.05Number of ? marks — more questions = more complex
9Agentic task markers0.04"read file", "deploy", "run command", "install"
10Math/logic0.06Equations, operators, "formula", "calculate"
11Language complexity0.04Average word length as a vocabulary proxy
12Conversation depth0.03Number of messages in context
13Tool usage0.04+0.8 if request includes tool definitions
14Output format complexity0.02"json", "csv", "xml", "structured"
15Domain specificity0.02"medical", "legal", "clinical", "regulatory"

The weights sum to 1.0. The weighted sum produces a score that maps to a complexity tier.

Routing table

Each (Profile, Tier) pair maps to a specific model:

Tierecoautopremiumfree
Simpledeepseek/deepseek-chatgoogle/gemini-2.5-flashopenai/gpt-4oopenai/gpt-oss-120b
Mediumgoogle/gemini-2.5-flash-litexai/grok-code-fast-1anthropic/claude-sonnet-4-20250514openai/gpt-oss-120b
Complexdeepseek/deepseek-chatgoogle/gemini-3.1-proanthropic/claude-opus-4-20250514openai/gpt-oss-120b
Reasoningdeepseek/deepseek-reasonerxai/grok-4-fast-reasoningopenai/o3openai/gpt-oss-120b

Example: same prompt, different profiles

Prompt: "Hello!"
Tier: Simple (short, matches simple indicator keywords)

  eco     → deepseek/deepseek-chat       ($0.28/M input)
  auto    → google/gemini-2.5-flash      ($0.30/M input)
  premium → openai/gpt-4o                ($2.50/M input)
Prompt: "Prove step by step that quicksort has O(n log n) average complexity.
         Analyze edge cases and compare with mergesort."
Tier: Reasoning (reasoning markers: "prove", "step by step", "analyze", "compare")

  eco     → deepseek/deepseek-reasoner   ($0.28/M input)
  auto    → xai/grok-4-fast-reasoning    ($0.20/M input)
  premium → openai/o3                    ($2.00/M input)

Note

The router classifies based on user message content only. System messages and assistant turns do not affect the score.

Bypassing the router

To use a specific model, pass its full ID directly:

{
  "model": "anthropic/claude-opus-4-20250514",
  "messages": [...]
}

Or use a short alias:

{
  "model": "opus",
  "messages": [...]
}

See GET /v1/models for the full list of model IDs.