Two boundaries, one consumer app, one concept most guides flatten into one

What is extra usage on Claude, seen from a Mac app with its own $10 built-in cap sitting in front of Anthropic's

Every other article about this defines extra usage the same way: Anthropic's pay-as-you-go overflow once your Pro or Max window is spent. True, but it is only the second half of the story for anyone using Claude through a consumer desktop client. The first half is the client's own budget. Fazm is a macOS client that ships with $10 of bundled-key credits the app pays for, enforces that cap in the Swift source at a single static let, and auto-switches to your personal Claude seat the moment you cross it. From that moment on, Anthropic's extra usage semantics take over. This guide walks through both boundaries, the exact files that enforce them, and what a user actually sees when the handoff happens.

M
Matthew Diakonov
12 min read
4.9from Backed by the Mediar team
Ships $10 of bundled-key credits before any sign-in
Auto-switches to your Claude seat at the cap
Detects Anthropic's 'out of extra usage' string verbatim
Renders rate_limit_event live once on your own seat

The short version

Anthropic sells Claude access on three consumer tiers (Pro, Max 5x, Max 20x), each with a rolling 5-hour session budget and a 7-day weekly budget. Once both are exhausted, the subscription has two choices: wall you off until the window resets, or let you keep going at standard per-token API rates up to a self-set monthly cap. The second path is what Anthropic calls extra usage. You turn it on at settings.claude.com, put a card on file, set a monthly dollar cap, and the overflow is billed directly to you.

Almost every explainer stops there. It is a correct description of Anthropic's billing surface. It is also incomplete for anyone using Claude through a consumer client, because the client itself can have its own metered budget sitting in front of Anthropic's. Fazm does. That changes where the phrase "extra usage" lands on your screen, and when.

In Fazm there are two separate "you have crossed a line" moments a long session can produce. The first is local: you spent the $10 of bundled credits the app pays for on your behalf. The second is remote: you spent your own Claude Pro or Max window and Anthropic started serving at API rates. The second one is the classical definition. The first one is the one most users actually hit first.

$10 cap

Extra usage sits at two layers on a Mac client with built-in credits. The client enforces a USD cap in static source. Anthropic's overage path, once the client hands off, is surfaced on the rate_limit_event stream.

Fazm Desktop/Sources/Providers/ChatProvider.swift, line 476

The two boundaries, side by side

A user does not see the word "builtin" or "personal" anywhere in the UI; they see a chat that just works. But internally the bridge runs in one of two modes, and only one of them even has a concept of Anthropic-side extra usage. The other has a client-side USD cap instead.

builtin (bundledKey)

The bridge uses a bundled Anthropic API key that Fazm owns. Cost per request is metered in USD against a static cap of $10.00, defined in ChatProvider.swift line 476. Anthropic-side extra usage does not apply here; the bundled key is billed at standard API rates from the first token, and Fazm absorbs it until the cap is reached. There is no 5-hour or 7-day window on this path; the only limit is the dollar sum of all requests.

personal (personalOAuth)

The bridge uses your Claude Pro or Max seat via OAuth. Here the classical extra usage model applies: a 5-hour rolling window, a 7-day weekly cap, and Anthropic's pay-as-you-go overflow past them when you have the feature enabled at settings.claude.com.

The auto-switch

builtinCumulativeCostUsd is accumulated on every response (line 2814). The moment it crosses $10, switchBridgeMode(to: "personal") is called on line 2819 and the bridge process is torn down and restarted in OAuth mode. pendingRetryMessage is preserved so the user does not lose the in-flight prompt.

The anchor fact: one line of Swift defines the first boundary

The $10 cap is not fetched from a remote config. It is not a user-adjustable setting. It is a static let on the ChatProvider class, evaluated at compile time, identical for every Fazm user. To change it we ship a new build.

Desktop/Sources/Providers/ChatProvider.swift

