kibble

Kibble Blog

Estimated vs billed: why a coding-agent cost dashboard must never add the two

Estimated usage cost and actual charges answer different questions. A local tool prices logged tokens at a rate card. A vendor analytics API can report an estimate too: the source alone does not make a figure billed. Use the actual invoice to establish charges, and never add overlapping views of the same usage together.

Check the cost basis, not just the source

The estimate comes from the transcript files the agent writes on each machine (here is where they live). Sum the four token fields per turn, multiply by the model's list rates, and you have a per-day, per-engineer, per-repo figure with fine grain and no authority. It is available for every agent and every seat, including the ones nobody is billing per token.

The billed figure comes from the vendor. Anthropic distinguishes usage reports from cost reports: the groupings and coverage differ. These reports do not establish which repository a shared key worked in. Reconcile billing against the actual account terms and invoice.

Kibble reads the Claude Code Analytics API. Its estimated_cost field is a vendor-reported estimate, not an invoice amount. Local and vendor estimates can differ because of coverage and pricing assumptions; either can differ from actual charges.

Six reasons they disagree

1. Seats do not bill per token

Included subscription usage is not a separate API-token bill. A local estimate is the equivalent API cost at its rate card. Extra usage and plan-specific arrangements can still create metered charges, so read the actual subscription terms before interpreting it.

2. The rate card moves

List prices change, new models arrive with new rates, and a pricing table embedded in a tool is exactly as current as its last release. The vendor prices each request at the rate in force when it ran. An estimate made at today's rates for last quarter's tokens is wrong by whatever changed in between.

3. Discounts and tiers

Batch pricing, negotiated terms, fast mode and cache-write duration can change the price. Some logs identify some of those categories, but they do not establish the company's billing contract. Compare the estimator's assumptions with the applicable vendor rates.

4. Transcripts get cleaned up

Claude Code deletes session files older than its retention window, 30 days by default. A collector that started in June has no estimate for May, and none will ever appear. The billed report for May is still there. A dashboard that sums the two would show May as cheap.

5. Days end at different times

Compare the same time zone, date range and completed collection window. A session can span midnight, so its records can contribute to more than one day; it is not automatically assigned to one day as a whole. An invoice's billing period may also differ from the calendar range on a dashboard. A wider range can help diagnose a boundary mismatch, but it does not guarantee that a difference disappears.

6. The same request, counted twice

An agent run on a laptop and an agent run in CI can share an API key. The billed report puts both on the key. The local estimate puts the laptop's tokens on the laptop and, if the collector also runs in CI, the runner's tokens on the runner. That is the whole reason to have the estimate. It is also why the two sets of rows describe the same dollars from two directions, and adding them counts every request twice.

The rule

Label the cost basis. Merge overlapping usage once. Verify charges against the invoice.

Kibble sums a member's local devices before merging local and vendor usage at its reporting grain. Claude Console estimates replace matching local estimates; remote vendor usage remains additive because the local collector cannot see it. This source precedence does not turn either estimate into billed cost. Repository attribution is a separate local estimate and is not an invoice allocation. Owners and managers do not receive a per-machine breakdown; machines remain visible only to their owner.

Two practical consequences fall out:

What to do with the gap

A gap is a clue, not a diagnosis. Check reporting windows, subscription coverage, the rate card and machines that stopped reporting. No percentage by itself proves a pricing error or duplicate collector. Start with the worked cost calculation and collection status, then investigate the difference.

A useful dashboard labels its estimates and coverage. Actual charges still need the vendor invoice and the billing terms behind it.