Deadline: June 15, 2026

A programmatic Claude usage tracker before June 15, written in one CLI command against an endpoint Anthropic does not document.

Sonnet 4 and Opus 4 retire on June 15, 2026. Every pipeline pinned toclaude-sonnet-4-20250514orclaude-opus-4-20250514breaks that day. The migration itself is a one-line model-string change. The harder part: knowing whether the new model burns your plan window faster than the old one did. Anthropic’s official Usage & Cost API does not see the Pro / Max plan windows.claude-meter --jsondoes, and it reads them with the OAuth Bearer token Claude Code already put in your keychain.

M
Matthew Diakonov
7 min read

Direct answer (verified 2026-05-14)

For consumer Pro and Max plans, the programmatic tracker is claude-meter --json, which calls GET api.anthropic.com/api/oauth/usage with the OAuth Bearer token Claude Code stores in macOS Keychain under service Claude Code-credentials. That endpoint returns the same eight-float UsageResponse the claude.ai settings page renders. Anthropic’s official Usage & Cost Admin API (docs) only reports API-key (sk-ant-...) spend; consumer Pro / Max plan rolling-window utilization is not on that surface. June 15, 2026 is the Sonnet 4 / Opus 4 deprecation date (official deprecations page), which is why a working tracker matters before then: the new models weight against your plan window differently and any baseline measured pre-migration is stale.

Two usage APIs, only one of them sees Pro / Max plans

Anthropic ships a real, documented, programmatic usage API. It is the right tool for the wrong job. Side by side:

