Feature request: read-only usage scope on `claude setup-token` (or a usage:read grant) for subscription accounts
Problem. claude setup-token mints a long-lived token scoped user:inference. The usage endpoint that powers Claude Code's own /usage panel requires user:profile, so a setup-token gets 403 permission_error: "OAuth token does not meet scope requirement user:profile" (req_011CdMiznyqXPWoTj6WiQgQZ). Result: local monitoring tools (menu-bar dashboards, statuslines for a second machine profile, multi-account decks) can hold a token that may spend inference for a year but cannot read how much of the window is left — the inverted privilege order.
Ask. Either (a) let setup-token optionally include a narrow read-only usage grant (e.g. usage:read — window percentages + reset timestamps only, no profile/PII), or (b) offer a separate long-lived read-only usage token for subscription accounts. Explicitly NOT asking for user:profile on setup-tokens.
Why it's aligned. Statusline JSON already exposes exactly these fields to any user script (rate_limits.five_hour/seven_day) — the data is user-visible by design; only the out-of-session read path is missing. It would also drain the ecosystem swamp: today tools poll /api/oauth/usage with borrowed session credentials or scrape claude.ai cookies (#31637), precisely because no sanctioned read-only path exists. A scoped read token is the safety-improving alternative.
Related: #31637, #43149.
4 Comments
I think related: https://github.com/anthropics/claude-code/issues/79360
+1 — and a concrete hardware use case for exactly the grant described here.
I run a fork of Clawdmeter, a desk-side ESP32 device that displays Claude session/weekly utilisation. The upstream reads usage via a host daemon; my fork clawdmeter-wifi removes the host entirely — the device polls over Wi-Fi itself, which makes the long-lived setup-token the only practical credential: there's no browser for an OAuth flow and no host to run a refresh loop.
Because that token can't call
/api/oauth/usage, the device is left with the worst-of-both-worlds workaround: sending a 1-token/v1/messagesrequest every minute purely to read theanthropic-ratelimit-unified-*response headers. That wastes tokens on both sides, and the headers only expose the blended 5h/7d windows. Per-model weekly limits (e.g. Fable 5's separate allowance) are visible in /usage but unreachable from a device.Option (a) — a narrow usage:read grant on setup-token — would fit this class of project perfectly: read-only, no PII, no inference, so it sits entirely outside the abuse pattern that motivated the recent third-party-auth restrictions. Happy to be a test case.
Related: #80732 asks for host-side surfaces (CLI/statusline) for the same data; a usage:read token would give those tools a sanctioned backend too.
Caveat: d-mato says the rate limits on the
/api/oauth/usageAPI are severe - I don't understand why that would be the case when/v1/messagesgives up-to-date usage in the response headers on every turn, implying they're readily available. To make this change useful, Anthropic would also need to substantially reduce the rate limiting on the/api/oauth/usageendpoint — even once per minute should cost nothing given the headers already ship these figures on every turn, and at that cadence the bucket being shared with Claude Code's own /usage stops mattering.Agreed would be useful to have some way to access our usage data even if it is just for our own enjoyment of seeing the data
I have a project where I am using quite a hacky/janky way of getting the data for my hardware desktop gadget and it is eating away at my conscience making repeated "Hi" calls to Haiku to read the requests response headers...
https://github.com/HermannBjorgvin/Clawdmeter/
+1 — the inverted privilege order is exactly right: I hold a token that can spend inference for a year but can't read a percentage.
For flavor, here's the contraption this pushes me into. My desk usage meter is Clawdmeter by @HermannBjorgvin (an ESP32 that renders the window percentages over BLE), which free-rides the Claude Code session credentials, because that's the only thing that can read
/api/oauth/usage—and those credentials only stay fresh while Claude Code itself runs in the terminal (the Electron app token is not readable). So to keep the data live I run a launchd agent whose entire job is to launch Claude Code every 4 hours with a throwaway prompt:Claude Code wakes, finds its stored token, refreshes it as a side effect, and exits — one deliberately tiny haiku call per 4 hours as a token-keepalive tax, pinned to the cheapest model so the workaround itself barely touches the limits it exists to observe. It works, and it is absurd. A
usage:readgrant would delete the whole thing.