LLM router
A router needs somewhere to route to, and someone to decide.
Every request declares a pool: the models it is willing to be answered by. A triage layer looks at the request and the pool, then picks a member to answer. That second step is the part most routers skip or fake, and it is the reason this page exists.
The pick only matters because a verification ladder runs underneath it. Without a check on the way out, sending traffic to a cheaper model is a bet against your own users. With one, it is a decision you can watch pay off on the receipt.
The pool: what a request is allowed to run on
A pool is resolved once per request, from whichever of these it finds first. Nothing is guessed silently: an id that does not exist in the live catalogue is refused with a 400, not dropped from the pool.
A pack name
llm11-fast, llm11-balanced, or llm11-smart. Each resolves live against the current catalogue's price bands, so a pack self-maintains as new models ship instead of going stale like a hardcoded list would.
An explicit model list
llm11_models in the request body: an array of exact catalogue ids you choose yourself. Every id must exist in the current catalogue, or the request is rejected outright rather than silently narrowed.
A pinned single model
Send one catalogue model id as model instead of a pack. That gives triage a pool of exactly one, so no routing decision happens at all. Verification still runs on whatever it returns.
The project default
Send neither, and the project's own configured pool applies: a pack you picked in settings, or a custom list. This is what most requests use in practice.
The three packs
Each pack is a price band over the live catalogue, ranked by a blended per-million rate, not a fixed list of names. That is what keeps a pack cheap and current without anyone having to edit it by hand when a provider ships or retires a model.
llm11-fast
The cheapest end of the catalogue. Best for high-volume, low-stakes traffic.
llm11-balanced
A working mix of cheap and capable models. The sane default.
llm11-smart
The most capable models available, priced at whatever that costs.
Set a project’s default pack in settings, or override it per request with model or llm11_models.
Triage: the decision layer a pool needs
Declaring a pool is not routing. Something still has to look at each request and choose a member, and that choice is where a router either earns its keep or turns into a coin flip with extra steps.
llm11 runs one typed decision call per request, before generation, against the pool that request was offered. It answers what kind of task this is, which pool member should handle it, and how much verification the answer will deserve, all in one pass, with a calibrated confidence attached to the pick.
That call runs on Jev, TypeSafe AI’s System One model, when a deployment has it configured. A built-in heuristic backend stands in otherwise: no network call, more conservative routing, and a confidence capped low on purpose so the fallback errs upward rather than pretending to certainty it does not have. The receipt always names which backend decided a given request.
_llm11 (excerpt)
{
"candidatePool": [
"google/gemini-3.8-flash",
"openai/gpt-5.6-luna",
"anthropic/claude-opus-5"
],
"poolSource": "project",
"modelUsed": "google/gemini-3.8-flash",
"triageBackend": "jev",
"triageConfidence": 0.93,
"taskType": "extraction",
"criticality": "low"
}Why verification is what makes the pick safe
Sending a request to a cheaper model is only a good idea if you find out when it does not work. A router with no check on the way out cannot tell the difference between a downgrade that held up and one that quietly shipped a worse answer to a user. It just logs a lower number and moves on.
Checks run in proportion
Schema and reference checks always run, for free. Groundedness runs when you supplied context. Cross-model comparison and resampling are held back for requests that earned them, cheapest checks first.
One escalation, not a loop
A failed check sends the request to the strongest remaining pool member once, re-checks that answer, and stops. A retry loop would cost you more than an honest answer with a flag on it.
The receipt shows the arithmetic
Every request comes back with what ran, what each check found, what it cost, and what the pool's most expensive member would have cost for the same tokens, so a downgrade is something you can verify rather than take on trust.
One base URL, then a pool is optional
An existing OpenAI- or Anthropic-shaped integration works unchanged the moment you swap the base URL. Routing only kicks in once you name a pack, a list, or leave the project default in place; pin a single model and you get the same request you send today, with a check on the way out.
the whole migration
- base_url="https://api.openai.com/v1"
+ base_url="https://llm11.com/v1"Go deeper
The router with Jev
How the triage layer's decision backend actually works, and why it is not the only one.
What a router can and cannot claim
What Jev's own claim about itself does, and does not, mean for the answer a model writes.
Compare routers and gateways
How this stacks up against OpenRouter, LiteLLM, and the rest, structurally rather than on a benchmark.