You know your token profile and you have opinions about your stack. Cost-Route measures the shortlist you are already considering against your own questions, prices every candidate across three procurement routes, and shows which price mechanics actually decide the bill. Then it names the gap between what you estimated and what the calls really cost.
Prices read from OpenRouter and the Hugging Face router at 2026-09-28T09:03:36.555Z. Page generated 2026-09-29T11:19:12.175Z.
The three procurement routes. A closed API model, quoted per token · B open weights served by a third party · C open weights self-hosted, an estimate from named assumptions and never a price.
Everything measured is fixed and timestamped. Everything here is a guess, by definition, so you may as well move it and see how far the answer travels. This panel follows the tab you picked above; switching tabs re-points it at the other workload's own measurements.
The buyer said $18.00/month. Here is every named reason that number is not what this workload costs, and what each one is worth.
Each row changes one thing about the buyer's own assumptions and reprices the whole bill. The dollar figure is what that mechanic was worth given everything changed above it, so the steps sum to the gap between the buyer's own assumptions and the measurement, not to the column total. Negative means the correction made the bill cheaper.
The table below is the same walk, frozen at the numbers current when this page was generated.
| Step | Tokens per call | Effect on the bill | |
|---|---|---|---|
| Buyer's stated estimate | $18.00 | ||
| does not follow from their own assumptions, before anything was measured | $-12.90 | ||
| Buyer's own assumptions cost | $5.10 | ||
| Prompt size How much text you send with every request | 1,500 → 3,000 | +$4.50 | |
| Answer length How much text comes back | 50 → 17 | −$0.39 | |
| Prompt caching Whether the repeated part of the prompt is served from cache | 0 → 2,734 | −$4.10 | |
| Reasoning tokens Work the model bills for but never shows you | 0 unchanged, measured 0 | $0.00 | |
| This model was billed for no reasoning tokens on this workload, so the mechanic did not apply. On a reasoning model it would, and it is billed without ever appearing in the answer. | |||
| Measured | $5.11 | ||
Steps run from the most fundamental quantity to the most specific. Each dollar figure is what that mechanic was worth, given everything changed before it. A different order would give different per-step figures and the same total.
Absent rather than zero. A row reading $0.00 beside a mechanic that never ran looks like a saving nobody took; these are mechanics that were never available here.
The shortlist is an input, not a finding. These are the models the buyer named, spanning $0.1400 to $10.0000 per 1M input tokens — about a 71x spread across both procurement routes, out of 458 text models in the catalogue. The job is to test whether the cheap one clears the bar, not to rank the market, and the reason each candidate is here is printed on its own row.
Quality and latency are locked: they were measured against a golden set at a timestamp and cannot be recomputed in a browser. Cost per call and per month respond to the panel at the top of the page.
| Candidate | Quality gate | Served | p50 / p95 | $ per 1M in | Per call | Monthly |
|---|---|---|---|---|---|---|
| OpenAI: GPT-4o-mini current openrouter · route A The buyer's current default, and the incumbent the ledger has to explain: the gap between the estimate and the measurement is only interesting on the model the buyer is running today. Marked by this flag rather than by matching a name. | FAIL 12/14 correct 1 fabricated | 14/14 no failures | 1,294 / 2,021 ms | $0.1500 effective $0.0817 | – | – |
| Fails because: 1 hallucination flag; the bar allows 0 | ||||||
| OpenAI: GPT-5.6 Sol openrouter · route A The frontier option, at 13x the incumbent's input price and a 1M-token context. Included to price what the extra quality actually costs. Publishes a tier override, so a long prompt can cross into a different rate than the headline one. | PASS 14/14 correct 0 fabricated | 14/14 no failures | 2,311 / 6,019 ms | $2.0000 effective $2.0000 | – | – |
| Anthropic: Claude Fable 5.1 openrouter · route A The most expensive input rate in the shortlist, $10/M against the incumbent's $0.15/M, and 40x cheaper on cached input at $0.25/M. The clearest illustration that the list price is not the price, and that whether you get the cached rate is a prompt-structure decision rather than a purchasing one. | PASS 13/14 correct 0 fabricated | 14/14 no failures | 4,143 / 5,141 ms | $10.0000 effective $10.0000 | – | – |
| DeepSeek: DeepSeek V4 Flash 0423 openrouter · route B The cheapest candidate in the shortlist, open weights under MIT, and about 5x cheaper again on cached input. Included specifically to test whether the cheapest option clears the buyer's bar, which is the question the page exists to answer. | PASS 11/14 correct 0 fabricated | 14/14 no failures | 2,094 / 4,198 ms | $0.1400 effective $0.0707 | – | – |
| DeepSeek: DeepSeek V4 Pro 0423 openrouter · route B The same family one tier up, at roughly 11x Flash's input price. Included so the page shows an intra-family spread instead of treating a model family as a single option; a buyer choosing 'DeepSeek' is really choosing a tier. | PASS 14/14 correct 0 fabricated | 14/14 no failures | 5,635 / 12,513 ms | $0.9553 effective $0.2218 | – | – |
| MoonshotAI: Kimi K3 openrouter · route B A third open-weight lab, priced between DeepSeek Pro and Claude Fable, with a 1M-token context and a bespoke licence rather than a permissive one. Included so the open-weight route is not represented by a single vendor, and so the licence column shows that 'open' is not one term. | PASS 14/14 correct 0 fabricated | 14/14 no failures | 1,813 / 2,654 ms | $3.0000 effective $0.5190 | – | – |
"Effective" is the blended input rate after caching, computed from the measured profile. It is printed beside the list price because the two columns rank candidates differently, and the list price is the one nobody pays.
One accuracy figure per candidate hides which questions the candidates separate on. This is the same run, re-cut: how many of each kind of question each candidate answered correctly, over the calls that were served. A question that was never answered is named under the cell rather than counted as a wrong answer.
| Candidate | Stated in one clause | Needs two clauses combined | Not answered by the contract |
|---|---|---|---|
| OpenAI: GPT-4o-mini current | 10/10 | 1/3 1 fabricated | 1/1 |
| OpenAI: GPT-5.6 Sol | 10/10 | 3/3 | 1/1 |
| Anthropic: Claude Fable 5.1 | 10/10 | 2/3 | 1/1 |
| DeepSeek: DeepSeek V4 Flash 0423 | 9/10 | 1/3 | 1/1 |
| DeepSeek: DeepSeek V4 Pro 0423 | 10/10 | 3/3 | 1/1 |
| MoonshotAI: Kimi K3 | 10/10 | 3/3 | 1/1 |
No candidate answered a Not answered by the contract question wrongly. Every difference the quality bar actually found is in “Stated in one clause”, “Needs two clauses combined”, and it is what fails GPT-4o-mini. A workload made only of the first kind has no measured reason to prefer the more expensive candidate. A low score on a kind is a failure to weigh against that candidate's price; a perfect score on a kind everyone passes is not a reason to buy it.
The Batch API is asynchronous and text-only, one provider per batch chosen at
submission with no fallback, and it returns no per-request latency. What it does return is
usage.cost for the whole batch — so this route can be priced in two independent
ways, and this section keeps them apart. The published columns are what the catalogue
lists for the :batch card. The measured columns are what the calls were
really charged: the synchronous bill from the sum of that run's per-call costs, the batch bill
from the batch's own usage.cost. 1 of these candidates were bought as a batch on this workload.
| Candidate | Standard card, per M in – out | Batch card, per M in – out | Published ratio | Sync bill, measured | Batch bill, measured | Measured ratio | Submit → done |
|---|---|---|---|---|---|---|---|
| OpenAI: GPT-4o-mini openai/gpt-4o-mini:batch | $0.1500 – $0.6000 | $0.0750 – $0.3000 | x0.5000 published | $0.003574 | n/a | not measured | — |
| OpenAI: GPT-5.6 Sol openai/gpt-5.6-sol:batch | $2.0000 – $10.0000 | $1.0000 – $5.0000 | x0.5000 published | $0.108686 | n/a | not measured | — |
| Anthropic: Claude Fable 5.1 anthropic/claude-fable-5.1:batch | $10.0000 – $50.0000 | $5.0000 – $25.0000 | x0.5000 published | $0.795350 | n/a | not measured | — |
| MoonshotAI: Kimi K3 moonshotai/kimi-k3:batch | $3.0000 – $15.0000 | $2.2800 – $11.4000 | x0.7600 published | $0.038635 | $0.087732 14 of 14 calls billed | x2.2708 measured | 1.86 h |
The two ratios answer different questions and neither substitutes for the other. The published ratio compares two rate cards and is true of every workload. The measured ratio compares two bills for these 14 questions and is true of this one — a model can publish 50% and settle somewhere else entirely, because caching, tiers and reasoning tokens are not uniformly discounted. OpenRouter's own docs say so about non-token components; this table is what it looks like when it happens.
The batch API reports one cost for the batch and none per request, so there is no per-call price to measure. The figures below are the batch bill divided by the calls it completed — arithmetic, not observation — and they are in their own table for that reason. They are what a monthly commitment would be priced from; they are not a per-call measurement, and nothing here should be quoted as one.
| Candidate | Batch bill, measured | Calls billed | Allocated, per call | Allocated, at your volume | Source |
|---|---|---|---|---|---|
| MoonshotAI: Kimi K3 | $0.087732 | 14 | $0.006267 | $125.33 | allocated: batch usage.cost / requests completed |
| Candidate | Why |
|---|---|
| openai/gpt-4o-mini | no batch was submitted for this candidate, and no stored batch covers it |
| openai/gpt-5.6-sol | no batch was submitted for this candidate, and no stored batch covers it |
| anthropic/claude-fable-5.1 | no batch was submitted for this candidate, and no stored batch covers it |
| deepseek/deepseek-v4-flash | no :batch endpoint for deepseek/deepseek-v4-flash, so the submit would return 400 |
| deepseek/deepseek-v4-pro | no :batch endpoint for deepseek/deepseek-v4-pro, so the submit would return 400 |
A model with no :batch entry in the catalogue
cannot be run asynchronously at all. The leg names them rather than leaving a silent gap in the
table above, because a missing row reads as an oversight and this is a fact about the catalogue.
OpenRouter's announcement says batch requests "generally charge 50% (and sometimes less) of their normal per-token price", and that is accurate as a description of the usual case. It is not a rule, and a buyer pricing an async workload against it will be wrong on 7 of the 72 cards that carry a rate on both sides.
| Batch card against its standard card | Cards | Share |
|---|---|---|
| Exactly 0.5x — the announced case | 65 | 90.3% |
| Cheaper than 0.5x | 3 | 4.2% |
| Dearer than 0.5x, still a discount | 2 | 2.8% |
| More than the standard card — going async costs more | 2 | 2.8% |
| The 7 that are not 0.5x | Prompt | Completion | What it means |
|---|---|---|---|
| openai/gpt-oss-120b | x0.1973 | x0.2267 | A deeper discount than the announcement describes. |
| z-ai/glm-5.3 | x0.3214 | x0.4545 | A deeper discount than the announcement describes. |
| z-ai/glm-5.3-flash | x0.4000 | x0.4000 | A deeper discount than the announcement describes. |
| moonshotai/kimi-k3 | x0.7600 | x0.7600 | A shallower discount than the announcement describes. |
| x-ai/grok-4.3 tiered rates above a prompt threshold | x0.8000 | x0.8000 | A shallower discount than the announcement describes. |
| openai/gpt-oss-20b | x1.3333 | x1.2444 | Batch costs more than the standard card on this model. |
| deepseek/deepseek-v4.1-flash | x4.4800 | x0.5600 | Batch costs more than the standard card on this model. |
Read from the catalogue at
2026-09-28T09:03:36.555Z, at no cost: every
:batch entry is a full model entry with its own pricing, so the comparison needs no
submission. It is a price list, not a bill — the two columns above are labelled accordingly.
Route C is an estimate built from named assumptions, not a quoted price, and it is the only row in the repository with no monthly cost field. Sorting it beside A and B as though it were one more price is the mistake this table exists to prevent.
| Route | Candidate | Monthly | What price does not say |
|---|---|---|---|
| Route A Closed API model quoted price | openai/gpt-4o-mini openrouter | $5.11 |
|
| Route A Closed API model quoted price | openai/gpt-5.6-sol openrouter | $155.27 |
|
| Route A Closed API model quoted price | anthropic/claude-fable-5.1 openrouter | $1136.21 |
|
| Route B Open weights, served by a third party quoted price | deepseek/deepseek-v4-flash openrouter | $3.12 |
|
| Route B Open weights, served by a third party quoted price | deepseek/deepseek-v4-pro openrouter | $21.54 |
|
| Route B Open weights, served by a third party quoted price | moonshotai/kimi-k3 openrouter | $55.19 |
|
| Route C Open weights, self-hosted estimate | — | $1019.10 to $2040.00 if the instance is held up all month estimate, not a price |
|
The monthly figures for routes A and B price each candidate's own measured token profile at this workload's stated volume, and they are fixed. They are not the candidates table above, which moves with your inputs; where the two differ, they are pricing different configurations and both are right.
The buyer said $25.00/month. Here is every named reason that number is not what this workload costs, and what each one is worth.
Each row changes one thing about the buyer's own assumptions and reprices the whole bill. The dollar figure is what that mechanic was worth given everything changed above it, so the steps sum to the gap between the buyer's own assumptions and the measurement, not to the column total. Negative means the correction made the bill cheaper.
| Step | Tokens per call | Effect on the bill | |
|---|---|---|---|
| Buyer's stated estimate | $25.00 | ||
| does not follow from their own assumptions, before anything was measured | $-19.98 | ||
| Buyer's own assumptions cost | $5.02 | ||
| Prompt size How much text you send with every request | 30 → 9 | −$0.01 | |
| Answer length How much text comes back | 1,000 → 1,294 | +$1.47 | |
| Image output tokens The image itself, which is billed by the token and not by the picture | 0 → 1,290 | +$70.95 | |
| This model bills image output at 30/M against 2.5/M for text output, so the same token count costs 12.0x more when the output is a picture. The pricing page lists both rates one line apart and gives no hint which one an image lands on. | |||
| Prompt caching Whether the repeated part of the prompt is served from cache | 0 unchanged, measured 0 | $0.00 | |
| The measurement found no cache hits, so a discount this route does publish was never taken. | |||
| Reasoning tokens Work the model bills for but never shows you | 0 unchanged, measured 0 | $0.00 | |
| This model was billed for no reasoning tokens on this workload, so the mechanic did not apply. On a reasoning model it would, and it is billed without ever appearing in the answer. | |||
| Measured | $77.42 | ||
The buyer's stated estimate plus every change below it comes to $77.43 against the $77.42 on the total row, because each row is rounded to the cent on its own. The bridge closes to $77.4229 before that rounding. The bold line is a running subtotal, not another amount to add.
Steps run from the most fundamental quantity to the most specific. Each dollar figure is what that mechanic was worth, given everything changed before it. A different order would give different per-step figures and the same total.
Absent rather than zero. A row reading $0.00 beside a mechanic that never ran looks like a saving nobody took; these are mechanics that were never available here.
There is no quality gate on this workload, and that is a statement about the measurement rather than about the models. Image output has no correct-share to compute, so the only machine gate is the buyer's own 15,000ms latency ceiling. The pictures are shown so the judgement that the machine cannot make is one a reader can.
| Candidate | Runs with an image | Median | Fastest – slowest | Spread | Image tokens per run | Billed, both runs | Cost coverage |
|---|---|---|---|---|---|---|---|
| Google: Nano Banana (Gemini 2.5 Flash Image) route A | 2/2 every run returned an image | 5,872 ms | 4,333 – 7,411 ms | 1.7x | 1,290 / 1,290 | $0.08 | 2/2 |
| OpenAI: GPT-5 Image Mini route A | 2/2 every run returned an image | 34,439 ms | 32,957 – 35,921 ms over the ceiling | 1.1x | 4,175 / 4,175 | $0.08 | 2/2 |
Latency and cost are summed over different sets of runs on purpose. A call that returned no picture took some amount of time that was not a generation time, so it is left out of the latency figures; it was billed for the tokens it burned getting there, so it is left in the cost. Two rules pointing opposite ways, and dropping the failed runs from the cost would understate the monthly figure this workload exists to produce.
Neither of these was called. The Hugging Face router catalogue carries 140 models and none of them declare an image output, and the BFL routes that would serve FLUX directly are behind an account with no credit balance - so there is no route to run and no published rate to quote. What is readable is the model card's licence field, and that is what this table reports.
| Model | Route | Licence field | What it means commercially |
|---|---|---|---|
| FLUX.1 schnell black-forest-labs/FLUX.1-schnell | Route B | Apache-2.0. Permissive, so commercially usable with attribution. read from the Hub card, not measured | The permissive half of the pair: a buyer could ship this. |
| FLUX.1 dev black-forest-labs/FLUX.1-dev | Route B | The Hub card reports the licence field as 'other', which is the FLUX.1-dev Non-Commercial License. Rendered as what the field literally says, not as the friendlier paraphrase. read from the Hub card, not measured | The restricted half. 'other' is a con in the route table, not a neutral value, and the page says so. |
A licence is the one thing on this page that costs nothing to read and cannot be measured. It is still a purchase decision: the permissive row and the restricted row are the same weights with different terms, and the terms decide whether the cheaper one is usable at all.
Route C is an estimate built from named assumptions, not a quoted price, and it is the only row in the repository with no monthly cost field. Sorting it beside A and B as though it were one more price is the mistake this table exists to prevent.
| Route | Candidate | Monthly | What price does not say |
|---|---|---|---|
| Route A Closed API model quoted price | google/gemini-2.5-flash-image openrouter | $77.42 |
|
| Route A Closed API model quoted price | openai/gpt-5-image-mini openrouter | $79.81 |
|
The monthly figures for routes A and B price each candidate's own measured token profile at this workload's stated volume, and they are fixed. They are not the candidates table above, which moves with your inputs; where the two differ, they are pricing different configurations and both are right.
a single red circle on a plain white background is the exact string that was sent and billed. It is the workload, not an example of one. There is no golden set and no machine quality gate here, because whether a picture is any good is a human judgement.Take the document or prompt, ten to fifteen questions you already know the answers to, and the models you are considering. You get this page back with your numbers in it. Three ways in, in increasing order of control:
POST /webhook/cost-route with the workload as
JSON, for anything you want to run repeatedly or wire into a pipeline.A text run of five or six models on fourteen questions costs roughly $0.01–1.00 depending on the shortlist — the frontier model dominates the bill, which is the finding, not a caveat. Nothing runs on a visitor's behalf, and no key is needed to read this page.
This page is the artifact. The pipeline that produces it — the benchmark runner, the estimate-versus-measured ledger, the renderer, the saved run files and the test suite — is in the repository, together with the n8n workflow that orchestrates the calls. Point it at your own contract or prompt and your own shortlist by adding one workload file, and the same report comes back with your numbers in it.
Written by Madeline Li · LinkedIn