OpenRouter is what keeps Fulltrace multi-provider and cheap to run. One API key unlocks a whole catalogue of models, paid per token with no subscriptions. If a model fails mid-run, the job moves to the next one on its route, and every run is priced before it starts.
The routing philosophy across Fulltrace is not "use the strongest model everywhere". It is: use the cheapest capable model for each stage, keep repeatable work in code, and spend intelligence where it matters. That only works if switching models is trivial, and that is what OpenRouter provides: one endpoint, one key, one bill, and the whole catalogue behind it.
Model choice is a route, not a fixed value: a failed provider call moves the job to the next model in line, and the attempt is recorded in telemetry. The fix-proposal stage narrows this to transport-only failover, pinned to Claude Sonnet 4.5, so a network blip can never quietly hand a code fix to a weaker model. The full failover story lives with the runtime, on how it works; the Codex role profiles that ride this gateway live on the codex page.
Key handling follows the secrets guardrail (G10). The OPENROUTER_API_KEY lives in a user-scope environment variable, read at runtime, never stored in the repo, in config, in queue payloads, or in reports.
Live and in daily use: failover routes are active, the catalogue picker is live in Studio, and four Codex role profiles run through the managed config block.
One shared picker replaced every scattered model input in the dashboard: a searchable, grouped list over OpenRouter's live catalogue, wired to the fix-proposal model and every per-stage and per-run override. The parsing, grouping and free/paid logic behind it is a pure module covered by 23 tests, and marking is conservative: only a model priced at exactly zero counts as free.
A code-owned mapping folds OpenRouter's provider IDs into three tool groups, and the current selection is pinned at the top under its own heading, so the pick is one glance and a search away.
Live fetch first, a six-hour cache behind it, a stale cache behind that, and a curated built-in list as the floor. Offline or mid-outage, the picker still renders a full list.
The catalogue is fetched direct from the extension over a public GET: no API key needed for metadata, no new gateway endpoint, no new authority. The picker writes only config that was already writable.
Every run gets a cost estimate before I confirm the spend, priced by a shared module that covers Anthropic, OpenAI and OpenRouter alike and attributes every token to the model that actually did the work (the dashboard shows it in action). One rule applies throughout, guardrail G1: the tightly rate-limited free models never run the jobs that check or change code. Nothing runs blind, and nothing hides in the totals.
Usage and cost for every model shows up on the dashboard: per-model session and all-time totals, including OpenRouter model IDs alongside Claude usage. Building it surfaced a real bug: cached and reasoning tokens were being double-counted as additions when they are subsets. Fixed, and the totals are honest.
The dashboard also shows, live, how much OpenRouter credit is actually left, kept separate from what the subscription plans cover, so a run is never launched into an empty account.