Models & pricing
370+ models on one balance — how each media kind is billed, how discounts apply, and how to read the live catalog instead of a table that goes stale.
GPUniq serves 370+ models — text, image, video, music, speech and restoration — behind one API key and one USD balance. The catalog changes weekly, so this page documents the rules. For the numbers, ask the API:
curl https://api.gpuniq.com/v1/llm/models/catalog
models = client.llm.models()
for model in models["models"]:
print(model["slug"], model["retail_input_usd_per_mtok"])
curl https://api.gpuniq.com/v1/openai/models \
-H "Authorization: Bearer gpuniq_your_key"
GET /v1/llm/models/catalog is public and needs no key. It is the only
authoritative price list — the model cards in /chat
read from it too. The same list priced in rubles is at
GET /v1/llm/models/catalog/rub.
This page no longer prints per-token price tables. They went stale faster than anyone could maintain them: model prices move with the wholesale market, sometimes weekly. Media prices (per image, per clip, per second) are stable enough to publish and live on the image, video and music & speech pages.
What the catalog returns
One entry per model. The fields that matter when you are choosing or budgeting:
| Field | What it tells you |
|---|---|
slug | The string you put in model. |
label, description | Human-readable name and one-line summary. |
provider | Vendor family — anthropic, openai, google, xai, deepseek, qwen, zhipu, moonshot, bytedance, minimax, … |
category | flagship / reasoning / balanced / fast — the shelf it sits on. |
media_kind | text, image, video, music, audio, embedding or rerank. Decides which endpoint serves it — the last two are embeddings & rerank. |
retail_input_usd_per_mtok, retail_output_usd_per_mtok | Text pricing, USD per million tokens, input and output priced separately. |
retail_cached_input_usd_per_mtok | What cached input costs on the model's primary route, or null when no route discounts it. Applied only when the provider that served your call gave GPUniq that discount — see How pricing works. |
retail_usd_per_image | Flat price per delivered image. Video and music rows still carry their unit price here for one more release — read retail_usd_per_unit for them. |
retail_usd_per_unit + video_billing_unit / audio_billing_unit | Media price and the unit it is charged in — video, second, track or character. |
pricing | Structured prices by variant where a table exists: per_second_usd by resolution (Seedance, with the reference-to-video rate), by_resolution_usd per clip at the model's kickoff defaults (Kling / Veo, spelled out in assumes), by_size_usd per image tier. null for everything else. |
available, unavailable_reason | Whether a live route serves the model right now. unavailable_reason is no_route (nothing maps the slug) or all_routes_disabled. Hide a row with available: false — its kickoff would fail. |
aliases | Other spellings that resolve to this row: the vendor's dotted form (claude-haiku-4.5), the aggregator id (anthropic/claude-haiku-4.5). A request under any of them is routed and billed as this row. |
discounted, discount_percent_label | Whether this model is sold below vendor list, and by how much. |
user_discount_percent, user_tier_discounts | Your account's own discount, if any, on top of the public one. |
tokens_per_sec, tokens_per_sec_approx | Measured throughput, for picking between models of similar quality. |
credit_metered, usd_per_credit | Set on the Topaz restoration models, which meter in credits. |
capabilities | Reference-input caps, resolutions, aspect ratios and duration range for media models; context_tokens and max_output_tokens for text models, taken from the vendor's published figures (the hourly OpenRouter record) where available. |
The response also carries default_model — currently claude-haiku-4-5,
used when a chat request omits model.
external_models lists OpenRouter ids GPUniq has no native row for. An
id that resolves to a native slug (anthropic/claude-haiku-4.5,
qwen/qwen3-max, …) is never listed there: a request under it is routed and
billed as the native row, and it appears in that row's aliases. Routing
variants (:batch, :free, :online, :nitro, …) are not listed either —
they cannot be called through chat/completions; only :thinking and
:extended, which are distinct models, stay.
For video models, treat capabilities as a hint and the
video request reference as the contract. A few
entries still advertise values that the request validator refuses —
Veo 3.1, for one, accepts durations of 4, 6 or 8 seconds, not 5.
Prices in rubles
GET /v1/llm/models/catalog/rub returns the same catalog with every price
converted to rubles. Like the USD catalog it is public; call it with your key
and your account discounts are applied, exactly as in the USD version.
curl https://api.gpuniq.com/v1/llm/models/catalog/rub \
-H "X-API-Key: gpuniq_your_key"
import requests
catalog = requests.get(
"https://api.gpuniq.com/v1/llm/models/catalog/rub",
headers={"X-API-Key": "gpuniq_your_key"},
).json()["data"]
print(f"Rate: {catalog['usd_to_rub']} ₽ per $1")
for model in catalog["models"]:
print(model["slug"], model["retail_input_rub_per_mtok"])
The key is optional — without it you get the public prices.
What changes compared to the USD catalog
Rows, their order and every non-price field (slug, media_kind,
capabilities, discounts, throughput, …) are identical. Each price field
swaps usd for rub in its name and holds the ruble amount:
| USD catalog | Ruble catalog |
|---|---|
retail_input_usd_per_mtok, retail_output_usd_per_mtok | retail_input_rub_per_mtok, retail_output_rub_per_mtok |
retail_usd_per_mtok | retail_rub_per_mtok |
retail_usd_per_image | retail_rub_per_image |
retail_usd_per_unit | retail_rub_per_unit |
retail_cached_input_usd_per_mtok | retail_cached_input_rub_per_mtok |
pricing.per_second_usd, pricing.by_resolution_usd, pricing.by_size_usd | the same keys with rub |
official_usd_per_unit | official_rub_per_unit |
usd_per_credit | rub_per_credit |
base_usd_per_mtok (top level) | base_rub_per_mtok |
external_models is converted the same way. Two fields are added at the top
level:
| Field | What it tells you |
|---|---|
currency | Always "RUB". |
usd_to_rub | The rate used for the conversion, rubles per $1. |
A price that is null in the USD catalog stays null. Amounts are rounded to
four decimal places: per-second and per-character media rates are fractions
of a kopeck.
{
"exception": 0,
"message": "Каталог моделей в рублях получен",
"data": {
"currency": "RUB",
"usd_to_rub": 96.8427,
"default_model": "claude-haiku-4-5",
"base_rub_per_mtok": 145.264,
"models": [
{
"slug": "deepseek-v3.2",
"media_kind": "text",
"retail_input_rub_per_mtok": 19.5235,
"retail_output_rub_per_mtok": 29.2852,
"retail_rub_per_image": null,
"discount_percent_label": 30,
"user_discount_percent": 0
},
…
],
"external_models": [ … ]
}
}
Rows are trimmed to a few fields here, and the figures are illustrative —
read current prices from the endpoint. Multiplying any USD price by
usd_to_rub gives exactly the ruble figure in the row.
Which rate is used
usd_to_rub is the rate at which a ruble top-up is credited to your balance
today — the same RUB figure that GET /v1/currency/rates returns. A price in
this catalog is therefore the number of rubles you need to top up to pay for
it at today's rate. The rate refreshes several times a day.
The balance is still charged in USD. The ruble catalog is a view of the
USD one: the model's USD price does not change, but its ruble figure moves
with the rate between requests. Receipts (cost_usd) and your balance stay
in dollars. If your account tops up by invoice at a rate agreed in your
contract, multiply the USD catalog by that rate instead.
Text & reasoning models
The main vendor families. Exact slugs and prices come from the catalog; this is the map of what's on the shelf.
| Vendor | Lines available | Best for |
|---|---|---|
| Anthropic | Claude Opus 5, Sonnet 5, Fable 5; Opus 4.8 / 4.7 / 4.6 / 4.5, Sonnet 4.6 / 4.5, Haiku 4.5 | General reasoning, coding, agents |
| OpenAI | GPT-6 Astra; GPT-5.6, 5.5, 5.4, 5.2 Pro; the Codex line (5.3 / 5.2 / 5.1); o3, o3-pro, o4-mini; GPT-4.1, GPT-4o | Reasoning, structured output, vision |
| Gemini 3.7 Flash, 3.5 Flash, 3.1 Pro, 3 Pro / Flash, 2.5 Pro / Flash; Gemma 4 / 3 | Long context, fast batch work | |
| xAI | Grok 4.5, 4.3, 4.2, 4.1 (incl. Thinking / Fast), Grok 4, grok-code-fast-1 | Real-time knowledge, low latency |
| DeepSeek | V4 Pro / Flash, V3.2 (+ Thinking), V3.1 / Terminus, R1 family, Chat, OCR | Cost-efficient reasoning, OCR |
| Qwen (Alibaba) | Qwen3.6 Max / Plus / Flash, Qwen3.5 line, QwQ, Qwen-VL | Open-weight scale, vision, cheap long context |
| Zhipu | GLM-5.2, 5.1, 5, 4.7 (+ Flash / Thinking), GLM-4V, GLM-OCR | Multilingual, OCR, low cost |
| Moonshot | Kimi K2.7 Code, K2.6, K2.5, K2 (+ Thinking), Moonshot v1 | Long context, agentic coding |
| ByteDance | Doubao Seed 1.6 (+ Thinking / Flash / Lite), Doubao 1.5 Pro | Chinese-first workloads |
| MiniMax | M3, M2.7, M2.5, M2.1, M2 | Balanced cost, multilingual |
| Xiaomi | MiMo v2.5 / v2.5 Pro | Low-cost reasoning |
Filter the catalog by category to narrow it — flagship for the top of each
line, fast for the cheap high-throughput tier.
How pricing works
Every surface bills against the same USD balance, but the unit differs:
| Media kind | Unit | Charged when |
|---|---|---|
| Text | per million tokens, input and output priced separately | On completion. completion_tokens includes any hidden reasoning tokens. Cached input (prompt_tokens_details.cached_tokens) is billed at retail_cached_input_usd_per_mtok only when the provider that served the call gave GPUniq a cache discount; otherwise as normal input. |
| Image | flat, per delivered image | Models rendered on GPUniq's own pipeline (most of the catalog): when the render finishes, whether or not you poll. Natively async upstreams (Nano Banana line, gpt-image-2 family): on the first poll that returns the image. |
| Video | per clip, or per second of output — depends on the model | On the first poll that returns video.url. |
| Music | per call (some models return two tracks for it) | On the first poll that returns the tracks. |
| Speech & audio | per 1000 characters, or per second | On the first poll that returns the file. |
| Topaz restoration | per credit, $0.14 / credit | On the first poll that returns the result. See Topaz. |
A failed, refused or timed-out media job costs nothing. Every media job is
charged once; the terminal payload is replayed to later polls until the
job record expires. For media, the kickoff response carries
estimated_cost_usd and the completion response carries the authoritative
cost_usd and your new balance_usd.
Price before you start
POST /v1/llm/{images,videos,music,audio}/jobs/estimate take the same body as
the kickoff and return the price without starting anything:
// POST /v1/llm/videos/jobs/estimate {"model": "kling-2-6", "prompt": "…", "resolution": "720p"}
{
"model": "kling-2-6",
"estimated_cost_usd": 0.315, // list price — what the kickoff reports and gates the balance on
"discounted_cost_usd": 0.315, // what this account would be charged
"billing_unit": "video",
"unit_price_usd": 0.315,
"units": 1,
"user_discount_percent": 0,
"breakdown": { "config": { "resolution": "720p", "audio": false, "duration": 5, "task": "t2v", "mode": null } }
}
Validation is the kickoff's (model_not_found, invalid_request,
no_provider_available), minus the balance gate. Per-second audio SKUs quote
the same duration assumption the kickoff gates on; the charge uses the real
length.
Discounts
Most models are sold below vendor list price, but the discount is per model,
not a flat platform rate — it ranges from 7.5% to 30% depending on what the
weights cost us wholesale. Read discount_percent_label for the public
discount on a given slug and discounted for whether one applies at all.
Account-level discounts stack on top and appear in the same record as
user_discount_percent / user_tier_discounts, so the catalog you fetch with
your key already reflects your price.
The open-weight tier
Open-weight models — among them deepseek-v4-pro, deepseek-v4-flash,
deepseek-v3.2, gpt-oss-120b, GLM-5.x, Kimi K2.x, MiniMax M3 and Gemma — are
not priced from a fixed catalog number. They are priced from the cheapest live
rate available for those weights, plus our margin, and that moves as the
market moves. Proprietary lines such as Qwen Plus / Max / Flash are not in this
tier and carry a fixed catalog price.
This is why no number for them is printed here: anything published would be stale within days. Read the live figure from the catalog or the model card in /chat.
Your balance
Requests are billed directly against your GPUniq account balance in USD. There is no separate token pool — prepaid token packages and ruble-to-token conversion were retired, and the balance is shared with every other GPUniq surface, so one deposit covers GPU rentals, volumes and every model here.
balance = client.llm.balance()
print(f"Available: ${balance['balance_usd']:.4f} USD")
curl https://api.gpuniq.com/v1/llm/balance \
-H "Authorization: Bearer gpuniq_your_key"
Top up from the web dashboard → Balance: card or SBP through T-Bank, or card through Stripe.
Usage history
Per-request detail with prompt / completion / cached / reasoning tokens and the USD charged.
history = client.llm.usage_history(limit=50, offset=0)
for log in history["logs"]:
print(f"{log['model']}: {log['total_tokens']} tokens — ${log['cost_usd']:.6f}")
| Endpoint | Returns |
|---|---|
GET /v1/llm/usage/history | Per-request log lines, newest first. Money is in USD: cost_usd per line and total_cost_usd in statistics. cost_rub / total_cost_rub are deprecated aliases of the same USD numbers — they never held rubles — and will be removed. |
GET /v1/llm/usage/breakdown | Daily / weekly aggregates by model. |
GET /v1/llm/usage/requests | Request-level records, with GET /v1/llm/usage/requests/{log_id} for one in full. |
completion_tokens counts hidden reasoning tokens as well as the visible
reply. On reasoning models the gap between what you read and what you pay
for is real, not a billing error — see
Long generations.
Model throughput
GET /v1/llm/models/{slug}/performance returns measured throughput for one
model — useful when two models are close on quality and you are choosing on
latency. The same figure appears in the catalog as tokens_per_sec, with
tokens_per_sec_approx flagging whether it is a measurement or an estimate.
curl https://api.gpuniq.com/v1/llm/models/claude-opus-5/performance \
-H "X-API-Key: gpuniq_your_key"