Claude CodeThe 8 fields the docs don't showPinned to the Fazm ACP bridge source

Claude Code extra usage, told through the 8-field event the SDK actually fires

Anthropic's support docs explain how to turn extra usage on. The pricing blogs quote hours-per-week allowances. Neither shows the telemetry Claude Code emits while you are consuming it. That telemetry is a `rate_limit_event` with 8 specific fields, and consuming it correctly is the difference between an agent that dies at 2am and one that keeps running with a warning. Fazm is a Mac app that runs Claude Code over ACP, so we had to wire all 8 fields into real UI state. The anchor fact below is the `RateLimitMessage` interface that carries them, lifted verbatim from our open-source bridge.

M
Matthew Diakonov
13 min read
4.9from 200+
Every claim pinned to a file and line in the open-source Fazm repo
Tested against the April 2026 top-10 SERP for 'claude code extra usage'
Anchor fact: the 8-field RateLimitMessage interface at protocol.ts:245
8 fields

The Claude Agent SDK fires a rate_limit_event with 8 fields. Fazm's ACP bridge declares them verbatim in the RateLimitMessage interface at acp-bridge/src/protocol.ts lines 245-256: status, resetsAt, rateLimitType, utilization, overageStatus, overageDisabledReason, isUsingOverage, surpassedThreshold. Every field is forwarded to Swift for UI rendering.

acp-bridge/src/protocol.ts, lines 245-256

What actually drains Claude Code extra usage

The thing that runs up your extra-usage bill is almost never "Claude was too chatty." It is a handful of repeatable patterns that each map to a specific token-per-request spike.

Long tool-call loopsNon-compacted context carry-overScreenshot-based agentsScheduled cron sessionsOpus on high-volume chatVision tokens on dense UIsMCP servers returning huge JSONHardcoded system prompts > 5k tokensUnpinned model fall-through

The 8 fields Claude Code emits while you spend extra usage

This is the telemetry that actually flows while Claude Code runs. The Agent SDK emits a `rate_limit_event` every few requests. Fazm forwards it untouched from the ACP subprocess into Swift so the Mac UI can render it. Here is the exact interface, copied from the open-source Fazm repo.

acp-bridge/src/protocol.ts, lines 244-256

None of these fields are invented. They are the raw SDK shape, the same event the `claude` CLI consumes internally. The difference is that a Mac app has to do something with them visually. Fazm's UI decides whether to render a warning banner, a fallback, or a silent log line based on exactly these 8 values.

0Fields in rate_limit_event
0Rolling windows (5h, 7d)
0Possible status values
0OAuth account, shared across clients

Field by field: what each one means for your session

The SDK docs treat this event as internal. The Anthropic pricing docs do not mention it at all. But the moment you build a client that runs Claude Code on behalf of a user, every one of these 8 fields becomes something you have to render, react to, or log.

status

"allowed", "allowed_warning", "rejected", or "unknown". This is the headline. "allowed_warning" is the first signal that your subscription window is filling up and extra usage is about to start paying.

rateLimitType

"five_hour" or "seven_day". Tells the UI which rolling window the event is about. Fazm uses this directly in the label so a warning reads "your 5-hour window resets at 7:15pm" instead of a generic rate-limit string.

utilization (0-1)

Your position inside the current window as a float. At 0.6 you have plenty of room; at 0.95 you are about to spill into extra usage. The SDK fires an event every few requests, so the UI can show a live gauge.

resetsAt (unix seconds)

When the current rolling window rolls over. Fazm formats this into a local-time string at ACPBridge.swift line 883, so the user sees "resets at 7:15pm" in their own timezone rather than an ISO timestamp.

overageStatus

"allowed" or "rejected". The second-layer signal. If status is rejected but overageStatus is allowed, you are on extra usage and the session continues at API rates. If overageStatus is rejected too, the session is actually out of budget.

overageDisabledReason

Human-readable string explaining why extra usage is disabled when it is. Monthly cap hit, org disabled the feature, payment-risk rejection. Fazm logs this verbatim so the user understands why their Pro plan stopped paying.

