Calculate LLM cost per customer and feature.
Turn provider token totals into an application ledger that shows which customer, workflow, retry loop, or accepted answer moved the bill—without logging prompts or personal data.
Rate snapshot verified 2026-08-16 · modeled cost is not an invoice
ACCOUNTING MODEL
Keep two ledgers, then make them agree.
Your provider knows billable usage, but it usually does not know that a request belonged to customer tenant_7f42 or the support_reply feature. Your application knows that context. Reliable attribution joins the two views instead of treating either as complete.
What was billed?
Requests, model and service tier, token buckets, cache use, batch status, credits, and provider-specific charges.
Why did it happen?
Opaque tenant, project, feature, attempt, accepted result, and the application request ID that connects the call to a useful outcome.
Privacy boundary: cost accounting does not require prompt text, output text, email addresses, or customer names. Use stable pseudonymous identifiers and protect the mapping in your existing application database.
EVENT FIELDS
Capture one small event after every model call.
Record the provider response's usage values when available. Do not estimate tokens from characters after the fact unless the provider returns no usage data, and label any fallback estimate clearly.
tenant_labelA stable, opaque customer or workspace label. Do not use an email address.
project + workflowThe product area and feature that caused the call.
provider + modelThe actual returned model where the provider exposes it, not only the requested alias.
input + cache bucketsKeep cache reads and provider-reported cache writes separate because each can have a different rate.
output tokensRecord the provider-returned total for the call; reasoning may already be included.
attempt + acceptedCount every paid attempt, and mark whether its result became the accepted answer.
request ID + timeA deduplication and reconciliation key. Keep it in the event log, not the public CSV.
Provider details differ. OpenAI's organization Usage API exposes model, project, user, API-key, batch, service-tier, input, cached-input, and output dimensions. Anthropic separately reports uncached input, cache creation, cache reads, and output. OpenTelemetry's GenAI conventions provide portable model, operation, workflow, cache-read, reasoning, and token attributes, but the conventions are still evolving.
LEDGER EXPORT
Aggregate events into a reviewable CSV.
For the free TokenGauge ledger, use project as the opaque customer or workspace grouping and workflow as the feature. Aggregate rows over one stated time window and preserve the event-level request IDs in your own system for deduplication.
project,workflow,rate_card_id,input_tokens,cached_input_tokens,output_tokens,attempts,accepted_answers
tenant_7f42,support_reply,openai:gpt-5.6-terra:standard:short,820000,410000,96000,125,103
tenant_a19c,document_extract,openai:gpt-5.6-luna:standard:short,360000,0,28000,84,79((uncached input × input rate) + (cached input × cache-read rate) + (output × output rate)) ÷ 1,000,000 Add explicit cache-write, storage, and tool charges to the explained residual.
Allocate the row cost by the share of attempts that did not become accepted answers. Treat this as a diagnostic estimate when attempts vary materially in size.
Attributed model cost is one direct-cost input, not complete cost of goods sold. Add tools, storage, search, hosting, support, and payment costs separately.
RECONCILIATION
Prove the estimate against the bill.
- 1
Freeze the window
Use the same UTC start and end time in the application export and provider report. Late-arriving usage should go into the next reconciliation run or an explicit adjustment.
- 2
Separate every rate dimension
Do not merge models, long-context tiers, service tiers, regions, batch jobs, or cache modes until after pricing. Map each group to the rate effective when the request ran.
- 3
Compare counts before money
Reconcile request counts and token buckets first. A money mismatch is much easier to diagnose after duplicate requests, missing streams, and retry events are removed.
- 4
Explain the residual
Record credits, taxes, commitments, non-token tools, rounding, and unsupported charge types. Never force the modeled token total to equal the invoice by hiding the difference.
A good control is explicit: provider total = attributed token estimate + explained residual. Keep the residual visible even when it is zero.
COMMON MISTAKES
Five ways attribution quietly lies.
Pricing the requested alias
Record the model actually returned where possible. Aliases and routed models can move.
Ignoring cache buckets
Cached input may have a different rate; cache creation can be another rate again.
Counting only successes
Discarded, failed, and retried calls can still consume billable tokens.
Calling an estimate an invoice
Published token rates do not capture every credit, commitment, tax, tool, or storage charge.
Using personal data as labels
A stable opaque ID is enough. Keep names, emails, prompts, and outputs out of the cost ledger.
Before you instrument.
Is the token-rate calculation the same as my provider invoice?
No. It is a modeled direct token cost. Credits, taxes, commitments, tools, storage, regional pricing, and other provider charges can make the invoice differ, so reconcile the model to the provider billing export.
Do I need to store prompts or model outputs?
No. Cost attribution can use opaque customer labels, workflow labels, rate-card identity, aggregate token buckets, attempts, and accepted-answer counts without storing prompt or output content.
How should retries be counted?
Count each provider request as an attempt, including failed or discarded attempts that consumed billable tokens. Count an accepted answer only when the application actually uses that result.
Want the ledger path installed?
The fixed £75 service adds project/workflow attribution, retry-aware usage fields, a canonical CSV export, focused tests, and one revision after a written scope.