FeatureAnthropic Admin Usage & Cost APIapi.anthropic.com /api/oauth/usage (used by claude-meter)
EndpointPOST /v1/organizations/usage_report/messagesGET api.anthropic.com/api/oauth/usage
AuthAdmin API key (sk-ant-admin-), org admin role requiredOAuth Bearer (sk-ant-oat01-) from Claude Code keychain, scope user:profile
What it reportsAPI-key (sk-ant-...) per-message tokens and USD costPro / Max plan rolling 5-hour and 7-day windows + extra_usage
Sees Claude Code on a Max subscriptionNo (Pro / Max is not API-key billed)Yes (the same token Claude Code itself uses)
Sees raw API traffic billed to a console workspaceYes, with workspace + service-tier breakdownsNo
Available to individual Pro / Max subscribersNo (Admin API key requires org admin)Yes
DocumentedYes (platform.claude.com/docs)No (undocumented; same endpoint Claude Code's --usage uses)
Best forCost attribution across an org's API workspacesTracking how close you are to a 429 inside a Claude Code loop

If your usage runs through Claude Code on a Max subscription, the official Admin API will report zero traffic for it. The metering surface for Pro and Max is a different endpoint, on a different auth, with a different shape. The deprecation deadline does not change that; it just makes the gap more visible because the gap is exactly where your migration risk sits.

The four steps that get you a scriptable plan-usage feed

This is the whole flow. None of it is more than a couple of shell commands; the longest step is waiting a week for a re-baseline.

1

1. Confirm Claude Code has a current OAuth token

security find-generic-password -s 'Claude Code-credentials' -w prints the JSON blob. Look for accessToken starting with sk-ant-oat01- and an expiresAt epoch in the future. If expired, run claude once and the CLI refreshes it back into the same keychain entry.

2

2. Install the wrapper or run the curl yourself

brew install --cask m13v/tap/claude-meter gives you a CLI that handles token-expiry, multi-account dedupe, and emits the parsed UsageSnapshot. If you want zero install, the curl block in the next section is the equivalent for the active Claude Code account only.

3

3. Pipe --json into whatever script you already have

Cron a Slack notifier on five_hour.utilization > 85, post to Alertmanager when extra_usage.utilization > 80, render seven_day_opus into your Starship prompt while you migrate model strings off the 20250514 IDs. The shape is stable across releases.

4

4. Re-baseline after each model migration

Switching one pipeline from claude-sonnet-4-20250514 to claude-sonnet-4-6 shifts the seven_day_sonnet float because the per-token weighting changes. Save a week of pre and post snapshots so you can see whether the new model burns the bucket faster or slower for your workload, before June 15 forces the migration on everyone else's traffic too.

The endpoint claude-meter actually calls

Two GETs, one OAuth Bearer, no Cloudflare. The cleanest source for the active Claude Code account, and the only path that does not require touching a browser cookie. Source from claude-meter/src/oauth.rs:

claude-meter/src/oauth.rs

The keychain entry that makes this work is the same one the running Claude Code CLI writes when you log in. Its shape, with the field names that matter:

security find-generic-password -s 'Claude Code-credentials' -w

The token rotates on its own. Claude Code holds the refresh token and the right OAuth client credentials and writes the new accessToken back into the same keychain entry. claude-meter just reads whatever is there. If the token expired and Claude Code is not running to refresh it, claude-meter falls back to the browser-cookie path that the menu bar also uses.

What the JSON looks like

A single snapshot. The shape is stable across releases; new fields are added, old fields are not removed silently. About 1.5 KB on a normal day:

claude-meter --json

Eight utilization floats, each in 0..100. The first four (five_hour, seven_day, seven_day_sonnet, seven_day_opus) are the ones the Settings page renders. The next three are weekly buckets for OAuth-app traffic, the “omelette” bucket, and the Cowork bucket; they exist on the wire even if the Settings UI does not show them. The extra_usage block is the metered-billing balance Anthropic shipped in April 2026; utilization here is dollar-based rather than token-based.

Use it from a script

Three jq one-liners that are good enough to paste into a Slack notifier, a Starship segment, or a tmux right-status:

claude-meter --json | jq

Or skip the install entirely

If you want to see the JSON without touching a brew tap, the curl equivalent is two commands. It only sees the account Claude Code is logged into; the wrapper is for multi-account dedupe and a menu bar surface, not for the call itself:

curl /api/oauth/usage with Claude Code's keychain Bearer

The anthropic-version header is required; 2023-06-01 is the only value that has worked across this endpoint’s history. No Referer header is needed for the OAuth route (unlike the claude.ai cookie route, which 403s without a settings/usage Referer).

Why the deadline matters more than the model swap

The June 15 migration itself is a one-line change. Replaceclaude-sonnet-4-20250514withclaude-sonnet-4-6(orclaude-opus-4-7for the Opus side) and your inference layer keeps working. What you do not get told is what the swap does to your seven_day_sonnet and seven_day_opus buckets. Per-token plan weighting can shift across model versions and the public docs do not publish the weights. A week of snapshots captured before the swap and a week after is the only way to see whether you should expect to hit the rolling 5-hour wall earlier or later post-migration.

Capture cadence: one snapshot per minute is enough to spot a window tipping over within the same poll interval the menu bar uses. If you are running an agentic Claude Code loop, that resolution is fine; if you are running batch jobs, every five minutes is plenty. The endpoint does not rate-limit at this cadence on a normal Pro or Max session.

Hit a wall mid-migration?

Half-hour call to walk through the OAuth endpoint, the curl, and what the snapshot drift looks like in your specific workload before June 15.

FAQ

Frequently asked questions

Why is June 15 the deadline I keep seeing?

Anthropic retires the original Claude Sonnet 4 (claude-sonnet-4-20250514) and Claude Opus 4 (claude-opus-4-20250514) on June 15, 2026. After that date, requests to those model IDs return errors. The replacements are Sonnet 4.5 / 4.6 and Opus 4.5 / 4.7. The official deprecation page is at platform.claude.com/docs/en/about-claude/model-deprecations. If you have any pipeline still pinned to the 20250514 model strings, this is the calendar date it stops working.

Why does the migration matter for usage tracking specifically?

Two reasons. First, the new models are weighted differently against the rolling 5-hour and weekly windows; an Opus 4.7 turn does not consume the same fraction of plan as an Opus 4 turn did. Anything you measured pre-migration is a stale baseline. Second, anyone running model-pinned scripts on a Pro or Max subscription needs a way to see the new burn rate from a script, not just from a settings page. That is the case the consumer plan never had a real answer for, and where the OAuth endpoint comes in.

Doesn't Anthropic already publish a programmatic Usage & Cost API?

Yes, two of them: the Usage & Cost Admin API at /v1/organizations/usage_report/messages and the Enterprise Analytics API. Both authenticate with an Admin API key (sk-ant-admin...), both report per-message token consumption and dollar cost for API-key traffic. Neither one exposes the consumer Pro / Max plan's 5-hour and 7-day windows. Those are a separate enforcement surface. If your usage runs through Claude Code, claude.ai chat, or anything else billed against a Pro / Max subscription rather than an API key, the official Usage & Cost API will not see your traffic.

Where do consumer plan windows actually live then?

On two undocumented endpoints. claude.ai/settings/usage renders from GET /api/organizations/{org_uuid}/usage with your browser session cookie. The same shape is reachable on api.anthropic.com via GET /api/oauth/usage with the OAuth Bearer token Claude Code already stashed in your macOS Keychain under service "Claude Code-credentials". Both routes return the same eight-float UsageResponse: five_hour, seven_day, seven_day_sonnet, seven_day_opus, seven_day_oauth_apps, seven_day_omelette, seven_day_cowork, plus an extra_usage block for the metered overage balance.

What does claude-meter --json actually emit?

A JSON array of UsageSnapshot objects. Each snapshot has org_uuid, browser, account_email, fetched_at, and the parsed usage / overage / subscription blocks. The shape is defined in src/models.rs lines 60-73. A typical day's array is about 1.5 KB, easy to pipe into Slack, a Starship segment, a tmux status line, an Alertmanager rule, or whatever else you script against. There is no API key to manage; the tool reads Claude Code's existing OAuth credentials and, if those are missing or expired, falls back to your already-logged-in browser cookies.

Is calling api.anthropic.com/api/oauth/usage allowed?

It is the same endpoint the running Claude Code CLI calls every time it refreshes its own usage cache. The Bearer token is the one Claude Code minted for you when you logged in (scope user:profile is enough). claude-meter does not refresh the token (Claude Code does that automatically with its refresh token); it just reads what is already in the keychain. The cadence is one request per minute, well under what an open Claude Code session generates. The endpoint is undocumented, which means Anthropic can rename a field and break the parse; not that they prohibit reading it.

Can I do this without installing anything?

Yes. Read the keychain entry, pull the accessToken field, and curl the endpoint yourself: security find-generic-password -s 'Claude Code-credentials' -w | jq -r .claudeAiOauth.accessToken | xargs -I {} curl -s https://api.anthropic.com/api/oauth/usage -H 'Authorization: Bearer {}' -H 'anthropic-version: 2023-06-01'. You get the same JSON. claude-meter just wraps that with token-expiry handling, multi-account dedupe, an optional menu bar surface, and a polished --json shape.

What if I am not on macOS?

Today, claude-meter is macOS only because the keychain reader is /usr/bin/security and the cookie fallback understands Chromium's Safe Storage on macOS. The OAuth endpoint itself is not platform-specific, so the same curl pattern works on Linux or Windows if you can locate Claude Code's stored credentials on your platform (Claude Code uses the OS keychain on each: libsecret on Linux, Credential Manager on Windows). The lugia19/Claude-Usage-Extension Chrome extension is the cross-platform option that reads the cookie path instead.

Should I run this alongside ccusage?

Yes. They answer different questions. ccusage walks ~/.claude/projects/*.jsonl and totals the tokens your local Claude Code CLI sent to Anthropic. claude-meter reads the server's plan-side utilization. ccusage tells you what your machine spent in tokens; claude-meter tells you what fraction of plan ceiling Anthropic counted that against. Local-token sums and server utilization can drift by 30-40 points and both still be correct readings of what they measure. Run both. They poll different sources.

Will this break on June 16?

No. The model deprecation removes the old model identifiers from the inference API; it does not touch the usage endpoint or the OAuth scope. claude-meter keeps reading the same JSON; the only thing that changes is the Sonnet / Opus weekly buckets start filling at the 4.5 / 4.6 / 4.7 burn rate instead of the 4.0 burn rate. The breakage to plan for is at the inference layer of any pinned-model script you run, not at the metering layer.

How did this page land for you?

React to reveal totals

Comments ()

Leave a comment to see what others are saying.

Public and anonymous. No signup.