isUsingOverage (bool)

True iff the current request is being billed to extra usage rather than to your subscription allowance. A client that respects user expectations renders a small "paying per-token" badge when this flips to true.

surpassedThreshold (0-1)

The utilization value at which the SDK decides to emit "allowed_warning". Different plans have different thresholds. The SDK exposes it so the UI can decide whether to render a subtle heads-up or a loud banner.

One rate_limit_event, from SDK to Fazm's UI

The event crosses three process boundaries before it reaches a banner the user can see. ACP Node subprocess to Swift main app to the floating chat window. At each step it is revalidated, not blindly forwarded. Here is the path.

Claude Agent SDK to Fazm floating bar, via the ACP bridge

Claude Agent SDK (Node)
rate_limit_event payload
Patched ACP entry (patched-acp-entry.mjs:143)
ACPBridge.swift
Chat banner (utilization warning)
Resets-at string in local time
Auto-fallback to bundled key if rejected

What extra usage looks like in a real Fazm log

The ACP bridge logs every `rate_limit_event` to stderr as a single structured line. That stderr lands in `/tmp/fazm.log` on production builds. Tail it while you chat and you can watch your 5-hour window fill up in real time. The log line at acp-bridge/src/index.ts:2464 is the source.

/tmp/fazm.log (production)

The 8 steps a Mac app takes to consume this event safely

Forwarding a rate-limit event naively is easy and wrong. If you throw on the first "rejected" status, you lose partial responses. If you never throw, credit exhaustion silently hangs the chat. Here is the pipeline Fazm settled on, each step anchored to a file and line in the open-source repo.

1

1. SDK emits rate_limit_event

The Claude Agent SDK fires an event every few API calls with the 8 fields described above. This event flows into the ACP subprocess Fazm spawns (see acp-bridge/src/index.ts line 518 startAcpProcess).

2

2. Bridge forwards the event verbatim

acp-bridge/src/index.ts lines 2443-2466 parses the SDK event, normalizes the status enum, and re-emits it to Swift as a JSON-line on stdout with type "rate_limit". No fields are dropped, no new fields are invented.

3

3. Swift decodes into InboundMessage.rateLimit

ACPBridge.swift line 1111 reads the JSON dict, pulls out rateLimitType, utilization, overageStatus, overageDisabledReason, and constructs the typed case at line 183. Everything is typed, nothing is a stringly-typed prop.

4

4. Bridge re-fires as StatusEvent.rateLimit

Line 871 unpacks the full 6-field inbound case and forwards only the 4-field subset to UI code (status, resetsAt, rateLimitType, utilization). The 2 overage fields stay internal so the Swift side can decide the fallback path.

5

5. UI renders the banner, chat continues

The important subtlety: line 873-876 says "do NOT throw on rate_limit rejected." The bridge lets the session keep streaming, because the SDK's rejected signal is a pre-check; the real session may still complete. Throwing here would lose a partial response.

6

6. If credit_exhausted fires, fall back

Line 849-851 is the hard-stop path. When Claude returns credit_exhausted, the bridge throws BridgeError.creditExhausted, which the BridgeMode switch catches and auto-swaps to .bundledKey. CHANGELOG 2.0.7: "auto-falls back to built-in account."

7

7. Analytics captures the event

AnalyticsManager.swift line 1000 fires the creditExhausted(previousMode:) PostHog event, so the Fazm team can track how often users hit the ceiling on their Pro vs Max plans, which pipelines caused it, and whether the bundled fallback actually caught it.

8

8. Session survives, user sees resets-at string

The user-facing message from line 1599-1605 formats the SDK's "resets X" fragment into "You've hit Claude's usage limit (resets 11pm (America/Santiago)). Upgrade to Claude Pro at claude.ai for higher limits." The session continues; the chat doesn't brick.

The fallback that keeps the session alive

Extra usage has a ceiling. When your personal Claude account hits that ceiling, Fazm swaps the auth mode instead of letting the session die. The switch is this tiny enum at the top of the bridge. The runtime impact is large, the code is small.

