Price API and price badge
Two addresses give you UberLLM's current prices without an API key or an account:
- Prices as JSON:
GET https://api.uberllm.dev/api/v1/public/prices - A price badge:
https://api.uberllm.dev/api/v1/public/badge/<model-id>.svg
Both show the same price as the model's page on uberllm.dev: the lowest seller price right now. Prices are re-read every 30 seconds.
Prices as JSON
curl "https://api.uberllm.dev/api/v1/public/prices?model=deepseek/deepseek-v4-flash"
{
"updated_at": "2026-11-13T06:40:12Z",
"models": [
{
"id": "deepseek/deepseek-v4-flash",
"name": "DeepSeek V4 Flash",
"type": "text",
"input_per_m": 0.0091,
"output_per_m": 0.0182,
"list_input_per_m": 0.09,
"list_output_per_m": 0.18,
"discount_pct": 89.9,
"unit": "1M tokens",
"price_text": "$0.0091/M in · $0.0182/M out",
"page_url": "https://uberllm.dev/models/deepseek/deepseek-v4-flash"
}
]
}
The numbers above were read on 2026-11-13. Yours will differ, because prices move.
What you can ask for
All of these are optional. With none, you get every model you can call right now.
| Parameter | What it does |
|---|---|
model |
One model id, for example deepseek/deepseek-v4-flash. |
type |
Only text, image, video or audio models. Music, text to speech and speech to text are audio. |
q |
Words to find in the id or the name. Every word must match: q=claude opus. |
limit |
At most this many models, from 1 to 1000. |
If model names a model that does not exist, or one that nobody serves right now,
models is an empty list and the answer is still 200. An old model id that has been
renamed answers with the model it became.
What comes back
All prices are in US dollars. A field with no value is left out.
| Field | Meaning |
|---|---|
id, name |
The model id you send in a request, and its name. |
type |
text, image, video or audio. |
input_per_m, output_per_m |
Text models: the price now for 1 million input tokens and 1 million output tokens. |
list_input_per_m, list_output_per_m |
Text models: the model's published list price for the same. |
price |
Image, video and audio models: the price now for one unit. |
list_price |
Image, video and audio models: the official price for one unit. Sent only when it is above price. |
discount_pct |
How far the price now is below the list price, from 1 to 100. For a text model it is the smaller of the input cut and the output cut. Left out when there is no list price or the price is not below it. |
unit |
What one price buys: 1M tokens, image, megapixel, second, video, track, minute, 1k characters or request. |
price_text |
The price in words, in English, ready to show: $0.0091/M in · $0.0182/M out, $0.059 / sec, about $0.0315 per image. |
page_url |
The model's page on uberllm.dev. |
updated_at |
When these prices were read. |
A request can cost more than the price shown when the cheapest sellers are busy. See Pricing for how a request is billed.
From a web page
Any website can read the prices straight from the browser:
const res = await fetch("https://api.uberllm.dev/api/v1/public/prices?type=text&limit=10");
const { models } = await res.json();
for (const m of models) console.log(m.name, m.price_text);
Price badge
A small picture with the model's name and its price now. It updates by itself.
Markdown, for a README:
[](https://uberllm.dev/models/deepseek/deepseek-v4-flash?utm_source=embed&utm_medium=referral&utm_campaign=price-badge)
HTML:
<a href="https://uberllm.dev/models/deepseek/deepseek-v4-flash?utm_source=embed&utm_medium=referral&utm_campaign=price-badge">
<img src="https://api.uberllm.dev/api/v1/public/badge/deepseek/deepseek-v4-flash.svg"
alt="DeepSeek V4 Flash price on UberLLM" height="20">
</a>
- Put the model id in the address as it is, slashes included, and end it with
.svg. - The badge also says how far the price is below the list price. Add
?discount=0to show the price alone. - If nobody serves the model right now, the badge says "not available right now" and shows no price. It goes back to the price when a seller returns.
- A model id that does not exist answers
404. - The link carries
utm_source=embed, so we can tell that a visit came from a badge. It records nothing about your readers. Take it off if you prefer.
Limits and caching
- 300 requests a minute from one IP address on the JSON address. Over that you
get
429with aRetry-Afterheader. - Badges have no request limit, and a badge for a real model is always a picture: if prices cannot be read for a moment it says "not available right now" instead of breaking.
- JSON answers may be cached for 60 seconds, badges for 5 minutes. Sites that proxy images (GitHub does) can hold a badge a little longer.
- Models made for adult content are left out of both. They are in
GET /v1/models, marked"nsfw": true.
Errors
| Status | error.code |
Why |
|---|---|---|
400 |
invalid_type, invalid_limit, invalid_request |
A parameter has a value that is not allowed. The message says which. |
404 |
model_not_found, not_found |
Badge only: no such model, or the address does not end in .svg. |
429 |
rate_limited |
JSON only: too many requests from your IP address. Wait a minute. |
503 |
unavailable |
JSON only: prices could not be read just now. Try again in a few seconds. |
Related
GET /v1/models: the full model list in the OpenAI format, with context sizes and what each model supports.- MCP server: the same prices as tools for an AI assistant.
- OpenAPI spec: both addresses are in it.