Picking a model means checking four things at once: what it costs, how much context it takes, what it can do, and whether it is about to be deprecated. That lives in a 1.7 MB JSON file. This one reads it once at boot, serves it from memory with no database, and prices a single call down to the exact rate key it used.
Ask for the cost of a call and you get a receipt, not a number. Every line names the literal dataset key it was billed with, so the arithmetic can be verified against the JSON.
# 190k input tokens crosses Anthropic's 200k threshold
curl -X POST https://api-llm-specs.axium-lab.com/v1/estimate -H 'content-type: application/json' -d '{
"model": "claude-sonnet-4-5",
"usage": {
"input_tokens": 190000, "output_tokens": 4000,
"cache_read_tokens": 20000,
"cache_creation_tokens_by_ttl": { "1h": 8000 }
}
}'
input.text 190000 x 0.000006 = 1.14 [input_cost_per_token_above_200k_tokens]
output.text 4000 x 0.0000225 = 0.09 [output_cost_per_token_above_200k_tokens]
cache_read.text 20000 x 6e-7 = 0.012 [cache_read_input_token_cost_above_200k_tokens]
cache_write.1h 8000 x 0.000012 = 0.096 [cache_creation_input_token_cost_above_1hr_above_200k_tokens]
------
1.338 USD
The prompt crossed the threshold, so the whole request was repriced — output included — and
the 1 hour cache TTL composed with the long-context axis into that quadruple key. Both decisions come
back in resolution, next to the list of every key used.
How the estimator resolves rates →
api-llm-specs.axium-lab.com is the address the
free instance will answer on; until it is deployed, run it locally or deploy your own. The dataset ships
inside the image, so it boots without network.
git clone https://github.com/axium-lab/llm-specs-api.git
cd llm-specs-api
bun install
bun start # http://localhost:8080
docker build -t llm-specs-api .
docker run --rm -p 8080:8080 llm-specs-api
# The cheapest chat models with a 1M context window
curl 'localhost:8080/v1/models?mode=chat&min_input_tokens=1000000&sort=input_cost_per_token:asc&fields=id,provider,input_cost_per_token&limit=5'
# One model, every attribute the dataset has for it
curl 'localhost:8080/v1/models/bedrock/us.anthropic.claude-3-5-haiku-20241022-v1:0'
Every one of these is a decision taken in the code, not a slogan.
Each cost line carries rate_key and the quantity it multiplied. A total you cannot check against the source is a total you cannot trust.
The catalog ships serialized float noise (1.2999000000000001e-07) and rates as small as 1.3e-10. Everything accumulates in Decimal, never in number.
258 models legitimately price output at 0. A missing rate is never billed as zero — unknown usage lands in unpriced[] where you can see it.
The dataset is versioned and baked into the image, then revalidated with If-None-Match. A 304 transfers 0 bytes; an unreachable upstream is reported, not fatal.
82% of the ids contain a /, 244 contain :, four contain *. The lookup route takes them literally — nothing to escape.
RFC 9457 problem+json everywhere, with stable slugs: model-not-found, ambiguous-model, model-not-priced, limits-exceeded.
A 404 comes with suggestions — substring, then suffix, then trigram similarity, which is what rescues claude-sonnet-9-9.
Three dependencies, no build step, no database, no background jobs. Restarting the instance is what updates the dataset.
What the estimator cannot price is written down, not hidden: tiered pricing, web search and DBU rates are listed as limitations.
Ten routes. Everything queryable lives under /v1; /health sits outside it on purpose.
| Method | Path | Description |
|---|---|---|
| GET | /health | Liveness and readiness, dataset origin, startup_error. |
| GET | /v1/models | Listing with filters, sorting, projection and pagination. |
| GET | /v1/models/* | Lookup by id, slashes and colons included. |
| GET | /v1/models/by-id?id= | Lookup by query param, for the one id a path cannot carry. |
| GET | /v1/compare?ids= | Side-by-side comparison of several models. |
| GET | /v1/providers | The 127 providers with their model counts. |
| GET | /v1/modes | The 16 modes with their model counts. |
| GET | /v1/attributes | The 153 attributes, flagging the 86 pricing ones. |
| GET | /v1/meta | Counts, dataset origin, ETag and sha256. |
| POST | /v1/estimate | Cost of a single call, with a full breakdown. |
The catalog is LiteLLM's model_prices_and_context_window.json, MIT licensed, vendored into the
repository and redistributed normalized. The prices are the ones LiteLLM publishes — this project does not
source them, and it flags the implausible ones rather than correcting them.
How the dataset is loaded, and what it costs to be wrong →