# Cost

> Token and dollar cost of one attempt, how it was attributed, and the price table behind it.

A cost record is the token and money cost of one attempt, summed over every model API request the attempt made.

```json
"cost": {
  "input_tokens": 8000,
  "cached_input_tokens": 320000,
  "cache_creation_tokens": 12000,
  "output_tokens": 16000,
  "requests": 20,
  "usd": 0.99,
  "basis": "measured",
  "tariff": { "id": "prices-3f9a1c2e", "date": "2026-09-01", "source": "prices.toml" }
}
```

Token and money cost of one attempt, summed over all API requests the attempt made. Cached input is separated from uncached because the two are priced differently and blur cost comparisons when merged; cache creation is split by retention bucket for the same reason.

- `input_tokens` (integer): Uncached input tokens.

- `cached_input_tokens` (integer): Input tokens served from cache (cache reads).

- `cache_creation_tokens` (integer): Input tokens written to cache, all retention buckets together, when the provider bills them separately. When the two bucket fields are also present their sum must equal this.

- `cache_creation_5m_tokens` (integer): Cache-creation tokens in the 5-minute retention bucket.

- `cache_creation_1h_tokens` (integer): Cache-creation tokens in the 1-hour retention bucket, priced higher than the 5-minute bucket.

- `output_tokens` (integer)

- `reasoning_tokens` (integer): Reasoning tokens, as a breakdown of output_tokens: output_tokens includes them, as OpenAI and Anthropic report them. A producer whose source reports reasoning separately adds it into output_tokens.

- `requests` (integer): Number of model API requests aggregated into this record.

- `usd` (number): Billed cost in US dollars when the producer knows it. Consumers should prefer recomputing from tokens and a dated price table.

- `basis` (string): How the counts were attributed to this attempt. measured: summed from usage records that identify this attempt exactly (a per-session or per-agent transcript, or per-request usage tied to the attempt). allocated: apportioned from a coarser aggregate (per-day or per-worktree usage) by a heuristic such as a time-window join; consumers should down-weight accordingly. Absent means unknown. Required, and required to be `measured`, when the producer is the extractor (rule E171); from v0.3 a document whose producer is loopmath may give `allocated` when cost.ext[`dev.loopmath.logmatch`] marks a heuristic log match or a shared session.

  Recommended values (open set): `measured`, `allocated`.

- `ext` ([Ext](https://orchestrationcontextprotocol.io/specification/0.3/schema#ext))

- `tariff` ([Tariff](https://orchestrationcontextprotocol.io/specification/0.3/schema#tariff))

## Streams

Tokens are kept per stream because the streams are priced differently. Cached input costs an order of magnitude less than uncached input, and merging the two blurs every cost comparison. Cache creation is kept apart for the same reason, and split by retention bucket where the provider bills the buckets differently.

- When `cache_creation_tokens`, `cache_creation_5m_tokens` and `cache_creation_1h_tokens` are all present, the two buckets MUST add up to the total ([E170](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e170)).
- `input_tokens` is uncached input only. Many tools count cache reads inside input; their exporters subtract `cached_input_tokens` first. See [Implementations](https://orchestrationcontextprotocol.io/docs/implementations).
- `output_tokens` includes reasoning tokens, as OpenAI and Anthropic report them, and `reasoning_tokens` is a breakdown of it. A producer whose source reports reasoning separately from output adds it into `output_tokens`. Never add `reasoning_tokens` to `output_tokens` when totalling a cost.
- An absent cost record means the cost is unknown, not zero.

## Basis

Per-attempt cost is the producer's job, and many tools do not record usage per attempt. `basis` says how the counts were attributed:

| Basis | Meaning |
|---|---|
| `measured` | Summed from usage records that identify this attempt exactly: a per-session or per-agent transcript whose session belongs to this attempt, or per-request usage tied to the attempt. |
| `allocated` | Apportioned from a coarser total, such as per-day or per-worktree usage or a session shared by several attempts, by a rule such as a time-window join. |
| absent | Unknown. |

- A consumer SHOULD weigh `allocated` costs less than `measured` ones.
- A producer MUST NOT write `measured` for counts it apportioned.
- When the producer is loopmath's log extractor, every cost is `measured` ([E171](https://orchestrationcontextprotocol.io/specification/0.3/conformance#e171)). From 0.3 there is one exception: `allocated` is allowed when `cost.ext["dev.loopmath.logmatch"]` marks a heuristic log match or a shared session.

## Dollars and tariffs

`usd` is optional. A consumer SHOULD prefer recomputing dollars from tokens and a dated price table over trusting `usd`, because prices change and tools price differently. When a producer writes `usd`, it SHOULD also write the `tariff` it used.

The price table used to compute usd.

- `id` (string): Price table version: the prices.toml sha256 prefix.

  At most 200 characters.

- `date` (string): The tariff date used, YYYY-MM-DD.

  At most 40 characters.

- `source` (string): Where the prices came from.

  At most 500 characters.

- `ext` ([Ext](https://orchestrationcontextprotocol.io/specification/0.3/schema#ext))
