Feature: Claude usage source via minimal inference call reading anthropic-ratelimit-unified-* headers (multi-account with setup-tokens / user:inference)
#1,894 opened on Jul 4, 2026
Repository metrics
- Stars
- (12,194 stars)
- PR merge metrics
- (Avg merge 1d 15h) (323 merged PRs in 30d)
Description
Summary
Add a Claude usage source that reads live 5h/weekly limits from the anthropic-ratelimit-unified-* response headers of a minimal POST /v1/messages call. This works with long-lived claude setup-token credentials (scope user:inference) and would enable multiple persistent Claude accounts in the menu bar without browser cookies — a concrete mechanism for #1756 / #1843 / #1268.
Problem
For people running several Claude subscription accounts via a multi-account switcher (e.g. claude-switch, which mints one ~1‑year claude setup-token per account), CodexBar currently has no clean way to show all of them live at once:
- OAuth API (
GET /api/oauth/usage) requires scopeuser:profile.setup-tokens areuser:inferenceonly → 403 (measured). A full/logintoken hasuser:profile, but its refresh token rotates and doesn't stay valid — which is exactly why these users switched to setup-tokens. - Web (cookies): a
sessionKeyis revoked on logout, so switching accounts in one browser kills the previously-harvested account's data. - CLI (PTY): single account.
Net result: no durable way to show N long-lived Claude accounts (cf. #1756, #1843, #1268; and token-loss reports like #1823).
Discovery (measured on CodexBar 0.37.2 / macOS)
A minimal inference call with a user:inference setup-token returns HTTP 200 and carries the same unified limits in the response headers:
POST https://api.anthropic.com/v1/messages
authorization: Bearer sk-ant-oat01-… # a `claude setup-token`, scope user:inference
anthropic-version: 2023-06-01
anthropic-beta: oauth-2025-04-20
content-type: application/json
{"model":"claude-haiku-4-5-20251001","max_tokens":1,"messages":[{"role":"user","content":"."}]}
Response headers:
anthropic-ratelimit-unified-5h-utilization: 0.01 # fraction 0..1
anthropic-ratelimit-unified-5h-reset: 1783180800 # unix seconds
anthropic-ratelimit-unified-7d-utilization: 0.63
anthropic-ratelimit-unified-7d-reset: 1783713600
anthropic-ratelimit-unified-5h-status: allowed
anthropic-ratelimit-unified-representative-claim: five_hour
Notes:
GET /api/oauth/usagewith the same token returns 403 (user:profilerequired) — the dedicated usage endpoint is unavailable, but the headers carry the equivalent 5h/weekly data.POST /v1/messages/count_tokensdoes not include these headers, so it must be a real (max_tokens:1) messages call. Cost ≈ 1 output token per poll.- Verified across 4 distinct subscription accounts, each via its own setup-token, all returning correct distinct utilization values.
Proposed feature
For a Claude tokenAccount whose token is an sk-ant-oat… with only user:inference (or as an automatic fallback when /api/oauth/usage returns 403), obtain quota by issuing one tiny inference call and mapping headers:
unified-5h-utilization/-reset→ session (5h) windowunified-7d-utilization/-reset→ weekly window
This lets tokenAccounts backed by setup-tokens show live per-account quota without browser cookies (no logout fragility) and without user:profile — i.e. genuine multi-account overview with durable ~1‑year tokens.
Why it's attractive
- A concrete, durable mechanism for the multi-account requests (#1756, #1843, #1268).
- Sidesteps sessionKey logout/expiry and OAuth-refresh fragility (#1823 and #1287-class issues).
- Minimal cost (~1 token per poll; can be gated behind a refresh interval and used only when OAuth/web are unavailable).
Caveats / open questions
- The
modelid must be a currently-available model → keep a small fallback list. - The headers are the subscription unified limits (utilization 0..1). Model-specific weekly (Sonnet/Opus) and the "Daily Routines" window may not be present in the headers — those would still require the usage endpoint / web source.
- Should be opt-in / gated so normal accounts keep using OAuth/web as today.
Happy to provide more header captures, and I can attempt a PR if this direction is welcome. Thanks for CodexBar — it's genuinely great.