[FEATURE] Add per-request billing classification (subscription vs extra usage) to OTel api_request events

Status Open
Maintainer reply None cached
Activity 0 comments · opened Oct 11, 2026

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

For claude.ai subscribers, cost_usd on claude_code.api_request and the claude_code.cost.usage metric are list-price estimates. OTel consumers cannot tell whether a request was covered by the plan or billed as extra usage, so dashboards cannot separate real extra spend from usage the subscription already absorbed.

Today the only way to classify requests is to route Claude Code through a gateway such as LiteLLM via ANTHROPIC_BASE_URL and read the anthropic-ratelimit-unified-* response headers there. That does not cover sessions that run on Anthropic's infrastructure, such as Claude Code cloud sessions and Claude Tag. They never pass through a customer-run gateway, so their spend cannot be classified at all.

Claude Code already has this information. It reads anthropic-ratelimit-unified-status and anthropic-ratelimit-unified-overage-status on each response and tracks overage state internally (shown in /usage), but none of it reaches OTel. I checked this in v2.1.283.

Inferring the class from auth method does not work. OAuth sessions can be billed as extra usage, and a misrouted session can land on API billing (#68501, #36769).

Proposed Solution

Add an attribute to claude_code.api_request events, derived from the same response's headers. For example:

  • billing.type = "subscription" when unified status is allowed or allowed_warning
  • billing.type = "extra_usage" when unified status is rejected and overage status is allowed or allowed_warning
  • omitted when the headers are absent (API key, Bedrock, Vertex, Foundry) or inconsistent

Adding the same attribute to claude_code.cost.usage and claude_code.token.usage would also help.

Alternative Solutions

  • #16942 asked for utilization gauges. It was closed, and a gauge cannot classify individual requests anyway.
  • A gateway can read the headers for local sessions only, as described above.
  • Exposing extra_usage in the statusLine payload (#82656) does not reach OTel pipelines.

Priority

Medium - Would be very helpful

Feature Category

Other

Use Case Example

  1. Our organization is on a plan with extra usage enabled and exports Claude Code OTel to our own backend.
  2. Members use Claude Code locally, in cloud sessions, and through Claude Tag.
  3. A member hits the 5-hour limit and keeps working on extra usage. Their api_request events look the same before and after the switch.
  4. With billing.type, we could sum cost_usd where billing.type = "extra_usage" per user and alert on it, across every surface and without running a gateway.

Additional Context

  • Verified against the v2.1.283 binary. The unified rate-limit headers are parsed and overage state is held in memory, but the OTel event emitter and the standard attributes carry neither.
  • Related: #16942 (utilization gauges, closed), #82656 and #69791 (rate limits and extra_usage in the statusLine payload).

View original on GitHub ↗