Desktop/Sources/Chat/ACPBridge.swift, lines 194-203

When `BridgeError.creditExhausted` fires at line 851, the caller catches it and re-initializes the bridge with `.bundledKey`. The CHANGELOG entry for Fazm 2.0.7 (2026-04-05) describes the behavior in one line: "Fixed chat failing silently when personal Claude account lacks access to the selected model, now auto-falls back to built-in account." Your Pro plan runs out, and the session keeps going.

Two ways a client can handle extra usage, on the same SDK event

Same rate_limit_event fires in both cases. Only the client decides whether to surface it, ignore it, or route around it.

FeatureA naive Claude Code clientFazm (forwards all 8 fields)
Renders utilization as a live gaugeNo, shows only "rate limited" stringsYes, tied to utilization field (0-1 float)
Distinguishes 5-hour vs 7-day limitGeneric "usage limit" labelUses rateLimitType directly in the banner
Knows if overage is actively payingNoisUsingOverage boolean, shown as badge
Explains why overage is disabledSilent failureLogs overageDisabledReason verbatim
Survives credit exhaustion mid-sessionSession dies on silent 402BridgeMode swap, session resumes on bundled key
Local timezone resets-at stringRaw ISO timestamp or nothingFormatted at ACPBridge.swift line 883
Session continues on status=rejectedThrows, loses partial responseIntentional no-throw at ACPBridge.swift line 873
Analytics event for extra-usage exhaustionNo visibilityPostHog creditExhausted(previousMode:) event

Tactics that actually reduce how much extra usage you burn

None of these are clever. They are boring and they work. Every one of them maps to a token count you will see in the SDK's token usage fields, so you can validate whether the tactic is actually saving you anything instead of just feeling like it.

Extra-usage reduction tactics, ranked by impact per minute of effort

  • Compact between tasks. The SDK counts compacted tokens against overage too, but a compact-then-continue cycle cuts input tokens dramatically vs letting the context grow linearly.
  • Pin a cheaper model per pipeline. Fazm's scheduled pipelines let you run the 20-minute session-replay loop on Haiku while the user-facing chat uses Sonnet or Opus.
  • Avoid screenshot-based automations. Every screenshot is tens of thousands of vision tokens. Fazm uses macOS accessibility APIs (AXUIElement, CGEvent) for clicks and reads, which cost a few hundred text tokens per turn.
  • Cap scheduled agents. Three launchd plists (com.m13v.fazm-inbox, -founder-chat, -session-replay) fire on intervals of 5 minutes, 15 seconds, and 20 minutes. Each tick is a session. Set the interval where the ROI breaks even.
  • Use the bundled key as a ceiling, not a floor. Run everyday work on your personal Claude (subscription + extra usage capped). Fall back to the bundled API key only when the SDK emits overageStatus=rejected. That way you pay API rates only for the delta past your plan.
  • Monitor utilization > 0.8. When the SDK flips status to "allowed_warning", stop new long-running tool-call loops. Compact, ship the partial result, and start a fresh session after the window resets.
  • Log overageDisabledReason. If it says "monthly cap reached" three weeks into the month, raise the cap once and watch. If it keeps happening, it's not a cap issue, it's an input-token shape issue upstream.

The OAuth account is one pool. It is shared across clients.

A detail the top SERP results do not state clearly: when you sign into Claude Code via OAuth, your Pro or Max allowance is a single budget across anthropic.com chat, the Claude Code terminal CLI, Fazm, and any other client that uses the same OAuth identity. If you run a 2pm Fazm workflow that pushes the five-hour window to 0.9, a 4pm Claude Code terminal session inherits that 0.9 and may hit the warning threshold immediately.

The practical consequence: extra usage is a shared resource, not per-client. Turning it on in the Anthropic console turns it on for every client your OAuth account backs. Turning the monthly cap down affects all of them. This is why Fazm forwards the SDK's rate_limit_event instead of reinventing its own tracking, and why the `isUsingOverage` boolean is the truth, not the app's own guess.