Three things are true about this code that do not appear in any other article on this topic. The cap is a fixed USD amount, not a token count. It accumulates across devices (the authoritative value is seeded from Firestore on startup, at line 1693 via APIClient.fetchTotalBuiltinCost). And the switch to personal mode is automatic; the user does not have to click anything before their next prompt starts running on their own Claude seat.

Pre-query guard, ChatProvider.swift lines 2271 to 2277

// Pre-query guard: check if builtin cost cap is reached
if bridgeMode == "builtin" && builtinCumulativeCostUsd >= Self.builtinCostCapUsd {
    log("ChatProvider: Builtin cost cap reached " +
        "($\(String(format: "%.2f", builtinCumulativeCostUsd))/$\(String(format: "%.0f", Self.builtinCostCapUsd))) " +
        "— switching to personal mode")
    showCreditExhaustedAlert = true
    await switchBridgeMode(to: "personal")
    // Don't return — let the query proceed on the personal account
}

What "out of extra usage" looks like on the wire

Once Fazm is running on your personal Claude seat, Anthropic's own extra usage comes into play. If you spend everything on your Pro or Max window and your overage cap too, Anthropic returns an error that the Node bridge has to recognize. It uses a two-path detector: a structured check against the SDK's api_retry payload, and a regex fallback on the error message text. The regex literally contains the phrase the overage surface returns.

acp-bridge/src/index.ts (line 1901 onward)

The literal substring out of extra usage inside the regex is what ties this file to Anthropic's wording. When the overage cap is hit on your own Claude seat, the error text Anthropic surfaces to the SDK includes that phrase, and this line is how the bridge knows to stop retrying and tell the desktop side instead. The Swift side wraps that into BridgeError.creditExhausted and the floating bar offers an upgrade or retry path.

Where the USD flows, and where the boundary flips

The left column is everything that contributes to the $10 built-in cumulative cost. The hub is the check inside ChatProvider. The right column is what happens once that hub decides the cap is crossed.

Cost accumulation and the switch hub

Anthropic SDK
ACP bridge
@AppStorage cumulative
builtinCostCapUsd: 10.0
showCreditExhaustedAlert
switchBridgeMode("personal")
personalOAuth
rate_limit_event live

One long session, traced across both boundaries

1

First-time user opens Fazm

No Claude seat is connected. bridgeMode defaults to builtin. createBridge (ChatProvider.swift line 492) returns ACPBridge(mode: .bundledKey(apiKey: ...)). builtinCumulativeCostUsd starts at whatever Firestore has stored, or 0 for a brand-new install.

2

First dozen prompts, builtin mode

Each response carries a costUsd value read from the Anthropic SDK. Line 2814 adds that to the running total. The user sees nothing unusual; there is no 5-hour or 7-day window on this path, only a dollar total.

3

Cumulative crosses $10

The post-query check at line 2815 evaluates true. showCreditExhaustedAlert flips to true, AnalyticsManager.creditExhausted fires a credit_exhausted PostHog event (AnalyticsManager.swift line 1004), and switchBridgeMode(to: "personal") is called on line 2819.

4

Bridge tears down and restarts in OAuth mode

switchBridgeMode defers the restart if a query is still in-flight (line 570), otherwise kills the old ACP process and starts a new one with ACPBridge(mode: .personalOAuth). If the user is already signed in to Claude, the UI shows "Switched to your Claude account. You can keep chatting." If not, isClaudeAuthRequired flips to true and the Connect Claude button appears.

5

Now on your own Claude seat, windows apply

Every request billed to your Pro or Max quota. The ACP bridge forwards rate_limit_event from the Anthropic SDK (patched-acp-entry.mjs) so the floating bar shows utilization and reset time in real time. five_hour, seven_day, seven_day_opus, seven_day_sonnet start appearing on rateLimitType.

6

You exhaust the session window on your own seat

status flips to rejected for five_hour. Anthropic checks whether extra usage is enabled on your settings.claude.com account. If it is, the next event carries isUsingOverage = true and the response keeps flowing at standard API rates, billed to your monthly overage cap.

7

