Your "session window" is seven clocks, each with its own countdown.
One call to /api/organizations/{org}/usage returns seven separate Window objects. Each one has its own utilization and its own resets_at. A monitor that shows one bar is hiding six of them. ClaudeMeter surfaces all seven directly, polls every 60 seconds, and uses your existing browser session so you never paste a sessionKey.
The struct that makes "the session window" a misnomer
Open the source. The Rust struct that deserializes the server's /usage response has eight fields: seven of them are Option<Window> for the seven concurrent rolling buckets, plus one extra_usage for the metered overflow. There is no "session" field. There is no aggregate. There is no implicit "the" window. Whatever your monitor calls "the session" is a presentational choice on top of seven clocks the server is keeping independently.
The shape is small enough to fit on screen. That is also the ceiling: there is no other field on this endpoint that contains a token count, a dollar amount, or a remaining budget. Seven fractions and seven timestamps is the entire contract.
Anchor fact: 0 Window fields, each with its own resets_at
On a busy account it is normal to see five different reset timestamps simultaneously. The five-hour bucket might recycle this evening; seven_day_opus could reset four days later; the cowork bucket on a third day. Reading just one of these and calling it "your session" is how a tool tells you you have time left when the binding clock is two minutes from tripping.
What the seven windows actually do
Each one is a rolling bucket the server applies a separate utilization fraction to. A 429 fires when any one of them reaches 1.0, not when their sum does.
five_hour
The classic rolling 5-hour bucket. resets_at is set to the moment your oldest message in this window will age out, not 5 hours from a fixed start. This is the badge number.
seven_day
The catch-all weekly bucket on Pro and Max. Aggregates all chargeable traffic regardless of model. Independent resets_at; rolls forward continuously.
seven_day_sonnet
Per-model 7-day window for Sonnet traffic. Counted separately so a Sonnet-heavy week cannot eat the Opus quota.
seven_day_opus
Per-model 7-day window for Opus. On Max plans this is the bucket most users hit first; the 5-hour bar can look fine while this one is at 95 percent.
seven_day_oauth_apps
Charged traffic from third-party OAuth apps that connected to your Claude account. Invisible to JSONL counters because the bytes never touched your filesystem.
seven_day_omelette + seven_day_cowork
Two more server-internal buckets that ship over the same wire. Names are server-defined; we deserialize them as Option<Window> so the parse fails loudly if Anthropic renames a field.
The single line that removes the cookie-paste step
Most usage monitors require you to grab your sessionKey cookie out of DevTools and paste it into a config file or a UI field. ClaudeMeter does not, because the extension makes a credentialed fetch that the browser fills in automatically. The whole mechanism is credentials: "include" on a fetch that points at https://claude.ai, inside an extension that has host_permissions for that origin.
The piece that unlocks the flow is in the manifest. Without host_permissions for https://claude.ai/*, Chrome strips your cookies on the cross-origin fetch and the endpoint returns 401. With it, your session rides through unchanged and the response comes back identical to what the settings tab gets.
One poll, seven clocks, two surfaces
Where a single poll's data lands
The only public host is claude.ai. The bridge is loopback. Nothing else has a hand in the data path.
The shape of one snapshot in flight
Cookie in, seven clocks out
One credentialed fetch. Seven fractions, each with its own clock. The badge picks the worst five_hour across orgs and color-codes it; the menu bar exposes every clock individually.
Reproduce the seven-clock shape with one curl
You do not need to install anything to confirm what the server returns. Grab your session cookie out of DevTools, set $COOKIE and $ORG, and call the endpoint. The first jq just lists the keys. The second projects each window's utilization alongside its individual resets_at so you can see how spread the reset moments are.
Session window monitors compared
Reading 'session window' as one bar is a UI choice, not a server fact. The server tracks seven concurrent windows; here is what each common monitor does with that information.
| Feature | Local-log monitors and sessionKey-paste tools | ClaudeMeter (browser extension + menu bar) |
|---|---|---|
| Surfaces all 7 windows with separate resets_at | No. Most show one bar, sometimes two. | Yes. UsageResponse has 7 Window fields; CLI prints each. |
| Reads the percent claude.ai/settings/usage actually renders | Partial. JSONL counters compute their own percent. | Yes. Calls /api/organizations/{org}/usage directly. |
| Requires manual sessionKey or cookie paste | Often yes (sessionWatcher, several CLI tools). | No. credentials: 'include' rides existing browser auth. |
| Polls automatically as the window slides | Varies; many are launch-and-wait. | Yes. POLL_MINUTES = 1, fixed 60-second cadence. |
| Counts OAuth-app and cowork traffic toward the bar | No. Local logs cannot see traffic from other clients. | Yes. seven_day_oauth_apps and seven_day_cowork are first-class. |
| Aggregates across orgs on a multi-org account | No. | Yes. Iterates /api/account.memberships and dedupes by email. |
| Free, MIT, no telemetry, no third-party host | Mixed. | Yes. Only network call is to claude.ai itself. |
What a snapshot looks like as it streams
Real values from a normal afternoon, one chip per window. Each chip carries the bucket name, current utilization, and the day or hour its rolling window is set to recycle.
Five steps from zero to a live seven-clock badge
Install the menu-bar app.
brew install --cask m13v/tap/claude-meter drops ClaudeMeter.app into /Applications and the claude-meter CLI next to it. Launch the app and a tray icon appears. With no extension yet, it shows '!' until a data source connects.
Load the unpacked extension in your browser.
Clone the repo, open chrome://extensions (or arc://extensions, brave://extensions, edge://extensions), turn on Developer mode, click 'Load unpacked' and pick the extension/ folder. Pin the icon. The extension immediately calls /api/account, then /usage for every org you belong to.
Watch the badge populate.
Within 60 seconds the toolbar icon shows your worst five_hour percent and color-codes itself. Hover for a tooltip with 5h and 7d numbers. Click for the popup with the full breakdown of all seven Window fields.
Open the menu-bar app for the seven-clock view.
The bridge on 127.0.0.1:63762 receives the snapshot the extension pushed. The menu bar shows each window's utilization next to its individual resets_at, sorted with the most-pressing clock first.
Pipe the same snapshot to your terminal when you need it scripted.
/Applications/ClaudeMeter.app/Contents/MacOS/claude-meter --json prints the full snapshot, suitable for jq, suitable for a shell prompt, suitable for a status line. Same data the badge is built from.
What this monitor cannot do
macOS only for the menu-bar app; the extension itself runs on any Chromium browser, but the bridge it pushes to is a Mac binary. Safari is not supported (it stores cookies in a binarycookies file that needs Full Disk Access). The endpoint is undocumented; Anthropic can rename a field at any time, and when they do, the serde parse fails loudly and the badge shows !. Session cookies expire; when yours does, log back in to claude.ai and the next poll resumes. The numbers come from Anthropic's server; if Anthropic changes the bucket weights (they did on 2026-03-26), every monitor that reads /usage will shift simultaneously, including this one.
Watch all seven clocks instead of one
ClaudeMeter is free, MIT, and reads exactly what the settings page renders. Install the menu-bar app and the browser extension, and every bucket's utilization shows up next to its own reset timestamp, refreshed every 60 seconds, with no sessionKey to paste anywhere.
Need a custom session-window monitor for your team?
Bring a sample /usage response from your org and we will help you wire up the seven-clock view in your dashboard.
Frequently asked questions
Is the Claude session window the same as the 5-hour window?
No. The 5-hour window is one of seven rolling windows the server tracks per account. The full UsageResponse struct in src/models.rs lines 19-28 has seven Window-typed fields: five_hour, seven_day, seven_day_sonnet, seven_day_opus, seven_day_oauth_apps, seven_day_omelette, and seven_day_cowork. Each one carries its own utilization fraction and its own resets_at timestamp. When people say 'session window' they usually mean five_hour, but a 429 can fire because any of the other six tripped first. A monitor that only shows the 5-hour bar is hiding six clocks that can throttle you.
Do all seven windows reset at the same time?
No, that is the whole point of a rolling window. Each Window object ships its own resets_at value, computed independently as the moment the oldest still-counted message in that bucket ages out. five_hour can reset at 18:42 while seven_day_opus resets four days later. ClaudeMeter prints each timestamp separately in src/format.rs lines 75-98, so you can see which clock will tick over first. A 'session ends in 5 hours' countdown is a fiction unless it tells you which bucket it is counting.
How does claude-meter avoid making me paste a sessionKey?
The browser extension in extension/background.js line 6 calls fetch with credentials: 'include'. That tells the browser to attach your already-authenticated claude.ai cookies on a same-origin-style request from inside the extension. There is no copy of the cookie in any config file, in any localStorage entry, or in any environment variable. The host_permissions entry in manifest.json line 8 is what unlocks that flow ('https://claude.ai/*'). Tools that ask you to paste a sessionKey are doing so because they cannot piggyback on browser auth from the context they run in.
Why does the menu-bar binary read Chrome Safe Storage?
Because if you install the binary without the extension (Route B in the README), it has no in-browser context to ride on. So it falls back to reading the cookie database directly: it shells out to security find-generic-password to get the AES key macOS holds for 'Chrome Safe Storage', decrypts the cookies file for the profile that has a claude.ai login, and uses that cookie to call the same /usage endpoint. The extension route (Route A) skips that entire path and is the recommended install in the README.
How often does the monitor poll, and why that interval?
Every 60 seconds. POLL_MINUTES is set to 1 on line 3 of extension/background.js, and the alarm is registered with periodInMinutes: POLL_MINUTES on line 105. The cadence is chosen because rolling utilization slides as old traffic ages out, even when you stop sending messages. A sample from 30 minutes ago is usually wrong by a few percentage points, and at 95 percent utilization that gap matters. The Rust binary samples on demand whenever it is invoked, so the CLI gives you a one-shot snapshot synchronized to the moment you ran it.
What does the badge text mean?
The two-digit number on the toolbar icon is the worst current five_hour utilization across every org membership on your account, rounded to an integer. The logic is in extension/background.js lines 82-84: it walks every snapshot, takes the max of five_hour utilization, and renders that. The color comes from lines 86-88: green under 80 percent (#2c6e2f), amber 80 to 100 (#b26a00), red at 100+ (#b00020). If the fetch fails entirely the badge shows '!' instead of a number, which is a fast visual cue to re-login in claude.ai.
What if I am on multiple orgs on the same Claude account?
Both routes iterate. The extension calls /api/account first, walks account.memberships, and polls /usage for each org.uuid (extension/background.js lines 16-22). The CLI does the same in main.rs lines 17-30, deduping by account email at the end with dedupe_by_account so you do not see the same org twice if it appears under more than one cookie session. A monitor that only shows one number will under-report when one org is at 95 percent and another is at 30 percent.
Can I see which window will trip first without doing math myself?
The CLI prints them in the order the struct declares them, with each window's resets_at rendered as 'in Xd Yh' relative to now (src/format.rs lines 75-98). Eyeballing the column tells you which bar is tallest. The menu-bar UI sorts by utilization descending so the worst clock is at the top, and the badge always shows the worst five_hour value because the 5-hour window is the most common 429 source on Pro plans. For Max plans, seven_day_opus is often the binding constraint and shows up immediately below.
Does this work for the API plan, or only consumer plans?
Only consumer plans (Pro and Max). The /api/organizations/{uuid}/usage endpoint is what claude.ai/settings/usage renders from, which is the consumer billing surface. The Console API plan ships its own Usage and Cost API on platform.claude.com, which returns dollars and tokens broken down by workspace and model. Different host, different shape, different semantics. ClaudeMeter targets the consumer surface because the consumer surface is the one with private rolling windows that nothing else surfaces.
What does 'seven_day_omelette' mean?
It is a server-side internal name for one of the metered buckets (the curiosity is real, the field is real). The struct in src/models.rs deserializes it as Option<Window> like the other six, so it is decoded into the same shape and rendered the same way. We do not redefine or rename server fields because the day Anthropic ships a new bucket we want serde to either accept it transparently or fail loudly, not silently mistranslate. If you see a value here climbing while others stay flat, it is real traffic against a real server-side bucket.
How is this different from reading the JSONL transcripts on disk?
Local JSONL files have token counts; they do not have utilization. To convert tokens into a percentage you would need the denominator the server divides by, and that denominator is private (and changes on server-side deploys; it changed on 2026-03-26). Local-log monitors are accurate about what your machine sent, but they cannot match what claude.ai/settings/usage shows because they have to invent the ceiling. ClaudeMeter reads the percent the server already computed, which is the same byte-for-byte value the settings page displays.
Does anything leave my machine besides the call to claude.ai itself?
No. There is no telemetry, no analytics, no third-party host. The only network egress is the GETs to claude.ai (which you are already calling when you use the product). The bridge between the extension and the menu-bar app binds to 127.0.0.1:63762 explicitly (BRIDGE constant in extension/background.js line 2), which is loopback only. The whole project is MIT-licensed; the source you can audit lives at github.com/m13v/claude-meter.
Keep reading
Server quota is a fraction with a private denominator
Why local-log token counters cannot equal what claude.ai/settings/usage renders, and the field you should read instead.
Burn rate against a rolling window, not a calendar window
How utilization drifts minute-to-minute and why a sample from 30 minutes ago is usually wrong.
Open-source Claude usage trackers, compared (April 2026)
What every monitor on the market reads, what they miss, and which one matches the settings page byte for byte.