steipete/CodexBar

Feature: Claude usage source via minimal inference call reading anthropic-ratelimit-unified-* headers (multi-account with setup-tokens / user:inference)

Open

#1,894 opened on Jul 4, 2026

View on GitHub
 (3 comments) (3 reactions) (0 assignees)Swift (945 forks)batch import
P3clawsweeper:fix-shape-clearclawsweeper:needs-maintainer-reviewclawsweeper:needs-product-decisionclawsweeper:no-new-fix-prhelp wantedimpact:auth-providerissue-rating: 🌊 off-meta tidepool

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 scope user:profile. setup-tokens are user:inference only → 403 (measured). A full /login token has user:profile, but its refresh token rotates and doesn't stay valid — which is exactly why these users switched to setup-tokens.
  • Web (cookies): a sessionKey is 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/usage with the same token returns 403 (user:profile required) — the dedicated usage endpoint is unavailable, but the headers carry the equivalent 5h/weekly data.
  • POST /v1/messages/count_tokens does 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) window
  • unified-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 model id 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.

Contributor guide