Two Prices for the Same Model: Building Claude Burst
A flat Claude subscription can cost far less than the equivalent API usage for heavy users. Reconstructing one month of Claude Code session usage with local tooling showed that the same token volume, priced at public API rates, totalled several times the fixed monthly subscription price, meaning heavy users effectively consume API capacity worth a large multiple of what they pay.
I recently ran a comparison out of curiosity: what would a normal month of Claude Code usage on a fixed subscription have cost if it had instead been billed at public API rates. I built some local tooling to reconstruct that from session usage, because the standard analytics were not giving me the visibility I wanted into what individual sessions were actually consuming. That tooling is also open source, a live cost and usage panel that sits next to the terminal and prices every turn as it happens rather than waiting for an end of month invoice: github.com/andrewbakercloudscale/ai-agent-cost-usage-panel.
The result was startling. A heavy user on a flat monthly subscription had generated a token volume that, translated into public API pricing, worked out to a large multiple of what the subscription itself costs, and that gap looked impossible at first, since either my measurement was badly wrong, or Anthropic was selling the same intelligence through two commercial models whose economics were radically different.
The answer turns out to be more interesting than either explanation, and building something around that answer turned out to be a longer job than the idea itself suggested. What I built is called Claude Burst, and it is open source: github.com/andrewbakercloudscale/claude-burst.
1. Claude does not really have one price
When people say that Claude costs a certain amount, they are usually mixing together several very different products. Anthropic sells access to the same broad model family through subscriptions, through its metered API, through enterprise products, and through cloud providers such as Amazon Bedrock. The model may be recognisably the same, but the commercial contract around each route is not.
Claude Max is a fixed monthly subscription that includes Claude Code. It is not unlimited, since Anthropic applies rolling session limits that reset every five hours, weekly limits, and potentially other capacity controls, whereas API access is explicitly metered, so the more tokens you consume, the more you owe.
Amazon Bedrock also provides metered access to Anthropic models, but the bill arrives through AWS rather than directly from Anthropic.
| Route | Commercial model | What stops you | Typical identity |
|---|---|---|---|
| Claude Max | Fixed monthly subscription | Five hour, weekly and other usage limits | Individual Claude login |
| Anthropic API | Metered token consumption | Rate limits, spend limits or your budget | API or platform credential |
| Amazon Bedrock | Metered cloud consumption | AWS quotas, policy or your budget | AWS credential or Bedrock API key |
This means that asking what Claude “costs” is already the wrong question. A better question is what Claude costs through a particular commercial channel for a particular workload shape.
2. Does a large API equivalent value mean Anthropic is losing money on that account?
No, and this is the first distinction that matters. An API equivalent cost estimate answers a hypothetical question: what would this observed token mix have cost if it had been charged at public API list prices? It does not tell us Anthropic’s marginal cost of inference, its internal cost of compute, the effect of capacity commitments, its gross margin, or the economics of serving a subscription user during otherwise underutilised capacity.
The quality of the estimate also depends heavily on the measurement. Claude Code makes extensive use of prompt caching, so a tool that simply multiplies every input token by the normal input token price can significantly overstate the equivalent API bill, and a credible calculator needs to distinguish uncached input, cache writes, cache reads, output tokens, the model used, and any other pricing buckets that matter at the time.
My point is therefore not that Anthropic is necessarily losing money on any particular subscriber. The point is that the public value of the consumption, when translated into another Anthropic pricing model, can be dramatically larger than the subscription fee, and that pricing discontinuity is real even if Anthropic’s internal cost is far below the API equivalent number.
3. Why would Anthropic price it this way?
The most useful way to think about Max is not as cheap API access. It is closer to a bounded block of interactive capacity sold to one human.
Anthropic controls the risk through time windows, weekly allowances, model limits and other usage constraints, and a human developer also consumes capacity differently from a production API workload that can fan out thousands of requests, run continuously, serve external customers and create much less predictable concurrency. The API customer is buying something different even if the underlying model weights are the same.
There is also straightforward market segmentation. A fixed subscription gives an individual a psychologically simple price and encourages deep adoption, while API pricing captures value from workloads that scale with software rather than with one person’s working day, and enterprise products add administration, contractual controls, governance and support on top of the model access itself.
This is common in computing, and the interesting part is the size of the gap that appears once coding agents become heavy consumers of tokens, because a single strong engineer can now generate an amount of inference that would once have looked like a small application workload.
4. The obvious architecture is Max first, metered overflow second
Once I understood the distinction, the architecture became almost embarrassingly obvious.
Suppose an engineer has their own Max subscription and uses Claude Code interactively. While that subscription has capacity, use it. When Anthropic itself says that the five hour or weekly allowance has been exhausted, stop sending that engineer’s inference through the subscription and route the overflow to the same Claude model through Amazon Bedrock.
When the subscription window resets, move the engineer back automatically, and the cost equation becomes very simple:
effective monthly cost = Max subscription + actual metered overflow
You are no longer choosing between Claude Max and Bedrock. You are using them as two capacity tiers for the same underlying model family, where Max becomes the included base capacity and Bedrock becomes the burst layer.
This is conceptually similar to many infrastructure patterns we have used for years, where you consume the cheaper bounded capacity first, then pay an on demand rate only for the demand that exceeds it.
5. Anthropic already exposes the pieces required to build this
I initially assumed that implementing the idea would require an ugly wrapper around Claude Code, and it does not.
Anthropic’s current Claude Code documentation explicitly supports an LLM gateway through the ANTHROPIC_BASE_URL configuration. More importantly, the documentation says that if you set only the base URL and do not provide a replacement gateway credential, Claude Code keeps using the developer’s saved claude.ai subscription login, so requests pass through the gateway while the normal subscription usage limits and billing still apply.
That gives us exactly the interception point we need, since Claude Code also exposes the five hour and seven day subscription windows together with their reset timestamps, and distinguishes account usage limits from temporary server throttling. That means a router does not need to guess when somebody is close to a limit, scrape a web page, or estimate the window from local logs. It can wait until Anthropic says the allowance has actually been rejected, record Anthropic’s own reset time, replay that request to Bedrock, and remain on Bedrock until the window opens again.
There is one subtle but important rule here: a plain HTTP 429 is not enough. Anthropic also uses 429 responses for temporary server side throttling and other limits, so automatically converting every 429 into paid Bedrock traffic would be both technically sloppy and potentially expensive, and the router should switch only when the subscription specific quota state says that the included allowance is genuinely exhausted.
6. Checking this against Anthropic’s actual terms
That distinction between a genuine subscription rejection and ordinary throttling matters technically, and it also matters contractually, so it is worth checking against what Anthropic actually documents and has enforced, rather than against intuition alone.
The design does not attempt to make Max deliver more than Anthropic has allowed. It does not rotate accounts, share one user’s credentials across a team, modify Anthropic’s quota headers, fake a reset, or suppress a rejection. Once Max says no, that Max channel is treated as unavailable until Anthropic’s own reset time, and the next request is a separate, properly authenticated request through Amazon Bedrock, using a Bedrock credential the organisation already holds rather than the subscription’s own token.
That distinction lines up closely with how Anthropic itself describes this pattern. Anthropic’s Claude Code documentation states directly that pointing the base URL at a gateway without supplying a separate gateway credential does not replace the subscription, because the saved claude.ai login remains the active credential and its usage limits and billing still apply. That is precisely the mechanism Claude Burst relies on for the Max side of the routing, described by Anthropic as a supported configuration rather than discovered as a workaround.
The enforcement actions that have actually happened against subscription usage in 2026 are aimed at something different. Anthropic has repeatedly acted against tools that extract the OAuth token from a Claude Pro or Max login and hand it to a separate, unofficial client, so that client can call Anthropic’s API while impersonating Claude Code. That is credential extraction, and it is what got those tools blocked. Claude Burst does not do this, since the real claude binary is what runs, Claude Code’s own request and its own OAuth headers pass through the local gateway untouched on the Max path, and the only place a different credential is introduced is the Bedrock overflow path, where the organisation’s own AWS credential authenticates a separately billed request rather than impersonating the subscription.
The Consumer Terms’ catch all clause against bypassing Anthropic’s systems or protective measures is the one worth reading most carefully, and the router’s own behaviour is designed around it rather than against it: once Anthropic’s own rate limit response says the allowance is exhausted, the gateway treats that rejection as final for the rest of the window rather than retrying it, disguising it, or working around it, and the overflow to Bedrock happens only after the limit has been respected, never instead of respecting it.
None of this removes the more mundane consumer versus commercial question. Anthropic’s own guidance to users who hit their Max limits during coding work is to switch to metered API credits, and the Consumer Terms note that Claude Pro and Max are offered for individuals or entities, while separate Commercial Terms govern API keys and Console access. That means an organisation running many individual Max subscriptions is still operating under Consumer Terms per account, with each account expected to reflect one engineer’s own ordinary use rather than a shared or automated pool, which is as much a procurement question as a technical one, and it is the reason Claude Burst is built around one Max login per engineer rather than any shared credential.
I am not a lawyer and this is not legal advice, and terms of service are not static either: Anthropic sharpened its own published distinction between the Claude Code CLI and its separate Agent SDK once already in early 2026. A company relying on this pattern at scale should read the current Consumer Terms, Acceptable Use Policy, and Claude Code legal and compliance documentation itself, and treat this section as a starting point for that review rather than a substitute for it.
7. Security controls can change the enterprise calculation, but not the contract
One of the normal reasons to insist on an enterprise AI product is data control, but that control does not actually come from which Anthropic plan sits in the base URL. It comes from where an organisation’s own data loss prevention sits relative to the traffic.
For a setup like this to be safe regardless of whether a given request ends up going to Max or to Bedrock, the inspection needs to sit in one of two places: in front of the terminal itself, so a coding agent’s tool calls and file reads are filtered before they are even assembled into a request, or on the wire between the laptop and the internet, the way a zero trust network access gateway inspects and filters egress traffic regardless of which destination a process is trying to reach. Either position catches an accidental paste of a secret, a customer record, or other regulated data before it leaves the building, and it does so on every route this architecture can take, rather than only the one route an administrator happens to be thinking about that day.
That also means the safety of running something like Claude Burst is not a property of the gateway itself. It is a property of what already sits around it. An organisation with mature, already deployed DLP and zero trust controls sitting in front of the terminal or on the wire can reasonably treat the choice between Max and Bedrock as a cost and capacity decision, because the same inspection already applies to both. An organisation without that maturity should not assume the routing layer gives it any of that protection, because it does not, and should instead assess this case by case, looking at which teams, which data classifications, and which existing controls, if any, actually sit between the engineer’s machine and the model, before deciding whether a fixed subscription plus metered overflow is an acceptable pattern for that team at all.
It does not remove every difference between consumer and commercial products either. Consumer and commercial Anthropic products still have different administration, data processing, retention, and governance arrangements, and those still matter on their own terms. The lesson is simply that a company should identify which controls it genuinely needs from the AI vendor and which controls it already enforces elsewhere, rather than assuming the most expensive commercial route is automatically the safest architecture, or that a cheaper subscription route is automatically unsafe.
8. Building the first version of the router
I have called the experiment Claude Burst, and the first version is deliberately small and Mac only.
Claude Code points to a localhost gateway, the gateway forwards requests to Anthropic using the engineer’s existing Max login, and it watches only the authoritative quota metadata. When Anthropic rejects the subscription allowance, Claude Burst records the reset time and replays the request against the mapped Claude model on Amazon Bedrock.
The Bedrock credential is kept in macOS Keychain. The current MVP uses a Bedrock API key and Amazon’s Anthropic compatible Messages endpoint, which keeps the translation layer much smaller than converting every Claude Code request into the older Bedrock InvokeModel wire format.
The most important behaviour is deliberately conservative, since ordinary 429s do not trigger paid overflow. The code only changes routes when the subscription specific limit is rejected, and it moves back to Max after the exact reset timestamp supplied by Anthropic. There are obvious next steps before this becomes enterprise software, among them replacing long lived Bedrock API keys with AWS SSO and role assumption, testing broader model compatibility, and soak testing the gateway against new Claude Code beta capabilities as Anthropic releases them, which is why I am treating this as an open source experiment rather than pretending the first build is a finished platform.
9. The first version worked, and that was not the same as it being trustworthy