Your monthly overage cap is reached

Anthropic surfaces an error containing the phrase "out of extra usage". The bridge regex at acp-bridge/src/index.ts line 1903 matches, a credit_exhausted protocol message fires (line 1914), and the floating bar shows an actionable error with the exact resets-at timestamp, not a generic 429.

What you feel: one boundary or two

A heavy Claude day, without and with a client-side budget

Every prompt hits your own Pro or Max seat from message one. You cross your 5-hour session window, Anthropic flips you onto extra usage (if you enabled it), and keep working until your monthly overage cap is reached. One budget. One 'ran out' moment. One invoice on your Anthropic account.

  • No client-side trial budget, you sign in before use
  • Only one out-of-usage message to parse: the overage one
  • Every token billed to you from the first chat
  • No concept of a bundled-key onboarding path

What the log looks like when both boundaries fire

A condensed excerpt of /tmp/fazm.log of a single long session that starts in builtin mode, crosses the $10 cap, auto-switches to personal mode, and then eventually exhausts Anthropic's extra usage too. Line formats match the actual log strings in ChatProvider and the Node bridge.

fazm.log
$0

bundled-key credit cap, ChatProvider.swift line 476

0

places in the app that trigger the auto-switch

0

substrings in the extra-usage detection regex

0

bridge modes, bundledKey and personalOAuth

Three trigger points, all the same switchBridgeMode call

The $10 cap is enforced in three places. Same effect every time, but the trigger differs depending on when the cumulative total crosses the threshold relative to the query lifecycle.

Where the switch fires

1

On startup

line 1701, after seeding cumulative cost from Firestore. Covers users whose cap was already crossed on another device.

2

Pre-query guard

line 2272. Checked before the next prompt is sent. Triggers when the user reopens the app and their stored total is already at the cap.

3

Post-query accumulation

line 2815. Runs after each response adds its costUsd to the total. Triggers the common case: a single query pushes you over.

4

showCreditExhaustedAlert

Flips to true on any of the above paths. The floating bar and main window both subscribe to this via ChatQueryLifecycle.

5

switchBridgeMode(to: "personal")

Single function handles all three. Defers the restart if a query is in-flight (line 570), otherwise tears down and restarts the bridge with .personalOAuth.

Edge cases a two-boundary model lets you handle cleanly

New user, no Claude seat yet

builtin mode covers the first chat without any sign-in. $10 is enough for a long evaluation session. If they decide to stay, the first boundary is where they connect their own seat; if they decide to leave, they never had to create a Claude account at all.

Returning user, seat already connected

bridgeMode may have been set to personal during onboarding. The $10 cap is irrelevant on that path; builtinCumulativeCostUsd is never incremented.

Built-in cap crossed across devices

Cumulative total lives on Firestore. A user who spent $6 on their laptop and $4 on their Mac Mini sees the switch on whichever device hits the $10 first, because initialize() seeds from the server value (line 1693).

Anthropic extra usage disabled by org admin

Post-switch, if the user is on a Team seat where extra usage is admin-disabled, the Anthropic error surfaces a different overageDisabledReason (admin_disabled). The regex still catches it via the generic 'hit your.*limit' branch.

Card on personal seat expires mid-session

Anthropic stops allowing overage. Error message containing 'out of extra usage' is matched by the regex at index.ts line 1903, the bridge sends credit_exhausted, and the Swift side shows an actionable billing link instead of a generic retry.

Exact vocabulary referenced across both boundaries

builtinCostCapUsd
builtinCumulativeCostUsd
bridgeMode
bundledKey
personalOAuth
switchBridgeMode
showCreditExhaustedAlert
credit_exhausted
out of extra usage
credit balance is too low
rate_limit_event
isUsingOverage
overageStatus
overageDisabledReason
five_hour
seven_day
overage
fetchTotalBuiltinCost
AnalyticsManager.creditExhausted

When either boundary matters in practice