0

Fields in the SDK's rate_limit_event, forwarded verbatim through Fazm's ACP bridge.

0%

Utilization threshold at which Fazm's chat UI renders a heads-up banner that new long tool-call loops are risky.

0

Launchd plists that fire autonomous Claude Code sessions in Fazm: inbox (5m), founder-chat (15s), session-replay (20m). Each tick spends extra usage.

Use Fazm to run Claude Code without losing sessions to extra usage

Sign in with your own Claude account to share your Pro/Max allowance, let Fazm auto-fall back to the bundled API key when your plan hits its ceiling, and watch utilization climb in /tmp/fazm.log while the chat keeps streaming.

Download Fazm

Frequently asked questions

What is Claude Code extra usage, in one honest sentence?

Extra usage is the Anthropic billing setting on Pro and Max plans that, once toggled on, lets Claude Code keep running after you blow past your subscription allowance by charging the overflow at standard API rates. It is opt-in per account, capped by a monthly dollar ceiling you set in the console, and can be rejected mid-session if you hit that ceiling or if Anthropic's risk signals disable it. Docs: support.claude.com article 12429409. What the docs do not document is the wire format Claude Code actually emits while you consume it. That format is a `rate_limit_event` with 8 fields, and this guide walks through all 8 against real code.

What are the 8 fields in the rate_limit_event Claude Code emits?

They are declared in Fazm's ACP bridge at `acp-bridge/src/protocol.ts` lines 245-256, because the bridge forwards the Claude Agent SDK's `rate_limit_event` verbatim so a Mac app can consume it. The 8 fields: `status` ("allowed" | "allowed_warning" | "rejected" | "unknown"), `resetsAt` (Unix seconds), `rateLimitType` ("five_hour" | "seven_day"), `utilization` (0-1 float), `overageStatus` ("allowed" | "rejected"), `overageDisabledReason` (string or null), `isUsingOverage` (boolean), `surpassedThreshold` (0-1 float). Together, those tell a client app which of the two rolling windows you are in, how close to the ceiling, whether extra usage is picking up the slack, and if not, why.

What actually drains Claude Code extra usage the fastest?

Three patterns dominate. One, long-running agent sessions that never compact, because the input token count grows cubically with tool-call loops. Two, anything screenshot-based, because every frame is a multi-hundred-thousand-token image and vision models charge per token in, not per pixel. Three, scheduled background agents that fire without a human in the loop. Fazm's repo ships three of those: `com.m13v.fazm-inbox` (5 min), `com.m13v.fazm-founder-chat` (15 sec), `com.m13v.fazm-session-replay` (20 min). Each plist is a Claude Code session per tick. If you run a similar cron without a utilization guard, extra usage is the line item that absorbs the cost.

Why does Fazm forward rate_limit_event into its UI instead of letting Claude Code handle it?

Because the Claude Code CLI in terminal mode has a human at the prompt. Fazm runs Claude Code over ACP inside a desktop chat surface, sometimes autonomously, sometimes at 3am when nobody is watching. If the session throws `credit_exhausted` silently, the user's inbox pipeline just stops. By forwarding the SDK's own rate_limit_event into Swift (see `Desktop/Sources/Chat/ACPBridge.swift` line 183), Fazm can render a warning banner at utilization > 0.8, auto-fall back to the bundled API key if `overageStatus` is `rejected`, and log `overageDisabledReason` to the session transcript so the user understands why their Pro plan stopped paying. None of that is possible from the terminal CLI alone.

What does Fazm do when extra usage hits its ceiling mid-session?

`ACPBridge` has two `BridgeMode` values: `.personalOAuth` (your own Claude account, uses your extra usage allowance) and `.bundledKey(apiKey:)` (a bundled Anthropic API key Fazm pays for). When your personal plan returns a `credit_exhausted` event, the `BridgeError.creditExhausted` path at line 1599 fires, which the user-facing message formatter turns into "You've hit Claude's usage limit (resets X). Upgrade to Claude Pro at claude.ai for higher limits." The CHANGELOG at 2.0.7 describes the auto-fallback: "Fixed chat failing silently when personal Claude account lacks access to the selected model, now auto-falls back to built-in account." So the session survives the limit instead of dying on a silent 402.

