Skip to content

Persist anthropic-ratelimit-unified-5h-* response headers for hooks/statuslines #55333

Description

@Philamentous

Feature request: persist Anthropic rate-limit headers for hooks/statuslines

Repo: anthropics/claude-code
Type: Feature request

Title

Persist anthropic-ratelimit-unified-5h-* response headers per-session so hooks
and statuslines can read the live 5-hour usage without re-calling /usage.

Problem

Statusline hooks (and other tooling that runs on every prompt render) want to
display the same 5-hour-window usage that /usage and claude.ai show. Today
there is no way to do this from local files:

  • claude /usage is interactive-only; claude -p "/usage" prints the session
    summary, not the usage value.
  • Spawning claude per render is too slow and burns rate-limit budget against
    the very limit being monitored.
  • Transcript JSONLs (~/.claude/projects/<key>/<sid>.jsonl) record per-message
    usage.{input_tokens,output_tokens,cache_*} but none of the rate-limit
    reset/remaining headers.
  • Anthropic's API already returns anthropic-ratelimit-unified-5h-status,
    anthropic-ratelimit-unified-5h-remaining, anthropic-ratelimit-unified-5h-reset
    on every request — Claude Code receives them but doesn't persist them.

Users currently work around this by keeping a claude.ai tab open and
eyeballing the badge, or by writing brittle DOM-scraping userscripts that relay
the value to a local file (which is what I'm running today, but it shouldn't be
necessary).

Proposal

After each turn, append the latest rate-limit header values to a small
per-session file, e.g. ~/.claude/sessions/<sid>.usage.json:

{
  "updated_at": "2026-05-01T14:30:00Z",
  "unified_5h": {
    "status": "active",
    "remaining": 0.58,
    "reset": "2026-05-01T17:00:00Z"
  },
  "input_tokens_5h": { "remaining": 123456, "reset": "..." },
  "output_tokens_5h": { "remaining": 78901, "reset": "..." }
}

A symlink or sibling file at ~/.claude/usage-latest.json pointing at the most
recently written session would let statuslines read the latest value without
knowing the session id.

Alternatives considered

  1. Expose to statusline JSON input directly. Add a usage block alongside
    context_window in the data passed to statusline hooks. Cleanest API but
    limits visibility to statuslines only; other hooks (PreToolUse, etc.) and
    external tools still can't see it.
  2. Exit code or stdout from claude /usage. Make /usage work in --print
    mode and emit JSON. Useful but still costs an API call per poll.
  3. /usage as a no-API local read. Already implemented as headers exist —
    just persist them.

(1) and (3) are complementary; (3) is the foundation that (1) would consume.

Why this is a small change

Claude Code already parses these headers (it has to, in order to throttle
internally and to show /usage). The work is essentially:

  • After the existing post-request handler reads the headers, call
    fs.writeFileSync(sessionUsagePath, JSON.stringify(headers)).
  • (Optional) update ~/.claude/usage-latest.json symlink.

No new network behavior, no new permissions, no schema redesign.

Compatibility

Purely additive. Hooks that don't read the file see no change. The file lives
under the same ~/.claude/ directory tree that hooks already trust.


Filed by: Philamentous
CC version: 2.1.126

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions