About ModelGraveyard
A public, machine-readable ledger of every LLM that has appeared on, vanished from, or quietly changed price on OpenRouter.
What is OpenRouter?
OpenRouter is a unified API in front of 300+ LLMs from dozens of providers — Anthropic, OpenAI,
Google, Meta, Mistral, xAI, DeepSeek, Qwen, and many more. You point your code at
one endpoint, pick a model by ID like anthropic/claude-3.5-sonnet,
and OpenRouter handles routing, billing, and provider fallback. For thousands of
production apps it is the de facto registry of "which models exist and what do they cost."
That registry is exposed at /api/v1/models — a public, no-auth JSON catalog. ModelGraveyard fetches it every 6 hours, diffs
the snapshot against the last one, and writes a typed event for every change. The
data is committed straight into this git repo so the history is auditable and portable.
OpenRouter's own API reference and quickstart explain how to call it; this site is the lens for watching how it changes over time.
Why this matters: the silent-deprecation problem
Models on OpenRouter disappear without warning. The canonical receipt is BerriAI/litellm issue #20521 — a community report cataloguing 39 OpenRouter models that vanished from the live API while
still appearing in downstream pricing JSONs, with no deprecation_date field
to warn anyone. The issue body breaks them down by provider: 9 Anthropic, 7 OpenAI,
6 Meta Llama, 4 Google, 3 Mistral, 10 others.
For a production app this is a real outage waiting to happen: a request that
worked yesterday returns 404 model_not_found today, with no upstream notification, no migration window, and no audit trail of
what the model used to cost or how it behaved.
OpenRouter does populate an expiration_date field
on some models — those become the "scheduled funerals" list. But the silent
removals are the dangerous ones, and the only way to catch them is to keep a
time-series of the catalog. That is what this project is.
What gets tracked
- model_added
- A new model ID appears in the catalog.
- model_removed
- A previously-seen ID is gone — buried in the graveyard with a final-state epitaph and a same-provider suggested replacement.
- price_changed
- Any of
prompt,completion,image, orrequestpricing changed, with old/new values and percentage delta. - context_changed
- The model's
context_lengthchanged. - deprecation_announced
expiration_dateis newly present — the model has been formally scheduled for retirement.
How to consume it
- Atom feed of all events — global subscription, drop into any RSS reader.
- Per-event-type feeds for narrower subscriptions: removals, catalog disagreements, deprecations, price changes, context changes, additions. The removals and disagreements feeds are the most-subscribed slices — both map directly to production-app outage signals.
- Per-provider feeds under
feeds/by-provider/— for example anthropic.xml, openai.xml, google.xml. Or pick a provider from the event log filter to get the URL automatically. - Raw JSON:
data/derived/events.json,graveyard.json,models-current.json. - Embed a status badge for any model — every model page has a copy svg button that
produces a paste-able pill (green for alive, slate for deceased) with the latest
last_seendate.
Catalog cross-reference
Alongside OpenRouter, a daily fetch pulls LiteLLM's model_prices_and_context_window.json — the other widely-used model registry. A canonicalization step strips
provider prefixes, date stamps (e.g. -20240620),
and routing namespaces (e.g. bedrock/anthropic.)
so the same underlying model collapses to a shared canonical slug across
both sources.
When a model is removed from OpenRouter but still listed by LiteLLM,
the system emits a high-severity disagreement_detected event. That is the exact pattern issue #20521 describes — a model that
production apps may still try to call because their pricing JSON still
lists it, even though the upstream gateway no longer serves it.
The cross-reference snapshot is published at data/derived/cross-reference.json, and disagreements feed into the RSS feed.
Methodology
A scheduled GitHub Action runs every 6 hours, fetches OpenRouter's catalog via the Flat Data action, and runs a Deno postprocess script that diffs the snapshot against the
last committed state. Each typed event lands in data/derived/events.json;
removed models also get a graveyard entry with a heuristic survivor suggestion
(closest same-provider context window). A second daily workflow does the same
for LiteLLM, then cross-references the two catalogs. The SvelteKit site is
rebuilt and redeployed to GitHub Pages whenever derived data changes.
Everything is in the public repo. Fork it, audit it, or open an issue if you spot a bug in the diff logic.
Related projects
- simonw/llm-prices — Simon Willison's curated price index. Cross-referenced when reasoning about the right replacement model.
- LiteLLM model_prices_and_context_window.json — the other canonical model registry. The v2 roadmap includes cross-referencing this with OpenRouter to surface "in LiteLLM but no longer in OpenRouter" silent drops.
- OpenRouter Rankings — the upstream view of which models are getting traffic. Useful signal for guessing which models are at risk of being sunsetted.
FAQ
Why every 6 hours?
A balance between catching deprecations quickly and not spamming the repo with empty commits. Most OpenRouter catalog updates land within a 6-hour window of each other.
Why only OpenRouter and not directly from providers?
OpenRouter is the largest single source of LLM availability data and already normalizes pricing fields across providers. Direct provider scrapers (Anthropic, OpenAI, Google) are on the v2 roadmap; their pricing pages are JS-rendered and brittle.
My model just disappeared. What do I do?
Open its graveyard page — the survivor link suggests the closest same-provider replacement. Confirm by checking the OpenRouter models page and the survivor's docs. For Anthropic models, also check the Anthropic deprecation policy; for OpenAI, platform.openai.com/docs/deprecations.
License?
MIT for the code. Data is from OpenRouter under their terms of service.