The Claude Code weekly quota wall: Claude Code already knows, it just will not tell you.
The CLI just emitted rate_limit_error: limit reached and stopped your loop. claude.ai web chat in the other tab still works, which is confusing. The credentials and the endpoint that would name the bucket that walled you are already on your machine. Here is what the CLI threw away and how to read it.
The Claude Code weekly quota wall is Anthropic's rolling 168-hour per-account ceiling. The server returns seven weekly buckets on /api/organizations/{org}/usage (and on api.anthropic.com/api/oauth/usage for OAuth clients). The CLI 429s the moment any one of them crosses utilization 1.0, but the inline error string does not name the bucket. Pull the access token Claude Code already stashed in macOS Keychain under service Claude Code-credentials, hit the OAuth usage endpoint, and you will see which one fired plus the absolute UTC resets_at when it lifts. ClaudeMeter is the open-source menu bar app that polls that endpoint every 60 seconds for you; source at github.com/m13v/claude-meter.
The terminal moment
This is the exact UX of hitting the weekly wall mid-loop. Read line 5 carefully: no bucket name, no resets_at, no indication that seven_day_oauth_apps is the one that fired and not seven_day (which is why your web tab still works).
What Claude Code already has on your machine
Claude Code authenticated you with an OAuth flow at install time. The credentials it received are sitting in your macOS Keychain right now, under a single keychain item. The shape:
Two fields matter for the wall. accessToken is what authorizes calls to api.anthropic.com; the scope user:profile is enough to read your own usage. And rateLimitTier tells you which cap row to read against (Max 20x users see default_claude_max_20x here). Claude Code wrote both. Claude Code is choosing not to show them inline when the wall fires.
“The CLI prints one error string. The endpoint behind it returns seven utilization floats and seven reset timestamps. Same auth, same machine, two different surfaces.”
src/oauth.rs, github.com/m13v/claude-meter
The endpoint Claude Code reads but does not surface
The same token authorizes a GET on https://api.anthropic.com/api/oauth/usage. You can call it from a terminal in about ten seconds without installing anything else.
The response on a wall-fired account looks like this. The bucket that walled you is whichever utilization is at 1.0 (or 100 on payloads that ship 0 to 100 instead of 0 to 1).
What the CLI shows vs what the endpoint returns
| Feature | Claude Code CLI error string | api.anthropic.com/api/oauth/usage |
|---|---|---|
| Names which weekly bucket walled you | No. One generic 'rate_limit_error: ... limit reached' string for all seven weekly buckets and the 5-hour bucket. | Yes. Each bucket has its own utilization float and its own resets_at timestamp; the bucket at 100% is the one that fired. |
| Says when the wall lifts | No precise resets_at in the inline error. The /usage slash command shows it if you remember to run it. | Yes. Absolute UTC timestamp on every bucket, polled every 60 seconds. Two parallel agents converge on the same wake-up moment. |
| Separates Claude Code traffic from web chat | No bucket-level visibility in the CLI. You have to guess from context why web chat still works while the terminal is blocked. | seven_day_oauth_apps is its own field. If it is the one at 100%, web chat keeps working; that explains the asymmetric block. |
| Reports extra-usage dollar balance | Inline error does not mention it. extra_usage is on a different endpoint (/overage_spend_limit). | extra_usage row on the same /usage response. monthly_limit, used_credits, is_enabled, currency all read in one call. |
| Aggregates across multiple Claude accounts on one machine | Per-CLI-process only. The CLI you ran has no idea another shell is racing for the same weekly bucket on the same account. | dedupe_by_account in lib.rs collapses snapshots from OAuth + cookies + multiple browsers into one row per account. |
What to do in the next 60 seconds
Commit the half-done work first.
Run git commit -am 'WIP: refactor checkpoint' so the work is recoverable from disk. Claude Code's next session reads from git diff; if you skip the commit and the editor crashes, the wall cost you the work too.
Read which bucket fired.
Inside Claude Code, type /usage. Outside it, curl the OAuth endpoint with the token from your Keychain (snippet above) or open ClaudeMeter's popup. Whichever bucket is at 100% is the one that walled you. seven_day_oauth_apps at 100% with seven_day at 30% explains why claude.ai web chat still works.
Defer model-specific work.
If seven_day_opus is at 100% but seven_day_sonnet is at 60%, drop to Sonnet for the rest of the cycle. Most of a refactor is mechanical (rename, move, adjust import, update test) and Sonnet handles it at a fraction of the weekly cost. Reserve Opus for the genuinely hard subproblems on the next reset.
Sleep on resets_at, not on a guess.
The clock is rolling, so 'try again in 4 hours' is wrong. Wrap the next batch in a four-line bash guard that reads the resets_at field of the bucket that fired and sleeps until that exact timestamp plus 30 seconds of grace. Two parallel agents in different shells converge on the same wake-up because resets_at is absolute UTC, not a relative duration.
Wrap the next batch in a guard that sleeps on resets_at
Sleeping on a guess wastes minutes you could have been coding, because the rolling window does not refill on the hour. The absolute UTC timestamp on the bucket that fired tells you exactly when the oldest still-counted message ages out. Sleep on that plus a 30-second grace and the next batch lands the second the wall lifts.
Two parallel agents in two shells will converge on the same wake-up moment because the timestamp is absolute UTC, not a relative duration. ClaudeMeter packages the same logic in a menu bar app so you do not have to maintain the shell script; the bar shows the hottest bucket continuously and the popup names which one is at 100% the moment it crosses.
Why this matters for parallel Claude Code sessions
Running five Claude Code agents in five worktrees does not get you five separate weekly quotas. The seven_day_oauth_apps bucket is per-account, not per-process. Five agents in five panes stack into the same utilization float. Each individual CLI sees only its own 429 and prints the same generic error string; none of them knows about the others. The OAuth usage endpoint is the only place the per-account number is visible to any one shell, which is why a single menu bar reader that polls it once per minute beats five independent CLIs that learn about the wall after they hit it.
ClaudeMeter's dedupe_by_account in src/lib.rs collapses snapshots that share account_email or org_uuid into one row, so the popup shows the one shared percent every parallel agent on that account is racing to fill.
Want help wiring this into your Claude Code loop?
20 minutes with the team. We walk through your weekly burn, install ClaudeMeter, and drop the wall-guard script into your wrapper.
Frequently asked
What is the Claude Code weekly quota wall?
It is the rolling 168-hour per-account ceiling Anthropic enforces against your Claude Code traffic. Anthropic's /api/organizations/{org_uuid}/usage endpoint returns seven weekly buckets (seven_day, seven_day_sonnet, seven_day_opus, seven_day_oauth_apps, seven_day_omelette, seven_day_cowork, plus the cross-cutting seven_day aggregate) and a five_hour bucket on top. When any one of them crosses utilization 1.0 the API responds 429 and Claude Code prints rate_limit_error: ... limit reached and stops the loop. The clock is rolling, not calendar; the bucket that fired is not named in the CLI output.
Why does the CLI just say 'rate limit reached' without saying which limit?
Because Claude Code shows you the server's textual error string, and Anthropic's 429 body uses one shape regardless of which bucket fired. The structured detail lives in a separate JSON payload at api.anthropic.com/api/oauth/usage (the endpoint the OAuth token has scope for) and at claude.ai/api/organizations/{org_uuid}/usage (the endpoint the web Settings page calls). Neither is surfaced inline by the CLI. The slash command /usage shows a one-shot snapshot if you stop and type it, but during an active loop the next message is the one that 429s, and by then you are looking at the wall, not the bucket name.
How can I see which bucket actually walled me?
Two ways. (1) Run claude with /usage right after the wall fires; it prints the rolling-window percentages for five_hour, seven_day, and the per-model splits. (2) Read the raw JSON directly. The OAuth credentials Claude Code stores in macOS Keychain under service 'Claude Code-credentials' have user:profile scope, which is sufficient. Pull the access token with `security find-generic-password -s 'Claude Code-credentials' -w` and curl https://api.anthropic.com/api/oauth/usage with Authorization: Bearer <token>. You will see every bucket with its own utilization float and its own resets_at timestamp. ClaudeMeter polls that endpoint every 60 seconds so you do not have to.
Why does this fire while claude.ai web chat still works?
Because the bucket that walled you is probably seven_day_oauth_apps, which only counts traffic from OAuth-authenticated clients (Claude Code, MCP host loops, agentic CLIs). The web chat charges against seven_day (the all-up aggregate) and ignores the OAuth bucket. Your account can sit at seven_day=30% and seven_day_oauth_apps=100% at the same time, the web stays usable, the terminal does not. The field name is declared in models.rs lines 18-28 of the open-source ClaudeMeter repo.
How long until the wall lifts?
Whatever the resets_at field on the specific bucket that fired says. The seven_day buckets are rolling: resets_at is the UTC instant the oldest still-counted message will age out of the trailing 168-hour window. It is not a fixed weekday boundary. Two users at identical utilization will have different resets_at because their charging histories differ. claude-meter --json prints it. ClaudeMeter's popup renders it as 'in 2h' or 'in 3d' depending on distance, via fmtResets in extension/popup.js lines 17-27.
Will switching from Pro to Max fix it, or just push the wall later?
It pushes the wall later for the same workload. Max raises the cap on every weekly bucket. If you keep landing at 100% on a Wednesday with Pro, a bigger bucket means you land at 60% instead and finish the week. If you keep landing at 100% because one runaway agentic loop spent the whole week's quota in four hours, a bigger bucket just makes the next runaway loop more expensive. Read the rolling burn rate before you upgrade. Anthropic's July 2025 hours framing put Pro at roughly 40 to 80 Sonnet hours per week, Max 5x at 140 to 280, Max 20x at 240 to 480; those are estimated upper and lower bounds, not a stable conversion to the utilization float the server enforces.
Does enabling metered billing get me past the wall?
Conditionally. If extra_usage.is_enabled is true on /usage and used_credits is below monthly_credit_limit on /overage_spend_limit, prompts that would have walled instead bill against extra usage at standard API prices. If is_enabled is false, or out_of_credits is true on /overage_spend_limit, the wall stays the wall. ClaudeMeter shows extra_usage as a third row when it is present so you can see the live dollar burn instead of finding out at the end of the cycle. The field is in models.rs ExtraUsage struct, lines 9-16 of the repo.
Can I count my Claude Code tokens locally and avoid this?
No. ccusage and Claude-Code-Usage-Monitor walk ~/.claude/projects/*.jsonl and sum the inputTokens / outputTokens fields per session. The numerator is real. The denominator (Anthropic's plan cap) is not on disk. The server applies per-model weights and peak-hour multipliers that are not in the local logs. ccusage at 5% and claude.ai at 91% is the predictable mismatch that catches every team that tries this. The two are complementary: ccusage tells you what you spent in tokens, ClaudeMeter tells you where that puts you against the server's actual ceiling.
Is ClaudeMeter free, and what does it send anywhere?
Free, MIT licensed, source at github.com/m13v/claude-meter. The browser extension makes one HTTPS request per minute to claude.ai using the session cookie your browser already holds; the result is posted to a localhost bridge at 127.0.0.1:63762 that the menu bar app listens on. No telemetry, no cloud account, no analytics ping. Read background.js lines 14 to 44 if you want to audit the exact requests.
Adjacent reading
Why Max Users Still Hit Limits: Eight Buckets, Not One
Anthropic enforces eight independent server-side gates. Max raises caps; it does not collapse them. Triage which one fired in 60 seconds.
Hours Are a Vibes Metric, the Server Enforces a Float
Anthropic publishes weekly caps as 40 to 480 Sonnet hours by plan. The cap your account hits is a utilization float between 0.0 and 1.0. Here is the real contract.
ccusage at 5%, claude.ai at 91%: the predictable mismatch
Local-log tools count tokens that left your machine. Plan limits are utilization fractions on the server. Why they disagree, which one to trust.