What's the difference between the five_hour and seven_day rate limit windows?

Claude Code runs two rolling windows on Pro and Max. The five-hour window is the classic session budget; it resets as a sliding window relative to your first request. The seven-day window is the weekly ceiling Anthropic added in August 2025. Either can trigger extra usage consumption. The SDK's `rate_limit_event` tells you which one via `rateLimitType`, and `utilization` is your 0-to-1 position inside that window. Fazm uses both: a utilization banner in the chat UI, and, via `rateLimitType`, a message like "Your five-hour limit resets at 7:15pm" rather than a generic "rate limit" string. Source: `ACPBridge.swift` line 886 uses `rateLimitType` as the label.

Is there a way to avoid Claude Code extra usage entirely?

Yes, three ways, with tradeoffs. First, keep sessions short and compact often. Every unnecessary context carry-over is a future input-token charge. Second, avoid screenshot-based agents for repetitive GUI work, since vision tokens are the dominant cost. Fazm uses real macOS accessibility APIs (AXUIElement and CGEvent) for clicking and reading state, which is why a Fazm workflow that toggles a Mail rule uses a few hundred tokens while a screenshot-based equivalent burns tens of thousands. Third, route autonomous cron agents through a cheaper model. Fazm's inbox and session-replay pipelines let you pin the model per pipeline so the 20-minute replay loop can run on Haiku while the 15-second founder chat uses Sonnet.

Can I see the rate_limit_event in my own Fazm session logs?

Yes. The ACP bridge logs every `rate_limit_event` to stderr with `Rate limit: status=..., type=..., utilization=..., resets=...` at `acp-bridge/src/index.ts` line 2464. Fazm's bridge stderr lands in `/tmp/fazm-dev.log` for dev builds or `/tmp/fazm.log` for production. Tail that file while you chat and you can watch your utilization climb in real time. When it crosses `surpassedThreshold`, the SDK changes `status` from `allowed` to `allowed_warning`, and at `rejected` you know the window closed.

Does Fazm share extra usage with Claude Code in terminal?

Yes, when you sign in with `.personalOAuth` (the default), the extra usage pool is a single allowance on your Claude account, shared across anthropic.com chat, the Claude Code CLI in terminal, and any Fazm session. This is the practical consequence of OAuth: you are not running two accounts, you are running one account from two clients. So a long Fazm session at 2pm can push your five-hour utilization high enough that a 4pm Claude Code terminal session inherits a rejected rate limit. The UI banner in Fazm is deliberately the same fact the CLI would show, sourced from the same SDK event.

Why does the SDK emit both status=rejected and overageStatus=rejected as separate fields?

They answer different questions. `status=rejected` means your subscription allowance is exhausted for this window. `overageStatus=rejected` means the fallback billing at API rates has itself been disabled, which can happen if you hit your monthly spending cap, if the org turned extra usage off, or if Anthropic's payment risk layer rejects the card. `overageDisabledReason` is the human-readable string explaining which of those. A well-behaved client renders both: if `status=rejected` but `overageStatus=allowed`, the session continues on extra usage silently. If both are `rejected`, that is when your session actually dies and you need the fallback path Fazm wires up in `BridgeMode.bundledKey`.

Claude Code extra usage is telemetry, not a toggle

A client that consumes the 8 fields correctly stays alive past the five-hour rollover, explains why your overage is disabled, and routes around a monthly cap instead of dying on it. Fazm runs Claude Code inside a Mac app, so we had to wire this up. The code is open. The event is open. The only thing missing from the SERP was someone explaining all 8 fields at once.

Download Fazm for Mac
fazm.AI Computer Agent for macOS
© 2026 fazm. All rights reserved.

How did this page land for you?

React to reveal totals

Comments ()

Leave a comment to see what others are saying.

Public and anonymous. No signup.