Casual users will never cross either. A few chats a day on claude.ai stays inside the Pro window with plenty of margin, and a few chats through Fazm stays inside the $10 built-in credit budget for weeks. Both boundaries are for the heavy workloads: long agentic sessions, multi-tool refactors, overnight automation runs that leave the desktop bar open for hours.

For those workloads the two boundaries do two different jobs. The client-side $10 cap bounds Fazm's own spend against its bundled key, so a single runaway session cannot consume an uncontrolled amount of API cost on Fazm's bill. Anthropic's extra usage cap, once the user is on their own seat, bounds their spend on their own invoice. Two independent controls, each enforced in its own source of truth, each visible at a different moment on the floating bar.

$0bundled-key cap, enforced in Swift (ChatProvider.swift line 476)
0bridge modes the desktop client runs (bundledKey, personalOAuth)
0substrings in the credit-exhausted detection regex (index.ts line 1903)
0lifecycle points that can fire switchBridgeMode to personal

Want to see both boundaries flip on your own Mac?

Book a 15-minute walkthrough. We will open the floating bar against your own Claude seat and step through the builtin-to-personal handoff and the Anthropic extra usage path live.

Frequently asked questions

What is extra usage on Claude, in one paragraph?

Extra usage is Anthropic's pay-as-you-go overflow on a paid Claude subscription. After you burn through your Pro, Max 5x, or Max 20x window (both the rolling 5-hour and the 7-day weekly cap), Anthropic does not hard-stop you. If you have extra usage turned on at settings.claude.com with a card on file and headroom under your monthly cap, it keeps serving requests at standard API rates. The twist on a Mac client like Fazm is that there is a second, client-side boundary that lives in front of Anthropic's: the app ships with a $10 built-in credit budget it pays for on your behalf, and only after you cross that does it hand your traffic over to your own Claude seat, where Anthropic's extra usage rules take over.

Where exactly is Fazm's $10 built-in cap defined?

In the desktop source. ChatProvider.swift at line 476 declares static let builtinCostCapUsd: Double = 10.0. Every response the bundled-key bridge processes accumulates into @AppStorage("builtinCumulativeCostUsd") var builtinCumulativeCostUsd at line 479. The post-query hook at line 2814 adds queryResult.costUsd to that running total, and line 2815 checks whether the sum crossed the cap. When it does, the app fires AnalyticsManager.shared.creditExhausted and calls switchBridgeMode(to: "personal") on line 2819.

What is the difference between Fazm's built-in credits and Anthropic's extra usage?

They sit at different layers. Fazm's built-in credits are metered in USD and paid for by Fazm against a bundled Anthropic API key. The $10 cap is a product decision made in the desktop source, not an Anthropic feature. Anthropic's extra usage, by contrast, is the overage path on your own subscription: after you hit your Pro or Max limits, Anthropic keeps serving at standard API rates up to a monthly cap you set at settings.claude.com, and invoices you directly. A Mac user in Fazm will usually hit the $10 cap first (builtin mode), then get auto-switched onto their personal seat (personal mode), at which point Anthropic's extra usage semantics kick in.

When does the auto-switch from builtin to personal mode actually happen?

Three trigger points, all in ChatProvider.swift. First, on app startup: line 1701 seeds the cumulative cost from Firestore and immediately switches to personal if the server-authoritative total is already at or above $10. Second, pre-query at line 2272: before sending a prompt, the app checks builtinCumulativeCostUsd against the cap and switches if it crosses. Third, post-query at line 2815: after the cost of the latest response is added, it re-checks and switches if the query pushed it over. The user sees a one-time showCreditExhaustedAlert banner and keeps typing; the bridge is torn down and restarted in personalOAuth mode mid-conversation.

How does the ACP bridge detect that a user has run out of Anthropic extra usage?

With a dual detector. acp-bridge/src/index.ts line 1901 first checks the Anthropic SDK's structured api_retry payload for errorType === "billing_error" or "rate_limit", or HTTP status 402 or 429. If the structured signal is not present, line 1903 falls back to a regex that matches human error text including the verbatim phrase out of extra usage, plus credit balance is too low, hit your limit, rate limit rejected, and unable to verify membership. Either path triggers a credit_exhausted protocol message on line 1914, which the Swift side turns into BridgeError.creditExhausted.

