LLM Price Tracker — OpenRouter Markup vs Provider List Prices
Pricing
from $1.00 / 1,000 markup table rows
LLM Price Tracker — OpenRouter Markup vs Provider List Prices
See OpenRouter's estimated markup vs each provider's direct list price — full comparison table every run. Optional scheduled alerts when prices, context windows, or markups move. Clean JSON, keyless sources, watchlist filters.
Pricing
from $1.00 / 1,000 markup table rows
Rating
0.0
(0)
Developer
Heim AI
Maintained by CommunityActor stats
1
Bookmarked
2
Total users
1
Monthly active users
19 days ago
Last modified
Categories
Share
See what OpenRouter's markup is right now, and get a structured feed of LLM API price changes on a schedule. Free keyless JSON sources, no scraping, no personal data. Detection is per-run: changes surface on your next scheduled run, not in real time.
Is OpenRouter marking up model prices? (checked 2026-07-15)
No — across 138 confidently matched models, zero verified markup. GPT-5.6 Sol ($5/$30), Claude Fable 5 ($10/$50), Grok 4.5 ($2/$6) and 100+ others sit at first-party list price (base tiers, verified against provider pricing pages 2026-07-15).
What the diff did catch:
| Trap | Example | Cost impact |
|---|---|---|
-latest aliases silently repoint | gemini-flash-latest: 2.5 Flash ($0.30/$2.50) → 3.5 Flash ($1.50/$9.00) | ~5x, no code change |
| Zombie checkpoints outlive retirement | mistralai/mistral-large = Large 2 (2407), retired 2025-03-30, still $2/$6 | 4x current-gen Large 3 list |
| First-party aliases move underneath you | DeepSeek's deepseek-chat now = V4 Flash; alias removed 2026-07-24 | breaking + price shift |
| Third-party hosts undercut list | kimi-k2.6 $0.66/$3.41 vs Moonshot $0.95/$4.00; glm-4.7 −33%/−21% | real discounts, host-dependent |
The risk isn't markup — it's silent repointing. This actor diffs prices, models, and pointers every run and alerts on price_change / new_model / removed_model / markup_change, so you find out before the invoice does.
What you get
1. The current markup table — every run, including the first. OpenRouter resells other providers' models, often at a markup, sometimes at a discount. One markup_snapshot row per OpenRouter model with a confidently matched direct list price (from the LiteLLM price map), worst markup first:
{"eventType": "markup_snapshot","modelId": "moonshotai/kimi-k2.6","openrouterPromptPrice": 0.66,"openrouterCompletionPrice": 3.41,"listPromptPrice": 0.95,"listCompletionPrice": 4,"markupPromptPct": -30.526316,"markupCompletionPct": -14.75,"matchedLitellmKey": "moonshot/kimi-k2.6","direction": "discount","versionConfidence": "undated","detectedAt": "2026-07-12T06:00:00.000Z"}
Matching is high-confidence only: provider family + exact normalized name. Ambiguous names are refused, not guessed — models without a confident match don't get a row. The markup is an estimate (LiteLLM's list price is community-maintained); matchedLitellmKey lets you audit every pairing. Toggle with includeMarkupSnapshot (needs both sources).
Markup exclusions (emit-only; matching may still compute a twin): rows and markup_change events are skipped when the OpenRouter id starts with ~, ends with :free, or either the OpenRouter id or the matched LiteLLM key contains -latest. Those rows are never charged.
Markup labels on every remaining markup_snapshot / markup_change row:
direction— OpenRouter vs list (not old→new):"markup"(OR dearer on either side),"discount"(OR cheaper on either side, no markup), or"parity"(prompt and completion both equal).price_change/context_changestill use"increase"/"decrease".versionConfidence—"dated-exact"when the twin was an exact full-name match and both sides carry the same date suffix;"undated"otherwise (undated exact, bare-collapse, one-sided date, etc.).
2. A change feed for scheduled alerting. Each run diffs current prices against your previous run and emits one event per change:
{"eventType": "price_change","modelId": "openai/gpt-5","source": "openrouter","field": "completionPrice","oldValue": 10,"newValue": 8,"pctChange": -20,"direction": "decrease","detectedAt": "2026-07-10T09:00:00.000Z","prevRunAt": "2026-07-09T09:00:00.000Z"}
eventType is one of price_change, context_change, new_model, removed_model, markup_change (markup changes also carry the four underlying prices so you can check the arithmetic, plus direction / versionConfidence as above). All prices are $ per 1,000,000 tokens — the unit providers quote. 0 = free; when a percent genuinely can't be computed (e.g. free → paid), the event still fires with pctChange: null, never a fabricated number.
How to use it (zero setup, no API key)
- Optionally set a watchlist — model-id substrings or globs (
gpt-5,claude-opus,anthropic/*). Empty = watch everything. - Pick sources (default both):
openrouter(~350 models) andlitellm(broad multi-provider map). - Run it on a schedule (hourly/daily). Give each independent schedule its own
monitorId— two schedules sharing one starve each other, because each run consumes the diff. - First run is a baseline: it emits zero change-events (nothing to compare yet) but still delivers the full markup table. A later run with 0 items just means nothing changed — normal, not an error.
Cost controls
changeThresholdPct— suppress price/context moves smaller than this relative % (e.g.5hides a +4% move).markupThresholdPts— suppress markup moves smaller than this many absolute percentage points.maxItemscaps delivered rows per event class. The cap is lossy: excess changes are dropped permanently (the snapshot still advances), not queued for next run.- Change events are delivered before the markup table, so alerts keep budget priority if your Max total charge runs out.
When a source breaks
If a source returns zero priced models, or its model count drops more than maxSourceDropPct (default 40%) since the last run, the run skips the diff: nothing charged, snapshot untouched, so an upstream outage can't bill you a flood of false removed_model events. The run still succeeds and emits one uncharged source_degraded item you can alert on.
Pricing
Pay per delivered row: price-change-detected per change-event, markup-snapshot-row per markup-table row (set includeMarkupSnapshot: false for a pure change feed), plus the standard per-run apify-actor-start charge. Rows filtered out by your watchlist, thresholds, or markup exclusions are never charged. One real-world price cut can produce more than one row — e.g. a completion-price drop is 1 price_change and, since it moves OpenRouter's markup, 1 markup_change.
Limitations
- Coverage follows the aggregators. A model shipped only through a lab's own API (e.g. Meta's Muse Spark, July 2026) is invisible here until OpenRouter or LiteLLM lists it — then a
new_modelevent fires automatically. - Markup is an estimate, dependent on LiteLLM's community-maintained prices; unmatched models carry
null, not a guess. - Detection is per-run. Run more frequently for tighter latency.
Data sources
OpenRouter models API and the LiteLLM price map — both public JSON, queried with an identifying User-Agent. Not affiliated with or endorsed by OpenRouter, BerriAI/LiteLLM, or any provider; verify prices against the provider's official page before commercial decisions.
Found this useful? A review helps others find it. Hit a problem? Open an issue and I'll fix it fast.
Telemetry
Each run records one anonymous event to the developer's own storage: a salted hash of the caller account ID (never the raw ID), the run origin, and a timestamp. No inputs, results, or personal data — this only measures adoption.