OpenRouter does two different jobs. One is access: a single OpenRouter key reaches Jev without a TypeSafe account. The other is comparison: the same key reaches decision models from different makers, so you can ask one question of all of them. Neither is production routing, where the cheapest reliable path usually wins and an extra hop is a cost.
The Decisions API is not chat completions
Jev on OpenRouter runs on the Decisions API, not the OpenAI-compatible chat endpoint. That single fact explains most of the integration friction. A chat-completions SDK will not work, because the request is a state plus a questions object and the response is typed answers, not a message. The OpenRouter explainer shows the shape: POST to https://openrouter.ai/api/alpha/decisions with model typesafe/jev-1.13, a state, and a questions map.
The 1.13 listing adds the operational details. The model id is typesafe/jev-1.13, with ~typesafe/jev-latest tracking the newest release. Context is 64K on the model page, with a note that 32,000 tokens are available for state plus questions. Output is free, and the sample response reports usage.cost in USD: 0.000019992 on one call. All questions in a request are answered in parallel and cannot see each other's answers.
No reasoning trace is a feature. If you need to justify an answer, log the state, question, model id, and probability, and build the explanation in code.
What the catalog actually contains
OpenRouter lists Jev 1.14 as typesafe/jev-1.14: $0.042 per 1M input tokens, $0 per 1M output, a 262K context, and one provider behind the listing. The card says OpenRouter forwards every request directly and makes no routing decisions for this model. That qualifier matters: "multi-provider routing" is not happening for Jev 1.14, and there is no failover.
The broader catalog is the comparison surface. The llm-openrouter-decisions plugin registers every decision model under an openrouter-decisions/ prefix; it counted 30 models from 13 makers as of October 2026, including Jev 1.14. It supports noul, choice, score, and image box answers, and switching models is a matter of changing the -m flag. That is the fastest way to see whether a cheaper or larger model answers your question the same way.
The Jev Router listing is a different product: a model that picks the best model and reasoning effort per request, balancing quality, speed, and cost. It runs on Jev. The listing does not name the candidate models, the reasoning efforts, or how each factor is measured, so the routing is not inspectable. Treat it as a hosted convenience, not a router you can audit.
There is also a version gap. The 1.14 card lists a 262K context; TypeSafe's models page describes jev-1.13.0 at 64k, with 32k for state plus the longest question. Check the version that actually served the request.
Using the official SDK through OpenRouter
The OpenRouter TypeSafe SDK guide documents a base-URL swap for @typesafe-ai/sdk and typesafe_sdk. Set TYPESAFE_BASE_URL=https://openrouter.ai/api and TYPESAFE_API_KEY to your OpenRouter key; the SDK appends /v1/systemone, so requests land on https://openrouter.ai/api/v1/systemone.
Two rough edges are documented. Bare ids such as jev-1.13 are mapped onto the typesafe/ namespace, but the reverse is not promised, which matters if you move between OpenRouter and TypeSafe. And client.models.list() hits OpenRouter's models API, whose response shape the TypeSafe SDK rejects. Code around that call rather than treating the swap as fully transparent.
The response adds id, provider, and usage.cost. Log them; the provider id tells you which account and terms applied.
CLI and MCP surfaces
tyrchen/jev is a Rust CLI for the Decisions API. Each command sends one state and one typed question, validates the answer against the question type, and writes JSON for scripts. The default model is typesafe/jev-1.13, overridable with --model; calls bill to the OpenRouter account behind OPENROUTER_API_KEY. A successful command means a valid answer exists, not that it is positive: a Noul can be valid and negative. The catalog README is truncated, so error handling and release artifacts are undocumented.
openrouter-jev-mcp is a Python decision gateway and stdio MCP server with five tools: jev_check for Noul, jev_classify for Choice, jev_score, jev_evaluate for multi-question batches, and jev_health. It uses an OpenRouter key on the alpha decisions endpoint with ~typesafe/jev-latest; native TypeSafe keys are not supported. Transient HTTP codes 408, 429, 502, 503, and 504, connection errors, and transport timeouts get up to three attempts with exponential backoff from 0.25 seconds and a 20-second deadline, with at most eight requests in flight per instance. Malformed or invalid answers become structured errors, treated as no judgment.
The diagnostics are unusually explicit: successful calls log state and answers by default to ~/.local/state/jev-gateway, with owner-only permissions, a 20 MiB cap, and 24-hour retention. The README says secret filtering is best effort, and RFC 6901 exclusions such as /state/customer only remove the field from the diagnostic copy, not from the request. If the state is sensitive, turn logging down before the first call.
What multi-provider routing really means
For decision models, most "routing" is one of three things:
| Pattern | What moves | Evidence to collect |
|---|---|---|
| Compare models | Same state and question, different -m | Per-model probability, cost, latency |
| Route by difficulty | Easy cases to a small model, hard cases up | Agreement rate, escalation rate |
| Route by availability | Fail over to a second provider | Provider id, error class, retry count |
The third is the one OpenRouter does not provide for Jev 1.14: one provider, no routing decisions. If availability matters, you need a second path (direct TypeSafe, a different gateway, or a self-hosted model) and a policy for when to use it. A base URL change is enough to move a client; it is not enough to guarantee the same probabilities.
The first pattern is the most valuable before committing. Run the same labeled set through Jev 1.14, Jev 1.13, and a couple of the other catalog models, and compare agreement on the exact decision your code will make. The llm plugin makes this cheap from a terminal, but it does not give you calibration. A model can agree on labels and still return probabilities that are not safe to threshold the same way.
Cost, latency, and the hot path
The list price is $0.042 per 1M input tokens with output free, on both the 1.14 card and TypeSafe's own page. The sample call reports usage.cost, so you can measure. The decision-model price war puts those numbers next to rivals; decision calls are cheap enough to run often, and state size moves the bill.
Latency is input-bound. There is no output stream to wait on, so the time is roughly a function of the state and the question set plus the gateway hop. OpenRouter adds one hop and its own rate limits; TypeSafe's direct limits are listed as 100K tokens per second and 80 requests per second, with 429s on either. If the decision sits in a tight loop, call the API directly. If it sits in an evaluation harness or a low-volume workflow, the gateway's key management and comparison surface are worth the hop.
A model alias such as jev-latest is convenient and unsafe for thresholds. Pin the version in production, log the model that answered, and re-run the comparison after a release. Jev on the Gateways covers the surface map, Routing Models, Tools, and Skills with Jev covers routing inside an application, and the AI gateway glossary term covers the category.
OpenRouter is at its best before the hot path: one key, many models, and a CLI that makes comparison trivial. Use it to choose, then move the chosen decision to the cheapest reliable route and keep the gateway for the cases where breadth matters.