DEV Community

Cover image for How to Track Claude Code Usage Across Your Team (Per Developer, Per Project)
Kuldeep Paul
Kuldeep Paul

Posted on

How to Track Claude Code Usage Across Your Team (Per Developer, Per Project)

There are four ways to track Claude Code usage across a team, and they answer different questions. /usage shows one developer their own session. The built-in analytics (the claude.ai admin console on Team and Enterprise plans, or the Claude Console on API billing) show adoption and spend per user. OpenTelemetry export streams per-user tokens, cost, sessions, commits, and pull requests into your own observability stack in near real time, on any plan or provider. An LLM gateway records every request with the developer's identity, the model, tokens, and cost, and can also enforce budgets. Most teams end up using built-in analytics for adoption and either OpenTelemetry or a gateway for cost attribution by person, team, and repository.

This post sets up each option, shows how to attribute usage to projects as well as people, and lists the weekly numbers worth reporting.

Four ways to track Claude Code usage: /usage, Anthropic analytics, OpenTelemetry export, and an LLM gateway

Pick the right tracking method

Method Works on Per-user Per-team or project Real time Enforces limits
/usage Every plan and provider Own machine only No Yes No
Team and Enterprise analytics Claude for Teams and Enterprise Yes (spend report CSV, Enterprise Analytics API) By user groups Updated daily Spend limits for usage credits
Console dashboard and Claude Code Analytics API Claude Console (API) Yes By workspace Daily metrics Workspace spend limits
OpenTelemetry export Every plan and provider Yes Yes, via resource attributes Near real time No
LLM gateway API keys and cloud providers Yes, per virtual key Yes, via key metadata and headers Per request Yes: budgets, rate limits, model allowlists

If your developers use Claude Code through Amazon Bedrock, Google Cloud, or Microsoft Foundry, the built-in analytics do not cover that usage. Claude Code does not send metrics from your cloud back to Anthropic, so OpenTelemetry or a gateway is the only way to get per-developer numbers there, per the Claude Code cost documentation.

Option 1: /usage for individual developers

Every developer can run /usage in a session. The Session block shows token usage by model, cache reads and writes, and a dollar estimate computed locally at list price:

Total cost:            $0.55
Total duration (API):  6m 20s
Total duration (wall): 6h 33m 10s
Total code changes:    0 lines added, 0 lines removed
Usage by model:
   claude-sonnet-4-6:  1.2k input, 5.3k output, 940.0k cache read, 50.0k cache write ($0.55)
Enter fullscreen mode Exit fullscreen mode

On Pro, Max, Team, and Enterprise plans, /usage also attributes recent usage to skills, subagents, plugins, and individual MCP servers, and recommends changes for anything behind 10% or more of recent usage (for example, trimming a large CLAUDE.md). Press d or w to switch between 24 hours and 7 days.

It is useful for individual habits, and nothing more: the figures come from local session history on that one machine.

Option 2: Built-in analytics

Team and Enterprise plans. The analytics dashboard shows daily active users, sessions, and contribution metrics with CSV export. The spend report in org analytics shows estimated spend per user and per model, updated daily, once usage credits are on. On Enterprise, the Enterprise Analytics API returns per-user usage and cost reports programmatically with a key that has the read:analytics scope.

Claude Console (API billing). The first time someone authenticates Claude Code with a Console account, a workspace called "Claude Code" is created automatically for centralized cost tracking. The Console dashboard shows spend and accepted lines per member, and the Claude Code Analytics API returns the same daily per-user metrics with an Admin API key.

Built-in analytics need no setup, which makes them the right first step. Their limits: daily granularity, no custom dimensions such as repository or ticket, and no coverage for cloud-provider usage.

Option 3: OpenTelemetry export

Claude Code exports metrics and events over OpenTelemetry on every plan and provider. Per the monitoring documentation, you turn it on with environment variables:

export CLAUDE_CODE_ENABLE_TELEMETRY=1
export OTEL_METRICS_EXPORTER=otlp          # otlp, prometheus, console, none
export OTEL_LOGS_EXPORTER=otlp             # events: prompts, tool results, API requests
export OTEL_EXPORTER_OTLP_PROTOCOL=grpc
export OTEL_EXPORTER_OTLP_ENDPOINT=http://collector.example.com:4317
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer your-token"
Enter fullscreen mode Exit fullscreen mode

