The provider invoice tells you that spend went up. It cannot tell you whether the increase came from one customer's agent loop, a retry pattern during an outage, or a prompt change that added hundreds of tokens to every chat session. That gap is the whole reason to instrument, and it is the first failure mode teams hit when they try to attribute cost from the invoice alone (Braintrust).
The fix is a fixed schema applied at the call site. A practical minimum set is: feature_id, team, customer_id (or tenant), environment, model, input_tokens, output_tokens, cached_tokens, prompt_version, timestamp, latency_ms, and a success flag. Each field earns its place:
feature_idmakes spend comparable across product surfaces and is what your primary dashboard groups by.teamis the chargeback key and should map to an existing cost center, not a Slack channel name.customer_idcovers multi-tenant B2B products where billing rolls up to organizations rather than seats (Braintrust).environmentkeeps staging traffic out of production totals; a load test indevshould never appear in a team's bill.prompt_versionpins the template so a prompt change that quietly adds 500 tokens shows up as a cost move, not a mystery.successis what lets you compute cost per resolved task rather than cost per call.
Keep cardinality in mind. Low-cardinality fields such as feature, environment, model and prompt version are safe to chart as separate series. High-cardinality fields such as customer_id and agent_run_id are fine to store and filter on but will make a chart unusable if you draw a line per value (Braintrust). The working rule: alert and chart on the cross-product of feature and model; filter by customer only when investigating.



