Pricing & budgets
Estimate GPT-6 Astra, GPT-5.6, Claude Opus 5.5, Sonnet 5.5, Haiku 5.5 and Fable 5.1 costs from one usage contract. Track live spend and share execution budgets across agents in Deuz SDK 2.3.
Le contenu des pages de documentation est en anglais. La navigation, la recherche et l’interface suivent la langue choisie.
Turn token usage into a dollar estimate, show cost as an agent runs, and give a
whole swarm one shared budget. Everything lives behind the optional
@deuz-sdk/core/pricing module. Deuz reports usage and estimates; your application
owns billing.
Estimate
Price a model call, including reasoning and cache usage.
Track
Read cumulative cost and cache savings from the stream.
Control
Share an execution budget across native agent runs.
Current model prices
These models are included in PRICES_2026. Rates are USD per 1 million
tokens for standard API processing. Use the exact API IDs shown here when
calling priceUsage; an ID the table does not list returns undefined rather
than a related model's price (see model lookup).
Verified September 20, 2026, except GPT-6.1 Sol.
| Model / API ID | Input | Cache read | Output + reasoning |
|---|---|---|---|
GPT-6 Astra · gpt-6-astra | $10.00 | $1.00 | $50.00 |
GPT-6.1 Sol · gpt-6.1-sol ¹ | $2.00 | $0.10 | $10.00 |
GPT-5.6 Sol · gpt-5.6-sol | $4.00 | $0.40 | $20.00 |
GPT-5.6 Terra · gpt-5.6-terra | $2.00 | $0.20 | $12.00 |
GPT-5.6 Luna · gpt-5.6-luna | $0.20 | $0.02 | $1.20 |
¹ Research-dated (October 9, 2026) and not re-verified. Its long-context, tier and regional multipliers are unverified, so the row applies its standard rates to every prompt length.
gpt-5.6 is also priced as Sol. Sol's promotional rates are available at least
through November 21, 2026. OpenAI lists cache writes at 1.25× the input rate,
but its usage reports no cache-write counter: the OpenAI adapters report
cacheWriteTokens: 0, so those prompt tokens are estimated at the input rate
(not live-verified). See OpenAI API pricing.
Checked October 6, 2026 against Anthropic's Claude API reference.
| Model / API ID | Input | Cache read | Output + reasoning |
|---|---|---|---|
Claude Opus 5.5 · claude-opus-5-5 | $4.00 | $0.20 | $20.00 |
Claude Sonnet 5.5 · claude-sonnet-5-5 | $2.00 | $0.20 | $10.00 |
Claude Haiku 5.5 · claude-haiku-5-5, up to 100K | $0.10 | $0.01 | $0.50 |
Claude Haiku 5.5 · claude-haiku-5-5, above 100K | $0.50 | $0.05 | $2.50 |
Claude Fable 5.1 · claude-fable-5-1 | $10.00 | $0.25 | $50.00 |
Claude Opus 5 · claude-opus-5 | $5.00 | $0.50 | $25.00 |
Claude Sonnet 5 · claude-sonnet-5 | $2.00 | $0.20 | $10.00 |
| Cache write | 5-minute retention | 1-hour retention |
|---|---|---|
| Opus 5.5 | $5.00 | $8.00 |
| Sonnet 5.5 | $2.50 | $4.00 |
| Haiku 5.5 | $0.125 / $0.625 | $0.20 / $1.00 |
| Fable 5.1 | $12.50 | $20.00 |
| Opus 5 | $6.25 | $10.00 |
| Sonnet 5 | $2.50 | $4.00 |
Cache reads cost 10% of input except on Opus 5.5 (5%) and Fable 5.1 (2.5%), whose rows override the SDK's 10% default. Haiku 5.5 has two cards: a prompt above 100,000 tokens (fresh input, cache reads and cache writes together) moves the whole request to the higher card. The other models have no long-context premium within their 1M context. Claude Sonnet 5 was pinned at $3/$15 before 2.3; the reference lists $2/$10. See Anthropic pricing and the model overview.
Long context and other tariffs
For the listed GPT-6 Astra and GPT-5.6 models, prompts above 272,000 tokens
use 2× input and cache rates and 1.5× output rates for the whole request.
The bundled rows apply that tier automatically. See the Astra model reference
and Sol model reference.
Haiku 5.5 uses the same mechanism at 100,000 tokens, and a row's
tiers can express any other threshold.
Batch, fast mode, regional processing, gateway markups and negotiated contracts can use different prices. Supply a custom price provider for the tariff you actually use. A model's price-table entry does not grant API access or select a processing tier.
priceUsage
Pass a model ID and the Usage returned by an SDK call. The result is a USD
number, rounded to six decimal places, or undefined if no price can be resolved.
import { generateText } from '@deuz-sdk/core';
import { createOpenAIResponses } from '@deuz-sdk/core/openai';
import { priceUsage } from '@deuz-sdk/core/pricing';
const openai = createOpenAIResponses({ apiKey: process.env.OPENAI_API_KEY! });
const modelId = 'gpt-5.6-sol';
const { text, usage } = await generateText({
model: openai(modelId),
prompt: 'Explain what makes an agent run durable.',
});
const usd = priceUsage(modelId, usage);
console.log(text);
console.log(usd === undefined ? 'Price unavailable' : `$${usd.toFixed(6)}`);Same usage, different models
This example is local arithmetic and makes no API calls. reasoningTokens is
the reasoning share of outputTokens, as every adapter reports it.
import type { Usage } from '@deuz-sdk/core';
import { priceUsage } from '@deuz-sdk/core/pricing';
const usage: Usage = {
inputTokens: 10_000,
outputTokens: 3_000, // 1,000 of them reasoning
reasoningTokens: 1_000,
cachedReadTokens: 20_000,
cacheWriteTokens: 0,
cacheWrite1hTokens: 0,
totalTokens: 33_000,
};
priceUsage('gpt-5.6-sol', usage); // $0.108
priceUsage('gpt-6-astra', usage); // $0.270
priceUsage('claude-opus-5-5', usage); // $0.104
priceUsage('claude-sonnet-5-5', usage); // $0.054
priceUsage('claude-haiku-5-5', usage); // $0.0027
priceUsage('claude-fable-5-1', usage); // $0.255For Sol, that is $0.040 input + $0.060 output (reasoning included) + $0.008 cache reads. This holds token counts constant; actual tokenization and reasoning usage vary by model.
Usage anatomy
Every adapter normalizes the provider's counters to one contract: the input
buckets are disjoint, outputTokens holds every generated token, and
reasoningTokens and audioTokens are shares of those buckets. priceUsage
therefore bills each token once:
| Usage field | How it is priced |
|---|---|
inputTokens | Fresh input × input. Excludes cache reads and cache writes. |
outputTokens | Every generated token, reasoning included, × output. |
reasoningTokens | Not billed again: it is the reasoning share of outputTokens. |
cachedReadTokens | Cache hits × cachedRead; default is 0.1× input. |
cacheWriteTokens | Cache writes × cacheWrite; default is 1.25× input. |
cacheWrite1hTokens | One-hour writes × cacheWrite1h; default is 2× input. |
audioTokens | Not billed again; a row's audio rate re-prices the share from input. |
serverToolUses | Excluded. Add per-call search/tool fees separately. |
totalTokens | A usage total, not an additional charge. |
How each wire maps onto that contract:
| Adapter | Normalization |
|---|---|
| OpenAI Responses | output_tokens already includes reasoning_tokens. |
| Chat Completions | completion_tokens already includes reasoning. |
| DeepSeek, Moonshot | prompt_cache_hit_tokens or a top-level cached_tokens are cached reads. |
| Anthropic | output_tokens includes thinking; thinking_tokens is its share. |
| Gemini native | outputTokens is candidates + thoughts; thoughts are its share. |
On every wire, inputTokens leaves cached reads out. A Chat Completions or
Responses-shaped host that counts reasoning beside the output (its total is
prompt + output + reasoning, or the reasoning exceeds the output) has it folded
into outputTokens. These host shapes come from provider documentation and are
not live-verified. Usage you build yourself in the 2.2 shape, with
reasoningTokens larger than outputTokens, still bills both counters in full.
Audio
audioTokens merges prompt and completion audio. A row's audio rate re-prices that whole share
from the input rate, which fits audio input. If a model bills audio output at yet another rate,
price it in your own PriceProvider.
generateText, generateObject, embed and embedMany return usage directly.
For streamChat, consume the stream and then await result.usage. Embedding
calls populate input usage; their output and cache buckets are zero.
Cache savings
cacheSavings(model, usage, table?) estimates what cache reads saved compared
with paying the full input rate for those tokens. It excludes cache-write costs.
import { cacheSavings } from '@deuz-sdk/core/pricing';
// Reusing the usage above:
cacheSavings('claude-fable-5-1', usage); // $0.195
cacheSavings('gpt-5.6-sol', usage); // $0.072PriceProvider and the deps seam
Use createPriceProvider() to connect the bundled table to calls through
deps.priceProvider. A client can bind it once for
all calls. This enables live cost events and USD budget checks.
import { createClient } from '@deuz-sdk/core';
import { createOpenAIResponses } from '@deuz-sdk/core/openai';
import { createPriceProvider } from '@deuz-sdk/core/pricing';
const deuz = createClient({
apiKeys: { openai: process.env.OPENAI_API_KEY! },
deps: { priceProvider: createPriceProvider() },
});
const openai = createOpenAIResponses();
const result = await deuz.generateText({
model: openai('gpt-6-astra'),
prompt: 'Review this architecture: one scheduler, many bounded agent tasks.',
});
console.log(result.text);A custom PriceProvider can load prices from your own service. Its
priceUsage(model, usage) method may return a number, undefined, or a promise
of either. The optional cacheSavings method has the same return shape. Keep
these methods free of billing side effects: the SDK may request multiple
estimates for the same work.
Metering: the onUsage callback
onUsage receives usage with the model ID that actually ran. In a tool loop,
it can fire multiple times as model invocations finish. Price those invocations
individually when a run switches models or delegates to another agent.
import { streamChat } from '@deuz-sdk/core';
import { createAnthropic } from '@deuz-sdk/core/anthropic';
import { createPriceProvider, priceUsage } from '@deuz-sdk/core/pricing';
const anthropic = createAnthropic({ apiKey: process.env.ANTHROPIC_API_KEY! });
const result = streamChat({
model: anthropic('claude-fable-5-1'),
prompt: 'Explain prompt caching with a short example.',
deps: { priceProvider: createPriceProvider() },
onUsage: (usage, meta) => {
console.log({
model: meta.model,
reason: meta.reason,
tokens: usage.totalTokens,
estimatedUsd: priceUsage(meta.model, usage),
agentPath: meta.agentPath,
});
},
});
for await (const text of result.textStream) process.stdout.write(text);The call-level callback overrides deps.onUsage; they are not both invoked.
UsageMeta exposes model, reason, optional ttftMs and optional agentPath.
It contains no dollar amount. Aborted calls can report partial usage; a failure
before usage is available does not guarantee a callback. Since 2.3,
usageAvailable: false marks usage the provider did not report: it sent none,
or the stream ended before its usage arrived. usage then holds zeros or only
what arrived, so the call's cost is unknown; do not bill it as a free call.
Keep metering callbacks synchronous
onUsage is a notification hook; the SDK does not await an async callback. For database writes,
collect records or enqueue work and explicitly await your application's flush before a request or
worker exits.
Live cost stream
With a price provider, streamChat emits cost parts through fullStream and
the UI wire v2. Agent loops emit them at model-step
boundaries; a single-turn stream emits one before finishing. Tool or child-agent
work after an event can appear in a subsequent cost update.
import { streamChat } from '@deuz-sdk/core';
import { createOpenAIResponses } from '@deuz-sdk/core/openai';
import { createPriceProvider } from '@deuz-sdk/core/pricing';
const openai = createOpenAIResponses({ apiKey: process.env.OPENAI_API_KEY! });
const result = streamChat({
model: openai('gpt-5.6-sol'),
prompt: 'Outline a migration plan in five steps.',
deps: { priceProvider: createPriceProvider() },
});
for await (const part of result.fullStream) {
if (part.type === 'cost') {
console.log({
totalUsd: part.costUsd,
stepUsd: part.deltaUsd,
savedUsd: part.cacheSavingsUsd,
});
}
}| Field | Meaning |
|---|---|
costUsd | Cumulative estimated cost. Display it directly; do not sum these events. |
deltaUsd | Optional increment since the previous reported cost. |
cacheSavingsUsd | Optional savings on cache reads, when available and positive. |
stepIndex | Optional step index. |
In 2.1, tool-loop accounting prices individual invocations against their actual
model and preserves settled dollar totals across durable resumes.
Changing models does not reprice previous calls at the final model's rate.
If an invocation cannot be priced, the loop cannot report a complete cumulative
cost. Missing pricing is unknown, not zero. So is a call whose usage the
provider did not report (since 2.3): a single call emits no cost part for it,
and a loop emits no further cost parts, exactly as an execution context's
ledger keeps that call's cost unknown.
The budget guardrail
For existing generation/tool loops, budget checks cumulative usage and estimated
cost at step boundaries. budget.usd needs a price provider; budget.tokens uses
reported token usage.
const result = streamChat({
model: openai('gpt-5.6-sol'),
prompt: 'Investigate the issue and propose a fix.',
tools,
maxSteps: 12,
budget: { usd: 0.5, tokens: 100_000 },
deps: { priceProvider: createPriceProvider() },
});
await result.consume?.();The current step finishes before the check stops further work. Streaming emits
budget-exceeded before finish, and providerMetadata.deuz.stoppedBy identifies
budget.usd or budget.tokens. Resume retains prior usage and known cost.
Without a price provider, or with incomplete pricing, the USD condition cannot protect the run. Include a token limit and a step limit as independent controls. For admission checks before a model attempt, use native execution budgets.
When a call's cost is unknown, because its price lookup failed or the provider
did not report its usage, the run's cost is unknown from then on, and
budget.usd, like costExceeds, waits instead of stopping the loop. A call
without usage adds no tokens either, so only the step limit is sure to bound a
host that never reports usage. A native execution budget keeps that call's
reservation held instead, so its limits still apply.
Native agent and swarm budgets
Native agents in 2.1 reserve estimated tokens and dollars before dispatch. Parent and child contexts share a ledger, so delegated work consumes the same budget. A USD limit requires a known USD estimate for admission.
import { createExecutionContext, runAgent } from '@deuz-sdk/core/agent';
import { createOpenAIResponses } from '@deuz-sdk/core/openai';
import { createPriceProvider } from '@deuz-sdk/core/pricing';
const openai = createOpenAIResponses({ apiKey: process.env.OPENAI_API_KEY! });
const execution = createExecutionContext({
budget: { usd: 2, tokens: 100_000 },
});
const result = await runAgent({
model: openai('gpt-6-astra'),
prompt: 'Propose a test plan for a durable task scheduler.',
maxSteps: 4,
maxOutputTokens: 2_000,
execution,
deps: { priceProvider: createPriceProvider() },
});
console.log(result.status, result.accounting);| Accounting field | Meaning |
|---|---|
spent | Known actual token and USD amounts. |
reserved | Still-held estimates, including uncertain attempts. |
committed | Spent + reserved. |
unknownTokens / unknownUsd | Counts of attempts whose actual amounts remain unknown. |
Missing usage or failed pricing keeps reservations held. Native sessions and
swarms persist the ledger for recovery; resuming cannot reset spend or loosen
saved parent limits. Verification callbacks that make SDK calls must forward
their execution and signal.
Admission uses estimates, so actual usage can exceed a reservation. The ledger records that overage and prevents later admission when the limit is exhausted. See native agent budgets and swarm budgets for persistence and child-policy details.
Custom rates and margins
Override individual rows for a deployment, or add your own model. Each supplied row replaces the complete row for that ID. Spread an existing row to preserve its cache rates and long-context tiers.
import { createPriceProvider, PRICES_2026 } from '@deuz-sdk/core/pricing';
import type { PriceTable } from '@deuz-sdk/core/pricing';
const table: PriceTable = {
'claude-opus-5': {
...PRICES_2026['claude-opus-5'],
input: 4.5, // Example contract rates, not public list prices.
output: 22.5,
cachedRead: 0.45,
cacheWrite: 5.625,
cacheWrite1h: 9,
},
};
const priceProvider = createPriceProvider({ table, margin: 1.2 });
// The factory retains other bundled rows and applies a 20% markup.
const usd = await priceProvider.priceUsage('claude-opus-5', usage);margin is a multiplier, defaults to 1, and also scales cacheSavings.
createPriceProvider performs no network calls and works in edge runtimes.
Passing priceUsage(model, usage, table) directly is different: the third argument
is the entire lookup table, with no automatic merge. To extend the bundled
table in that form, pass { ...PRICES_2026, ...table }.
Model lookup
Lookup is explicit. It resolves an ID in this order and stops at the first row it finds:
- The exact ID.
- An entry in
PRICE_ALIASES, such asmistral-large-latest→mistral-large. - Both again after dropping one vendor prefix, in any case (
openai/…,Qwen/…). - Both again after dropping a trailing snapshot date with a real month and
day (
-2025-12-11,-20251001or-251001).
Anything else returns undefined. Lookup never falls back to a family prefix,
so a new model, a variant with its own tariff or a made-up suffix stays unpriced
instead of borrowing a related row.
priceUsage('openai/gpt-6-astra', usage); // The Astra row.
priceUsage('claude-haiku-4-5-20251001', usage); // The claude-haiku-4-5 row.
priceUsage('claude-opus-5-not-a-real-model', usage); // undefined, not the Opus 5 price.
priceUsage('my-private-model', usage); // undefined without a matching row.Map your own IDs onto rows with aliases. An alias resolves only when its target
row exists, and the target can be one of your custom rows:
import { createPriceProvider } from '@deuz-sdk/core/pricing';
const priceProvider = createPriceProvider({
aliases: {
'prod-sonnet': 'claude-sonnet-5-5', // a deployment name
'kimi-k2-0905-preview': 'kimi-k2', // a snapshot you bill at the K2 rate
},
});With a USD budget, a call to an unpriced model is not bounded in dollars and
reports an unpriced-model warning; token limits still apply. Price the model
with a row or an alias, or keep a token limit beside the USD limit. Do not turn
undefined into a zero-dollar charge.
PRICES_2026 and ModelPrice
PRICES_2026 is a bundled snapshot, not a live pricing feed. The highlighted rows
above were checked on the stated dates; other bundled models retain their own
historical rates. Check the provider's tariff when updating a deployment.
PriceTable is Record<string, ModelPrice>. Each row requires input and
output, with optional cachedRead, cacheWrite, cacheWrite1h and audio rates.
Long-context price cards go in tiers:
import type { PriceTable } from '@deuz-sdk/core/pricing';
const table: PriceTable = {
'my-model': {
input: 1,
output: 4,
cachedRead: 0.1,
tiers: [
{ above: 128_000, input: 2, output: 6 },
{ above: 512_000, input: 4, output: 8, cachedRead: 0.4 },
],
},
};A tier's above is an exclusive threshold on the prompt: fresh input, cache
reads and both cache-write buckets. The highest threshold the prompt exceeds
prices the whole call. A rate the tier omits falls back to the row's own
rate (the 128K card above keeps cachedRead: 0.1), so spell out every rate that
changes. The two earlier fixed tiers keep working and take part in the same
choice:
| Row field | Trigger | Behavior |
|---|---|---|
tiers | The prompt exceeds a tier's above | Used by the Haiku 5.5 row at 100,000 tokens. |
over200k | inputTokens + cachedReadTokens > 200_000 | Existing tier for selected Gemini rows. |
over272k | Fresh input + cache reads + both cache-write buckets > 272,000 | Tier used by the listed GPT-6 / GPT-5.6 rows. |
Price individual invocations before summing their costs; a run's accumulated
tokens are not one long prompt. priceUsage and cacheSavings select the same
tier.
API at a glance
| Export | Use it for |
|---|---|
priceUsage(model, usage, table?) | Estimate one invocation in USD. |
cacheSavings(model, usage, table?) | Estimate savings from cache reads. |
createPriceProvider({ table?, aliases?, margin? }) | Inject pricing into calls or clients. |
PRICES_2026 | Read or extend the bundled rates. |
PRICE_ALIASES | Read the bundled explicit aliases. |
ModelPrice, PriceTable, PriceTier | Type your own pricing configuration. |
Prices here cover the token buckets available in Usage. Per-request fees,
provider tools, storage, media jobs and application infrastructure need their own
accounting. Continue with clients and dependencies,
UI streaming, native agents
or swarms.
Middleware
Wrap a model with composable, removable layers for logging, caching, redaction, and prompt-injection defense.
Model profiles
Ask what Deuz knows about a model before you call it — supported, unsupported or unknown capabilities, limits, effort rules, and every value a request changes. New in 2.3.