Claude Code's statusLineHook: read rate limits locally without any API calls

patwalls1 pts0 comments

How Claude Code's status line hook works — and how to use it

How Claude Code's status line hook works — and how to use it

Claude Code tracks your 5-hour session and 7-day weekly rate limits internally, and it exposes those numbers via its own /usage command. But there's a lesser-known mechanism — statusLineHook — that lets you capture that data automatically without polling an API or running a command. Here's how it works.

The hook configuration

Claude Code reads ~/.claude/settings.json on startup. One of its config keys is statusLineHook — a shell command string that Claude Code runs every time it updates its status line. The usage data is passed as an environment variable: HOOK_STATUS_LINE.

The value of HOOK_STATUS_LINE is a JSON string with rate-limit and session information. A typical value looks like:

"sessionUsagePct": 12.4,<br>"weeklyUsagePct": 67.1,<br>"contextUsagePct": 8.2,<br>"model": "claude-sonnet-4-6",<br>"costUSD": 1.24,<br>"sessionResetAt": "2026-06-11T18:42:00Z",<br>"weeklyResetAt": "2026-06-14T00:00:00Z"

These are the same numbers Claude Code renders when you run /usage — straight from its internal rate-limit state, updated in real time as each prompt is processed.

Wiring up a hook

To capture this data, add a statusLineHook to ~/.claude/settings.json. The simplest possible hook writes the JSON to a file:

"statusLineHook": "printf '%s' \"$HOOK_STATUS_LINE\" > ~/.claude/usage.json"

After saving and starting a new Claude Code session, the file ~/.claude/usage.json will be updated every time Claude Code processes a prompt. You can read it with:

cat ~/.claude/usage.json | jq .<br>jq '.sessionUsagePct' ~/.claude/usage.json # session %<br>jq '.weeklyUsagePct' ~/.claude/usage.json # weekly %

Why this is better than API polling

The typical approach to monitoring Claude Code usage is to call the Anthropic usage API. That requires an API key, makes network requests, and runs the risk of your monitoring tool contributing to its own rate limits.

The hook approach has none of these downsides:

Zero network calls — the data is local, written by Claude Code itself

No credentials — the hook runs in Claude Code's process; you don't need a token

Real-time — updated after every prompt, not on a poll interval

Privacy-preserving — the data never leaves your machine

You can verify there's no network activity from any hook-based tool with:

nettop -p Headroom # or whatever your tool is named

Chaining hooks

If you already have a statusLineHook configured, Claude Code respects it — the hook field is a string, so you'd need to chain commands with && or ;. Tools that install hooks responsibly should check for an existing hook first and append to it rather than overwriting.

Note for tool authors: Read the current settings.json before writing, and if a statusLineHook already exists, append your command with ; your-command rather than replacing the existing hook. Claude Code runs the hook as a shell command, so chaining with ; (or && if you want short-circuit behavior) works correctly.

What you can build

The hook mechanism unlocks a class of tools that were previously impractical because they required polling:

Ambient displays — menu bar widgets, terminal status lines, tmux statusbar segments

Threshold alerts — shell scripts that send a macOS notification at 80% session usage

Usage logging — append each update to a log file to build a session history

Workflow automation — trigger a context-window reset or save when the context fills up

Cost tracking — accumulate costUSD across sessions with a simple append-and-sum

A minimal tmux statusbar segment, for example:

# In .tmux.conf:<br>set -g status-right '#(jq -r '"'"'if .sessionUsagePct then "CC (.sessionUsagePct | round)%·(.weeklyUsagePct | round)%" else "" end'"'"' ~/.claude/usage.json 2>/dev/null)'

Headroom is a native macOS menu bar app built on exactly this mechanism.<br>It shows both meters at a glance — CC 12%·67% — color-coded as limits approach.<br>Free, MIT, zero config.

Download Headroom — free

brew install --cask patwalls/tap/headroom

The full JSON schema

Fields you can count on in HOOK_STATUS_LINE:

sessionUsagePct // float, 0–100, 5h session window<br>weeklyUsagePct // float, 0–100, 7d weekly window<br>contextUsagePct // float, 0–100, current context fill<br>model // string, active model name<br>costUSD // float, session cost if tracked by your plan<br>sessionResetAt // ISO 8601, when the 5h window resets<br>weeklyResetAt // ISO 8601, when the 7d window resets

Not all fields are present in every update — check for existence before using. costUSD may be 0 for plans that don't expose per-session cost.

Source and further reading

The Headroom app is open-source and shows a complete reference implementation of the hook + file-read approach: github.com/patwalls/headroom.

The relevant files are app/Sources/Headroom/Hook.swift (installs the hook) and app/Sources/Headroom/Usage.swift (reads and parses the JSON).

claude hook code usage json session

Related Articles