The metrics that matter for usage tracking:

Metric What it counts
claude_code.session.count CLI sessions started
claude_code.cost.usage Session cost in USD
claude_code.token.usage Tokens, by type: input, output, cacheRead, cacheCreation
claude_code.lines_of_code.count Lines added or removed
claude_code.commit.count Git commits created
claude_code.pull_request.count Pull requests created
claude_code.code_edit_tool.decision Accept and reject decisions for edits
claude_code.active_time.total Active time, by type: user or cli

Every metric carries user.email (when available), user.account_uuid, organization.id, and session.id. Add team and cost-center labels with resource attributes (no spaces in values):

export OTEL_RESOURCE_ATTRIBUTES="department=engineering,team.id=platform,cost_center=eng-123"
Enter fullscreen mode Exit fullscreen mode

Roll it out with managed settings

Developers forget environment variables. Push the configuration to every machine through the managed settings file instead. When managed settings set an OTLP endpoint, protocol, or credential, Claude Code removes conflicting developer-set variables at startup, and repository .claude/settings.json files cannot enable telemetry or redirect it:

{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "otlp",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "grpc",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "http://collector.example.com:4317",
    "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer example-token"
  }
}
Enter fullscreen mode Exit fullscreen mode

Prompt content in the claude_code.user_prompt event is redacted unless you set OTEL_LOG_USER_PROMPTS=1. Leave it off unless your policy allows storing prompts.

Query it in Prometheus

The exact Prometheus metric names depend on how your collector translates OTLP names and units, so run curl -s <your-prometheus-exporter>/metrics | grep claude_code before writing queries. With a common translation, cost per developer per day looks like this:

# Cost per developer over the last day (adjust the metric and label names to your exporter)
sum by (user_email) (increase(claude_code_cost_usage_USD_total[1d]))

# Tokens by type per team
sum by (team_id, type) (increase(claude_code_token_usage_tokens_total[1d]))
Enter fullscreen mode Exit fullscreen mode

Option 4: Route Claude Code through an LLM gateway

A gateway sits between Claude Code and the provider. Every request is logged with the developer's key, model, tokens, cost, and latency, and the same key carries budgets and rate limits. OpenTelemetry tells you what happened; a gateway can also stop it from happening.

With Bifrost, an open-source AI gateway, each developer gets a virtual key whose metadata (owner, team, cost center) is copied onto every log entry and cannot be overridden by the caller:

curl -s -u "$BF_ADMIN:$BF_PASS" -X POST https://bifrost.internal.example.com/api/governance/virtual-keys \
  -H "Content-Type: application/json" \
  -d '{
    "name": "dev-alice",
    "team_id": "<platform-team-id>",
    "metadata": {"owner": "alice@example.com", "team": "platform", "cost_center": "cc-1234"},
    "provider_configs": [{"provider": "anthropic", "allowed_models": ["claude-sonnet-4-6"], "key_ids": ["*"], "weight": 1.0}],
    "budgets": [{"max_limit": 20.00, "reset_duration": "1d"}, {"max_limit": 300.00, "reset_duration": "1M"}],
    "is_active": true
  }'
Enter fullscreen mode Exit fullscreen mode

Point Claude Code at it in ~/.claude/settings.json:

{
  "env": {
    "ANTHROPIC_BASE_URL": "https://bifrost.internal.example.com/anthropic",
    "ANTHROPIC_AUTH_TOKEN": "sk-bf-your-virtual-key"
  }
}
Enter fullscreen mode Exit fullscreen mode

If developers keep their Claude subscription login, send the virtual key as a header instead, so the gateway still logs and budgets their traffic: "ANTHROPIC_CUSTOM_HEADERS": "x-bf-vk: sk-bf-your-virtual-key", without setting ANTHROPIC_AUTH_TOKEN.

Then query spend by person or cost center from the log API, or from Prometheus:

curl -s -u "$BF_ADMIN:$BF_PASS" "https://bifrost.internal.example.com/api/logs?metadata_cost_center=cc-1234" | jq '.'
Enter fullscreen mode Exit fullscreen mode
sum by (virtual_key_name) (increase(bifrost_cost_total[1d]))
sum by (team_name) (increase(bifrost_cost_total[7d]))
Enter fullscreen mode Exit fullscreen mode

Track usage per project, not only per person

Per-person numbers answer "who"; finance and engineering leads also ask "which repository" and "which pipeline." Two ways to add that dimension:

How a gateway attributes Claude Code spend to people and repositories through key metadata and headers

Per-request headers through the gateway. Bifrost reads x-bf-dim-<name> headers and passes the value to logs, OpenTelemetry spans, and Prometheus labels. Claude Code can send custom headers, so set a repository dimension in that repository's settings (a header with no secret in it is safe to commit):

{
  "env": {
    "ANTHROPIC_CUSTOM_HEADERS": "x-bf-dim-repo: payments-api"
  }
}
Enter fullscreen mode Exit fullscreen mode

If you already use ANTHROPIC_CUSTOM_HEADERS for the x-bf-vk header, put both headers in the same value on separate lines, because a project-level value replaces the user-level one.

Separate keys for CI. Give every pipeline its own virtual key with metadata naming the repo and workflow, a small daily budget, and an expires_at for one-off jobs. CI spend then never mixes with interactive use.

The weekly report worth sending

Raw dashboards get ignored. A short weekly summary per team, built from gateway logs or OpenTelemetry plus your VCS, gets read:

  • Adoption: active developers per week, sessions per developer, and the share of developers above a minimal-use threshold.
  • Spend: cost per active developer per week and the top 10 spenders. A top spender is usually a misconfigured loop or the wrong default model, not a power user.
  • Model mix: share of requests per model. Push routine work to cheaper models with agent aliases.
  • Value: PR cycle time, review rework, and revert rate for agent-assisted PRs against your pre-rollout baseline. Tag agent-assisted PRs with a commit trailer or label so you can join them.
  • Friction: budget rejections and model-not-allowed errors. Rising counts mean limits or allowlists need adjusting.

Review per-developer budgets after the first two weeks and set them around the 90th percentile of observed daily spend.

Install the skills behind this post

ai-coding-agent-governance

ai-coding-agent-governance sets up per-developer keys, budgets, managed settings, CI keys, and adoption metrics for Claude Code, Codex CLI, Gemini CLI, Cursor, GitHub Copilot, and OpenCode.

npx skills add build-with-ai-hq/ai-coding-agent-governance
Enter fullscreen mode Exit fullscreen mode

llm-observability-stack

llm-observability-stack builds the dashboards and alerts: cost per user and feature, TTFT, error classification, and agent traces with OpenTelemetry GenAI conventions.

npx skills add build-with-ai-hq/llm-observability-stack
Enter fullscreen mode Exit fullscreen mode

Ask your agent "how do we see Claude Code usage per developer and per team?" and it starts with an audit of raw provider keys, agent configs, and managed policy on the machine, then writes the configuration for the path you choose.

Related reading

FAQ

Can I see Claude Code usage per developer on a Team plan?

Yes. The spend report in org analytics lists token usage and estimated spend per user and per model, with CSV export. The analytics dashboard shows active users and sessions.

Does Claude Code send usage data to Anthropic when I use Bedrock or Vertex?

No metrics from your cloud usage go back to Anthropic, so Anthropic's analytics do not cover it. Use OpenTelemetry export or a gateway for per-developer numbers.

Is OpenTelemetry export on by default?

No. Set CLAUDE_CODE_ENABLE_TELEMETRY=1 and choose an exporter. Use managed settings to enforce it across machines.

Can I track Claude Code usage per repository?

Yes. Send a repository dimension header through a gateway (for example x-bf-dim-repo with Bifrost), or give each CI pipeline its own key with repository metadata.

How do I make reported costs match our contract price?

Set the modelPricing managed setting to your contracted per-token rates. It changes what Claude Code reports in /usage, the status line, and OpenTelemetry, not what you are charged.

Top comments (0)