Search

↑↓ to move↵ to openesc to closetop 6 documentation results

Book a demoTry TokenTriage

In development · Explore the product preview. Join the launch list or book a walkthrough.

Browse docs

Override a price

Correct or supply a rate without rebuilding the binary. Overrides take effect on a date, retire rather than disappear, and stamp every row they price.

How-to guideLast updated

On this page

The Pricing surface is showing rows as UNPRICED, or the embedded table has a rate that does not match the contract you signed. You need a different price without waiting for the next release.

An override supplies one. What makes it worth a page is not the substitution but the three rules around it: an override applies from a date, it retires rather than disappears, and it brands every row it prices so an overridden dollar can never be mistaken for a catalogue one.

Point the config at an artifact

pricing:
  overrides_file: /var/lib/tokentriage/pricing-overrides.json

One file, layered over the embedded price table. It is read at boot, so changing the path is a restart. The Pricing surface reports whether the artifact it is showing you is live or waiting for one, which is worth checking before you conclude an override is not working.

An entry looks like this:

{
  "overrides": [
    {
      "key": "anthropic/claude-sonnet-4-5",
      "effective_from": "2026-09-01",
      "in": 0.0000024,
      "out": 0.000012,
      "created_by": "[email protected]",
      "created_at": "2026-08-10T18:00:00Z",
      "status": "active",
      "note": "negotiated rate, contract 4471"
    }
  ]
}

Rates are dollars per token. key is a pricing key, and getting it right is the part people get wrong: pricing keys explains how a request resolves to one, and the Pricing surface has a dry-run match that shows you what a given model resolves to before you commit.

You can write an override from the Pricing surface instead of by hand. Doing so needs the operator role.

The three rules

An override applies from a date, never before it. effective_from names an instant, and the entry prices requests at or after it. A future-dated override is visible and browsable now, and inert until its date arrives, which is how you land a contract change ahead of time rather than at midnight.

It is not retroactive. Rows already in your ledger keep the dollars they were written with. An override changes what the next request costs, and nothing about what a past one did. That is why last month’s total does not move when you correct a rate.

A superseded rate is retired, not deleted. Retiring an entry stops it pricing anything new while leaving it in the artifact, so a row priced under it stays explainable. The stamp is computed over the rate itself rather than over the entry’s status, so a row priced under a now-retired override still matches the stamp it carries.

How an overridden dollar identifies itself

A row priced through the embedded table carries the catalogue snapshot:

litellm@2026-07-14#179affb

A row priced through an override carries an operator stamp instead:

operator@2026-09-01#a1b2c3d

Source, effective date, and a short hash of the rate identity. It appears wherever a pricing snapshot appears: in cost.pricing_snapshot on the ledger row, on the record, and in exports.

That is the property that makes overrides safe to use at all. Someone auditing a figure can tell which rows were priced under a local rate and go and read that rate, rather than wondering why a number does not match a public price list.

Triage the unpriced rows first

localhost:9090/ui/pricingDemo data
The Pricing surface showing the active snapshot with its source, fetch date, generator and model count, and an unpriced triage panel listing the models that appear in the ledger with no entry in the price table.
The unpriced triage lists the models your traffic used that the price table does not cover. Each is a candidate for an override (real dashboard, demo mode).

The unpriced panel is the list of models your own traffic used that the table cannot price. Every row on it is excluded from every dollar total, so working the list down to zero is what makes your cost figures complete rather than merely correct.

An instance with nothing to triage says so: No unpriced rows — every logged row has a price.

Retiring one

Set an entry’s status to retired, or use the retire action from the surface. It stops pricing new requests immediately; nothing else changes. Do not delete the entry, because deleting it removes the record of a rate that priced real rows, and the stamp on those rows then points at nothing.

If the correct move is a different rate rather than none, add a new entry with a later effective_from and retire the old one. The artifact then reads as a history of what you charged yourself and when.

When an override is the wrong tool

The model has a price and you disagree with the catalogue. Check the pricing key first. A mismatch is more often a key resolving to a different variant than a wrong rate, and an override on the wrong key will not fix it.

A whole provider is missing. That is a descriptor question rather than a price one. Add a provider covers declaring an upstream, including declaring one free.

You want a different price per tenant. Overrides are global to the instance. Per-tenant economics belong to chargeback, which attributes the same dollars differently rather than changing them.

You want last month’s total to change. It will not. Overrides are forward-only, and reprocessing history is not something this product does.

What can go wrong

The override does nothing. Three checks, in order: is the artifact live rather than pending a restart, has effective_from arrived, and does the key match what the model resolves to. The surface answers the first two, and the dry-run match answers the third.

Rows still read as unpriced. The key is not matching. Use the dry-run rather than guessing at the spelling.

An old row’s snapshot names an override you cannot find. It was retired, and it should still be in the artifact. If it is not, somebody deleted it, and that row’s provenance is now unrecoverable — which is the reason for the retire-not-delete rule.

Two entries cover the same key. The one whose date has arrived most recently wins. Keep that legible by retiring what you have superseded.