cd /news/ai-tools/migrating-claude-code-to-a-custom-ba… Β· home β€Ί topics β€Ί ai-tools β€Ί article
[ARTICLE Β· art-23152] src=dev.to pub= topic=ai-tools verified=true sentiment=↑ positive

Migrating Claude Code to a custom backend in 2 lines (and what to actually watch for)

Anthropic's Claude Code can be redirected to any compatible backend using a single environment variable, `ANTHROPIC_BASE_URL`, enabling caching, rate-limit pooling, multi-vendor routing, and audit logging without code changes. A developer demonstrated that a proxy server can inject `cache_control` markers server-side to cut costs by 60-80% on long sessions, and round-robin across multiple API keys to avoid rate limits. However, the proxy must pass through SSE chunks without buffering and preserve critical headers like `anthropic-version` and `anthropic-beta` to prevent silent feature breakage.

read5 min publishedJun 6, 2026

TL;DR: Claude Code's ANTHROPIC_BASE_URL

env var lets you redirect every request to any compatible backend in one shell line. Almost no one does it, but it unlocks caching, rate-limit pooling, multi-vendor routing, audit logging, and billing routing without rewriting any code. Here's the 2-line setup, the things that quietly break, and the production checklist for actually running it.

export ANTHROPIC_BASE_URL=https://your-proxy.example.com
export ANTHROPIC_API_KEY=your-key
claude

That's it. The Anthropic SDK (which Claude Code is built on) doesn't care where it's sending requests, as long as the response comes back in Anthropic Messages format. It'll append /v1/messages

automatically, forward all your anthropic-version

and anthropic-beta

headers, and stream SSE the same way.

Same trick works with Cursor, Cline, Continue, and anything else that builds on the Anthropic SDK.

I've found five patterns that justify a custom backend:

Anthropic's prompt cache feature requires manual cache_control

markers that most teams skip. A proxy can inject them server-side on every system message. For a Claude Code session with a 20-30K-token system prompt and 50+ turns, this cuts your bill by 60-80%.

Most teams have 3-5 API keys spread across projects. Without a proxy, each is rate-limited independently β€” you can hit 429 on one while another sits idle. A proxy can round-robin across keys, exposing one virtual key with the combined rate budget.

Want to route claude-haiku-4-5

calls to one provider and claude-opus-4-7

calls to another (maybe one offers Haiku throughput discounts)? A proxy inspects the model

field and routes accordingly. Your Claude Code config doesn't change.

Claude Code makes a lot of requests. Without instrumentation, you have no idea what each session cost. A proxy can log per-request metadata (model, tokens, latency, session id) to a warehouse.

Different team members hitting different cost centers? A proxy can map API keys to billing tags and forward usage to finance.

The 2-line setup works for the happy path. In practice, here's what bites you.

Anthropic returns chunked SSE for stream: true

. If your proxy buffers responses or doesn't flush each chunk immediately, you'll see massive perceived latency β€” Claude Code will spin while waiting for the full response.

Fix: pass through SSE chunks without buffering. In Caddy, that means flush_interval -1

. In Cloudflare Workers, use TransformStream

with explicit .write()

per chunk. In Node, set noDelay: true

on the response socket.

Anthropic's SDK sends headers like:

anthropic-version

anthropic-beta

(for prompt cache, batches, etc.)x-api-key

(auth)x-stainless-*

(SDK telemetry)If your proxy strips any of these before forwarding to the real upstream, certain features break silently:

anthropic-version

β†’ SDK gets default-version response which may not match its expectationsanthropic-beta

β†’ prompt cache headers ignored, you wonder why caching isn't workingx-stainless-*

β†’ harmlessRule of thumb: forward everything except host

and authorization

(since you're rewriting those).

Claude Code uses tool calling heavily. A typical session has 30-50 tool call rounds, each one a separate API call with the full conversation history.

If your proxy is rate-limited at 60 RPM per source IP, a single Claude Code session can blow through it in 30 seconds.

Fix: rate-limit per API key, not per source IP. And budget for high burst rates (200+ RPM during heavy tool-call sessions).

If you want to inject cache_control

or rewrite request bodies, you have to parse the JSON, modify, re-serialize. Be careful: large requests (50K+ tokens of context as JSON-encoded strings) take noticeable CPU time to parse.

Minimal injection in Node:

const body = JSON.parse(rawBody);

// Inject cache_control on the first system message
if (body.system && typeof body.system === 'string') {
  body.system = [{
    type: 'text',
    text: body.system,
    cache_control: { type: 'ephemeral' },
  }];
}

const newRawBody = JSON.stringify(body);

For Claude Code's typical traffic this adds <5ms per request. For very large workloads, consider stream-parsing.

Anthropic sends error

SSE events mid-stream when something fails (rate limit, content filter, etc.). Most naive proxies forward the body as opaque bytes, which works. If your proxy tries to be "smart" and parse the SSE, you have to handle error events without breaking the connection.

The safe path: don't parse SSE in your proxy unless you absolutely have to.

If you're building this proxy yourself:

host

/authorization

That's not "2 lines" anymore. The 2-line part is the SDK config; the checklist is the actual cost of running it in production.

When you put a proxy in front of Claude Code, you get observability for free. You can see:

Anthropic's dashboard tells you the bill. Your proxy tells you why. For any team running Claude Code at scale, that's often more valuable than the cost optimization itself.

A few cases where a custom backend is more trouble than it's worth:

claude

once a day β€” direct API is fineThe break-even point is roughly:

Below that, just use the real Anthropic API and pocket the engineering time.

I built MidRelay precisely because this checklist took 6 weeks to get right and I figured other teams shouldn't repeat it. Hosted proxy with both Anthropic and OpenAI surfaces, prompt cache injection on by default, per-key usage logs, CORS enabled for browser clients.

Pointing Claude Code at it is the 2-line setup at the top of this post.

But honestly: the techniques here work whether you use MidRelay, build your own, or pick any of the other gateways. The interesting thing is almost nobody knows you can point Claude Code at a custom backend, even though Anthropic explicitly documented it. If this post does nothing else but make you realize that capability exists, that's worth your reading time.

If you've built something similar, drop a comment with what bit you in production β€” I'm collecting patterns for a follow-up post on multi-vendor LLM routing.

── more in #ai-tools 4 stories Β· sorted by recency
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain β€” perfect for shipping the agent you just read about.

$git push zahid main
β†’ Live at https://your-agent.zahid.host βœ“
Get free account β†’ Pricing
from €0/mo Β· no card required
LIVE [news/migrating-claude-cod…] indexed:0 read:5min 2026-06-06 Β· β€”