Screenshot
The core routing logic was sound and the first test suite proved the interesting case: a rejected Anthropic request really did get replayed to Bedrock with the model remapped and the OAuth beta header stripped. What it did not have was a way to answer a much more mundane question: if something goes wrong at three in the morning, what actually happened.
The original router had one real log statement, written when overflow activated, recording the claim, the reason and the reset time, and every other branch that could go wrong called an HTTP error response and returned. A body that failed to read, a request over the configured size limit, a Bedrock key missing from Keychain, a model with no entry in the model map, a network error calling either upstream, a failed write to the metrics file, all of these returned a sensible status to Claude Code, but none of them left a trace anywhere on disk.
That is a reasonable shape for a proof of concept. It is not a reasonable shape for something that sits between a paid subscription and a metered AWS bill and decides, unattended, which one an engineer’s inference goes through.
10. Every request now gets a start line and a done line
The fix I wanted was simple to state and slightly fiddly to get right without disturbing the streaming response path. Every request, successful or not, now gets a short id, generated once at the top of the handler and carried through the request’s context, and two lines get written for that id, one when the request starts and one when it finishes, with the finishing line always carrying the actual HTTP status the client received and how long the request took.
The fiddly part was getting the true final status out of a handler that streams a response body directly rather than building it up and writing it once. I wrapped the response writer in a small type that records the first status code written, whether that happens through the header call or through the first write, and still passes flushing through so the server sent events relay loop keeps working exactly as before. The wrapper does nothing except remember what already happened, and it does not change behaviour.
With that in place, a panic recovery wrapper became almost free to add. If anything below panics, a stack trace goes into the log against that same request id, the client gets a clean server error instead of a hung connection or a crashed process, and the done line still gets written, because a local gateway that a developer is relying on to keep working through their session should not be one unhandled error away from taking Claude Code down with it.
11. Naming the failure instead of hiding it
Once every request had a start and a done line, the next pass was going through each early return and giving the operator something to search for: not a generic exception message, but a labelled stage, whether that stage is reading the body, building the outbound request, the upstream call itself, loading the Bedrock key, or mapping the model, with each of those now writing one line naming the stage, the route, and the underlying error before the response goes back to the client.
This matters more than it looks. “Bedrock overflow unavailable” told a user something was wrong, but it did not tell whoever runs the fleet of these gateways whether the problem was a missing environment variable, a Keychain entry that got wiped by an OS update, or Bedrock itself being unreachable. Those are three different follow up actions, and previously they all looked identical from the log file, because there was no log file entry at all.
12. A metrics failure must never become a request failure
The structured metrics file records the route, model, tokens, estimated API equivalent cost, and the reset claim when one applies, and it is written after the response has already been sent to Claude Code. That ordering matters, because it means a failure to write that file, whether from a full disk, a permissions problem, or a configured path that turned out to be a directory, must never turn into a failure of the actual inference request. The old code silently discarded that write error, and it still silently continues past the failure, which is correct, but it now logs the error first, so a slow, quiet loss of metrics does not go unnoticed until someone tries to summarise usage and finds three weeks missing.
The same principle applied to the small local state file that records whether the gateway is currently in overflow. Reading a corrupted state file or failing to write an updated one previously failed silently, and both now log what happened and continue with a safe default rather than either crashing or pretending nothing occurred.
13. Writing tests for the failures, not just the feature
The original test suite proved the feature, and six new tests prove the surrounding behaviour that makes the thing operable.
One confirms that the start and done lines for a single request share the same id, since a log you cannot correlate is barely better than no log at all. One sends an oversized body and checks both the rejection and the specific log line explaining why. One removes the Bedrock credential entirely and checks that the failure is a clear, immediate error with the stage named, rather than a hang. One sends a model with no Bedrock mapping and checks that the error names the offending model. One sends a plain server error from the primary upstream and checks that it passes straight through without being mistaken for a subscription limit, since that distinction is the entire point of the conservative failover design. One points the metrics path at a directory instead of a file and confirms that the actual inference request still succeeds while the failure gets logged. The last one hands the handler a request body that panics on read, a reasonable stand in for a corrupted transport, and confirms that the panic is caught, logged with a stack trace, and turned into a clean error rather than escaping.
All eleven tests pass together, along with a vet check and a race enabled run. Test coverage on the router package sits at fifty two percent, which is an honest number for a project that still has real gaps in it, among them AWS SSO support and broader Bedrock model compatibility testing, rather than a number inflated by testing getters and setters.
14. What did not change
The privacy design from the first version stayed exactly as it was. Prompts, source code, tool inputs and model outputs are still never written to disk anywhere, including in the new logging, because logging everything here meant every code path and every failure mode, not the content of the requests themselves. For something that sits in front of a bank’s engineers, that is not a detail to change casually, and it is not a decision this pass tried to revisit.
15. The experiment I actually want to run
The interesting number is no longer the theoretical figure from that first comparison. It is the real blended cost of a strong developer over time.
For each engineer I want to measure the API equivalent value consumed while Max is serving requests, the number of times Max actually reaches a hard allowance, the amount of time spent on Bedrock overflow, and the real AWS cost of that overflow, and after a month the economics should be obvious.
If a fixed subscription absorbs most interactive coding demand and Bedrock only catches occasional bursts, then paying API rates for every token is economically difficult to justify for this workload. If heavy engineers live on Bedrock for large parts of the week, the apparent Max advantage will shrink and a commercial enterprise arrangement may be the better answer. Either result is useful because it replaces vendor pricing assumptions with measured workload economics, and now, when that experiment produces a surprising number or an unexpected failover, there will be a log line explaining why.
16. AI pricing is becoming an architecture problem
The broader lesson is that model selection is no longer the only meaningful cost decision in AI engineering. The route to the model can matter as much as the model itself.
Two requests can reach essentially the same Claude intelligence and have radically different economics because one sits inside a fixed subscription allowance and the other is metered token by token, and as AI agents become capable of consuming enormous amounts of context during an ordinary developer’s day, those pricing boundaries become architecture boundaries.
I learned the pricing half of this from a comparison that, at first glance, looked like a measurement error, a subscriber on a flat monthly plan whose usage translated into a large multiple of that plan’s cost at public API rates. I learned the engineering half of it by building something small enough to feel finished after a weekend, and then finding out how much further it is from working to trustworthy. The next logical step is not to complain that the pricing makes no sense, but to design around the commercial reality that Anthropic has created, and to build the boring, unglamorous parts, the logging, the error handling, the tests for the failure paths, with the same care as the interesting routing decision at the centre of it.
Use the included capacity, respect the limit, pay only for the burst that exceeds it, and log everything that goes wrong along the way so you never have to guess.
That may turn out to be a much better way to buy coding intelligence.
17. Installing and setting up Claude Burst
The code is now pushed, so here is the full, working setup rather than a description of it. Claude Burst is Mac only and needs macOS on Apple Silicon or Intel, Go 1.23 or later (there is no prebuilt binary, install.sh builds one locally), and either Claude Code already installed and logged into the Pro or Max account you want to route through, or a metered Anthropic API key if you have no subscription at all. You will also need Amazon Bedrock access to the Claude models you intend to burst to, and a Bedrock API key set as AWS_BEARER_TOKEN_BEDROCK.
17.1 Standard install (subscription primary, Bedrock overflow)
This is the setup described throughout this post: Claude Max as included capacity, Bedrock as paid overflow.
git clone https://github.com/andrewbakercloudscale/claude-burst.git
cd claude-burst
export AWS_REGION=us-east-1
export AWS_BEARER_TOKEN_BEDROCK='your-bedrock-api-key'
./install.shinstall.sh does five things, in order: it builds the claude-burst binary with go build and installs it to ~/.local/bin/claude-burst; it stores the Bedrock key in macOS Keychain, since AWS_BEARER_TOKEN_BEDROCK is set; it writes the initial ~/.config/claude-burst/config.json; it updates ~/.claude/settings.json with only ANTHROPIC_BASE_URL=http://127.0.0.1:7777, deliberately adding no Anthropic credential of its own so the saved Max login stays active; and it creates and starts a macOS LaunchAgent so the gateway survives reboots, adding ~/.local/bin to ~/.zprofile if it is not already on the path.
Restart Claude Code once the installer finishes, since it needs to pick up the new base URL.
17.2 No-subscription install (metered API key primary)
If there is no Pro or Max subscription to route through, an Anthropic API key can be the primary route instead, with Bedrock still as the secondary. Because both sides are now metered, a single rate-limit response should not be enough to flip paid traffic from one provider to another, so this mode fails over on a sustained run of failures rather than on a subscription-exhaustion header:
export AWS_REGION=us-east-1
export AWS_BEARER_TOKEN_BEDROCK='your-bedrock-api-key'
./install.sh
claude-burst keychain-set
claude-burst configure --primary anthropic-api-key --secondary bedrock --region us-east-1
claude-burst enableThen set ANTHROPIC_API_KEY in Claude Code’s own settings, in the env block of ~/.claude/settings.json alongside ANTHROPIC_BASE_URL, not in Claude Burst’s own config. The gateway never stores or injects an Anthropic credential itself; it only forwards whatever auth header Claude Code already sent, in exactly the same way it forwards the OAuth header in subscription mode.
17.3 Verifying it worked
claude-burst status
curl -s http://127.0.0.1:7777/health
claude-burst statsclaude-burst status confirms the gateway is running and which route it currently thinks it is on. The health check confirms the local listener is actually up on port 7777. claude-burst stats reads back whatever has already landed in the structured metrics file. It is also worth checking Claude Code’s own /status and /usage views directly, to confirm it is still routed through the intended subscription before any failover happens.
17.4 Day to day commands
claude-burst serve # run the gateway in the foreground
claude-burst configure --region us-east-1
claude-burst configure --primary anthropic-api-key --secondary bedrock
claude-burst configure --secondary none # disable overflow entirely
claude-burst keychain-set # Bedrock: reads AWS_BEARER_TOKEN_BEDROCK
claude-burst keychain-set --provider together # OpenAI-compatible secondary, reads TOGETHER_API_KEY
claude-burst enable
claude-burst disable
claude-burst status
claude-burst reset
claude-burst stats --days 30
claude-burst version17.5 Configuration file
Everything above ultimately writes to ~/.config/claude-burst/config.json. Older flat fields (anthropic_base_url, bedrock_base_url, model_map, keychain_service) are still read and still work, and are synthesised into primary/secondary blocks automatically, but a fresh install can configure primary and secondary directly:
{
"listen": "127.0.0.1:7777",
"reset_grace_seconds": 10,
"unknown_reset_seconds": 300,
"response_header_timeout_seconds": 60,
"max_request_mb": 128,
"primary": {
"provider": "oauth-passthrough",
"base_url": "https://api.anthropic.com",
"failover_strategy": "subscription-limit"
},
"secondary": {
"provider": "bedrock",
"base_url": "https://bedrock-runtime.us-east-1.amazonaws.com/anthropic",
"keychain_service": "claude-burst-bedrock",
"model_map": {
"claude-sonnet-5": "global.anthropic.claude-sonnet-5",
"claude-opus-5": "global.anthropic.claude-opus-5"
}
},
"metered_failover": {
"window_seconds": 60,
"min_failures": 3
}
}primary.provider and secondary.provider can each be oauth-passthrough, anthropic-api-key, or bedrock — neither slot is tied to a specific vendor. primary.failover_strategy is subscription-limit for the standard Max-plus-Bedrock setup described in this post, where only Anthropic’s own subscription-exhaustion headers trigger failover and a bare 429 never does; metered-failures for the no-subscription setup, where a sliding-window failure count triggers failover instead; or none to disable overflow. metered_failover.window_seconds and min_failures control that sliding window — ordinary 4xx errors like a bad key or a malformed request never count toward it, since routing to the secondary would not fix them anyway. Model IDs on Bedrock change over time, so keep model_map aligned with whatever Claude models are actually enabled in your Bedrock account.
17.6 Worked example: Claude Max primary, Together AI / GLM 5.3 as the failover
The secondary does not have to be Bedrock. It can be any OpenAI-compatible chat-completions endpoint, and Together AI serving GLM 5.3 is the example the project is verified against, including a genuine streaming tool call. This path does real bidirectional translation between Anthropic’s Messages format and OpenAI’s chat-completions format, including streaming tool calls and parallel tool-call schemas, rather than the byte-for-byte relay used for Bedrock and the two Anthropic-passthrough providers.
Install as usual, then set Together AI as the secondary instead of Bedrock:
export TOGETHER_API_KEY='your-together-api-key'
claude-burst keychain-set --provider together
claude-burst configure --secondary openai-compatible --secondary-base-url https://api.together.xyz/v1 --secondary-model zai-org/GLM-5.3
claude-burst enableThat leaves ~/.config/claude-burst/config.json looking like this — Claude Max stays primary exactly as before, only the secondary changes:
{
"listen": "127.0.0.1:7777",
"reset_grace_seconds": 10,
"unknown_reset_seconds": 300,
"response_header_timeout_seconds": 60,
"max_request_mb": 128,
"primary": {
"provider": "oauth-passthrough",
"base_url": "https://api.anthropic.com",
"failover_strategy": "subscription-limit"
},
"secondary": {
"provider": "openai-compatible",
"base_url": "https://api.together.xyz/v1",
"model": "zai-org/GLM-5.3"
}
}The routing behaviour is otherwise identical to the Bedrock case: Claude Max serves everything until Anthropic’s own subscription-exhaustion headers reject a request, and only then does Claude Burst fail over, this time translating the request into Together’s chat-completions format and translating the streamed GLM response back into Anthropic’s SSE event sequence, so Claude Code never has to know the model underneath changed.
One thing does not carry over on this path: images and documents in message content, Anthropic’s extended-thinking blocks in history, and prompt-caching cache_control hints are dropped rather than translated, since none have a real equivalent on a generic OpenAI-compatible endpoint. Ordinary coding-agent traffic is overwhelmingly text and tool-use, so in practice this rarely matters, but it is worth knowing before relying on GLM 5.3 as a burst target for a workload that leans heavily on images or long cached context.
A dual-account approach was considered instead of a second vendor entirely: log in as a second, work Claude account and fail over between two Max subscriptions rather than to a different model. It was investigated in enough detail to know how it would have to work, and rejected. Making it work would mean reading and independently refreshing a live Claude Code OAuth credential through an undocumented endpoint, which is exactly the pattern that has gotten other third-party tools blocked by Anthropic, and exactly the kind of workaround the earlier sections of this post argue against. Claude Burst treats a rejected request as a real stop, not an obstacle to route around, and that held here too.
17.7 Keeping Remote Control: transparent intercept mode
Claude Code disables Remote Control the moment ANTHROPIC_BASE_URL names anything other than api.anthropic.com — a check on the literal value of that variable, not on where the traffic actually ends up. The default setup described above sets exactly that variable, so turning the gateway on costs you that feature.
Transparent mode avoids the trade by getting into the path a level lower than Claude Code’s own settings, at DNS: /etc/hosts points the hostname at the gateway, and the gateway terminates TLS with a locally generated certificate authority trusted only on this one machine. Claude Code believes it reached Anthropic directly, because as far as its own configuration is concerned, it did. Remote Control keeps working.
claude-burst configure --intercept-mode transparent
claude-burst enable # generates the CA, trusts it, prints the one sudo step left
sudo scripts/transparent-root.sh installThe honest trade is blast radius. Base-url mode’s failure mode is scoped to one user’s Claude Code. Transparent mode’s is not: while that /etc/hosts entry exists, every process on the machine that talks to that hostname goes through the gateway, so if the gateway is down, Anthropic is unreachable machine-wide, not just in one terminal. The install step refuses to run unless the gateway already answers its health check, and verifies the redirect actually works before it ever touches /etc/hosts; removal reverses that ordering, undoing /etc/hosts first.
| base-url (default) | transparent | |
|---|---|---|
| Remote Control | disabled | works |
| Root required | no | once, for /etc/hosts and the packet filter |
| Certificates | none | a local CA, trusted only on this machine |
| Blast radius | this user’s Claude Code | every process on the machine |
There is one sharp edge worth naming: once /etc/hosts maps that hostname to the gateway, the mapping applies to the gateway’s own outbound requests too, so a naive resolver would have the gateway call itself, forever. It resolves that one intercepted hostname over DNS-over-HTTPS instead, which never consults /etc/hosts, while leaving the certificate’s expected hostname alone so verification is unchanged. Undo is one command, safe to run any time, idempotent even if nothing was installed:
sudo scripts/transparent-root.sh remove17.8 The admin panel, and forcing the secondary on purpose
A subscription primary only fails over on a genuine exhaustion signal, and that cannot be provoked on demand, which means the secondary path can sit completely unexercised for weeks — the worst possible moment to discover it is misconfigured. One command routes inference to the secondary on purpose for a window, and another returns to the primary immediately:
claude-burst force-secondary --minutes 15 # inference goes to the secondary
claude-burst reset # back to the primary immediatelyThe forced state is recorded as such, so neither the metrics file nor status ever imply Anthropic reported a limit it did not.
Alongside the CLI there is now a small local control panel, running on 127.0.0.1:7788. It shows the current route, usage, the last fifty requests, and the last twenty upstream responses with their headers — the anthropic-ratelimit-* ones are what actually decide failover, so “why didn’t it fail over” becomes something you can look at rather than something you reconstruct from log lines. It can force or clear overflow, change the secondary model and failover strategy, and revert Claude Code to the stock endpoint, without a terminal. It binds loopback only and has no login of its own, which is not automatically the same as safe — a malicious page can still point a hostname it controls at 127.0.0.1 and try to drive it from your own browser, so every request is checked against the Host header, and every action that changes state requires a header a cross-origin request cannot attach without a preflight the server never answers.
In transparent mode specifically, the panel also now always shows the one command that undoes the machine-wide redirect, since that step needs root and nothing here can run it for you. It turns red and repeats that same command if it ever detects the dangerous half-state: the redirect active but the certificate no longer trusted, meaning every request to Anthropic on that Mac is currently failing. That state is not hypothetical. It showed up directly while building the deploy tooling for this project, when a swap script’s “safe” fallback for base-url mode — point Claude Code straight at Anthropic before touching anything risky — turned out to strip certificate trust without removing the redirect in transparent mode, because the two modes have genuinely different resting states and code written for one did not silently hold for the other. The panel exists so that the one command out of that hole is never more than a glance away.
17.9 Running the tests
go test ./... -race
go vet ./...Both run automatically on every push and pull request through .github/workflows/test.yml.
17.10 Uninstalling
./install.sh uninstallThis removes the LaunchAgent and the binary, and deliberately leaves metrics, configuration, and the Keychain secret in place, so reinstalling later does not silently wipe your history.
17.11 Where the logs and metrics land
Everything Claude Burst writes goes under ~/.config/claude-burst/, and both files are metadata only: prompts, source code, tool inputs, and model outputs are never written to disk. metrics.jsonl is one structured line per request, with the route, model, HTTP status, latency, token usage, estimated API-equivalent cost, and, on a failover, the subscription limit claim and reset timestamp. claude-burst.log is plain text, with a start and done line for every request sharing the same short request id, plus a named stage for anything that failed, whether that is reading the body, calling Bedrock, loading the Keychain key, or a panic recovered mid-request.
Source code
Claude Burst is open source: github.com/andrewbakercloudscale/claude-burst.
The live cost and usage panel referenced in the opening section, the tool that made the original pricing gap visible turn by turn, is also open source: github.com/andrewbakercloudscale/ai-agent-cost-usage-panel.
References
- Anthropic, Plans and Pricing: https://claude.com/pricing
- Anthropic, What is the Max plan?: https://support.claude.com/en/articles/11049741-what-is-the-max-plan
- Anthropic, Use Claude Code with your Pro or Max plan: https://support.claude.com/en/articles/11145838-use-claude-code-with-your-pro-or-max-plan
- Anthropic, Other LLM gateways and subscriptions: https://code.claude.com/docs/en/llm-gateway
- Anthropic, Gateway protocol reference: https://code.claude.com/docs/en/llm-gateway-protocol
- Anthropic, Claude Code error reference: https://code.claude.com/docs/en/errors
- Anthropic, Consumer Terms of Service: https://www.anthropic.com/legal/consumer-terms
- Anthropic, Acceptable Use Policy: https://www.anthropic.com/legal/aup
- Anthropic, Claude Code Legal and Compliance: https://code.claude.com/docs/en/legal-and-compliance
- Anthropic, Claude Code on Amazon Bedrock: https://code.claude.com/docs/en/amazon-bedrock
- AWS, Inference using the Anthropic Messages API: https://docs.aws.amazon.com/bedrock/latest/userguide/inference-messages-api.html
- AWS, Use an Amazon Bedrock API key: https://docs.aws.amazon.com/bedrock/latest/userguide/api-keys-use.html