AI Pricing API
A free JSON endpoint listing 464 models across 66 providers, with every price normalised to cost per million tokens. No key, no signup, CORS enabled.
https://promptgeam.com/ai-pricing/data.jsonUpdated: 2026-10-18 · Size: about 165 KB · Auth: none
Why this exists
Model pricing is published per token, which means the numbers look like 0.00000015 and cannot be compared without a calculator. Every consumer of this data has to write the same normalisation and the same filtering for variable-priced routers.
This endpoint does that once: prices are already multiplied to a per-million-token basis, entries without a fixed price are excluded, and the provider is split out as its own field.
Price change history
Detected changes are also published, so you can track movement rather than just the current state:
https://promptgeam.com/ai-pricing/changes.jsonShape:
{"changes": [...], "added": [...]} · Auth: none
Each changes entry has detected, id, name, field (in or out), from and to, all in USD per 1M tokens. Each added entry records a model that appeared in the catalogue, with its initial prices.
The history starts when monitoring began and only grows. It is append-only: if a price moves and then moves back, both events are recorded.
Schema
| Field | Type | Meaning |
|---|---|---|
| updated | string | ISO 8601 UTC timestamp of the last refresh |
| count | number | Number of models in models |
| providers | string[] | Sorted provider slugs present in the data |
| models[].id | string | Catalogue id, e.g. anthropic/claude-sonnet-4.5 |
| models[].name | string | Display name |
| models[].provider | string | Provider slug, taken from the id prefix |
| models[].in | number | null | USD per 1M input tokens |
| models[].out | number | null | USD per 1M output tokens |
| models[].ctx | number | Context window in tokens, 0 if unknown |
Examples
Fetch and find the ten cheapest models for a workload that is input-heavy:
curl -s https://promptgeam.com/ai-pricing/data.json | jq -r '
.models
| map(select(.in != null and .in > 0))
| sort_by(.in) | .[:10][]
| "\(.name)\t$\(.in)/1M in\t$\(.out)/1M out"'
Compute a monthly cost in the browser. CORS is open, so this works from any origin:
const res = await fetch("https://promptgeam.com/ai-pricing/data.json");
const { models } = await res.json();
const inTok = 10_000_000; // 10M input tokens per month
const outTok = 2_000_000; // 2M output tokens per month
const ranked = models
.map(m => ({ ...m, monthly: (m.in ?? 0) * inTok / 1e6 + (m.out ?? 0) * outTok / 1e6 }))
.filter(m => m.monthly > 0)
.sort((a, b) => a.monthly - b.monthly);
console.log(ranked.slice(0, 5));
Rate limits and caching
There is no key and no quota. The file is regenerated once a day and served with a 30 minute cache header, so polling more often than that returns the same bytes. If you are building something that reads this frequently, cache it on your side.
What is excluded
Models priced at a negative sentinel value are variable-priced routers with no fixed rate; they are removed rather than shown as a nonsense number. Cache-read discounts, batch rates and provider-specific promotions are not modelled, because they depend on how you call the model rather than on the catalogue.
Attribution
No attribution is required. If you do link back to promptgeam.com/ai-pricing/, it is appreciated and helps keep the endpoint running.
Source and accuracy
The catalogue comes from OpenRouter's public models API, which aggregates pricing across providers. Prices are passed through rather than editorialised. If a figure looks wrong it usually means the upstream catalogue has not yet caught up with a provider change; the pricing page shows the same data with a human-readable view.