Why does Fazm ship credits at all? Why not just require a Claude seat?

The built-in credits are an onboarding affordance. A first-time Mac user who installs Fazm does not yet have a Claude Pro or Max seat configured and does not want to sign in to Anthropic before they can try the product. Shipping $10 of bundled-key credits means the first chat works in the first minute, without sign-in. Once they have spent that budget, the app has demonstrated value, and the auto-switch to their personal Claude seat is a natural next step instead of a sign-in wall before first use. Fazm's AnalyticsManager tracks the transition as a credit_exhausted event (AnalyticsManager.swift line 1004) so product teams can see where each user lands on the funnel.

What happens if the user has no personal Claude seat when the $10 is gone?

The switch still fires, but the bridge comes up in personalOAuth mode with no token. The next query surfaces isClaudeAuthRequired = true, the floating bar shows a Connect Claude button (ChatQueryLifecycle.swift line 54), and the app waits for the user to finish OAuth before any further prompts go out. The credit_exhausted alert tells the user their built-in credits ran out and prompts them to connect, with language that differentiates between the two paths (OnboardingChatView.swift line 514 onward handles the onboarding-flow variant).

How does Fazm know the per-query cost with enough precision to sum against a $10 cap?

The ACP bridge reads queryResult.costUsd off the Anthropic SDK response, which itemizes input tokens, output tokens, cache reads, and cache writes against the per-model price sheet. ChatProvider.swift lines 2800 through 2808 forward those four token counts plus the USD cost to APIClient.recordLlmUsage so the total is persistent on the server and can be reconciled across devices. The client-side @AppStorage cumulative is a mirror for instant gating; the authoritative total comes from fetchTotalBuiltinCost at initialize() (line 1693).

Can the built-in cap be raised from $10?

The cap is a static let on ChatProvider, so it takes a client rebuild to change. It is intentionally not user-configurable: users adjust their Anthropic-side monthly extra usage cap at settings.claude.com, not the Fazm-side built-in cap. The product decision is that built-in credits are a trial, not a subscription; the scale path for heavy users is to connect a Claude Pro or Max seat and let Anthropic's extra usage do the work on their own invoice.

If the user connects their Claude seat first, does the $10 budget still exist?

No. Bridge mode is selected at bridge creation (ChatProvider.swift line 493). If bridgeMode is "builtin" and a bundled API key is present, the bridge uses the bundled key and the $10 cap is enforced. If the user has chosen personal mode (or if onboarding routed them there), createBridge returns ACPBridge(mode: .personalOAuth) at line 505 and the built-in cumulative cost is irrelevant. From there on, the only extra usage that matters is Anthropic's, measured against the user's own seat.

What exactly does the user see when they cross from the built-in cap into their own Claude seat?

A brief alert ("Switched to your Claude account. You can keep chatting." if already connected, or "Your free built-in credits have run out. Connect your Claude account to continue." if not) and an on-screen Connect or Upgrade Plan button on the floating bar. The queued message is preserved so the user can retry without retyping; pendingRetryMessage on ChatProvider is held across the switch for exactly this. Once the seat is connected and a new query fires, any rate_limit_event flowing back from Anthropic is rendered live on the bar (rateLimitStatus / rateLimitResetsAt), which is the point where the page-level Anthropic extra usage vocabulary (five_hour, seven_day, overage) starts mattering.

Does Fazm ever pay for Anthropic extra usage on a user's behalf?

No. The bundled API key used in builtin mode is separate from any user's Anthropic account, and the $10 cap exists to bound Fazm's own spend against that key. Once the cap is reached and the app switches to personalOAuth mode, every subsequent request bills against the user's own Anthropic subscription, so any actual Anthropic extra usage invoice lands on the user's account, not Fazm's.