Claude Code Third-Party API Setup: ANTHROPIC_BASE_URL Guide & Troubleshooting
Claude Code Third-Party API Setup: ANTHROPIC_BASE_URL Guide & Troubleshooting
By default, Claude Code sends every request to Anthropic's official API. When the official route is unreliable from your network, or you want one place to manage keys, billing, and model switching across providers, pointing Claude Code at an Anthropic-compatible third-party endpoint is the cleanest fix. This guide covers exactly what to change, how to verify it works, and where to look when something breaks.
The 30-second version
Two settings do all the work: point ANTHROPIC_BASE_URL at a compatible endpoint and set ANTHROPIC_API_KEY to that endpoint's key. Then run claude --print "say hi" to verify.
First, understand: Claude Code is a client
Definition: Claude Code reads a small set of environment variables to decide where requests go, which key authenticates them, and which model runs. As long as the target endpoint implements the Anthropic Messages API request/response format, Claude Code works with it exactly as it works with the official API — tool calling, streaming, and multi-turn sessions depend on the endpoint's compatibility.
Configuring a custom base URL is a documented capability, not a hack. EXAIV exposes an Anthropic-compatible endpoint; see the official setup page for the short version of this guide.
The environment variables that matter
| Variable | Purpose | Notes |
|---|---|---|
ANTHROPIC_BASE_URL | Where requests are sent | Root of the compatible endpoint (EXAIV: https://exaiv.com/api/ai/v1/anthropic) |
ANTHROPIC_API_KEY | API key | Sent as the x-api-key header; used by Anthropic and most gateways including EXAIV |
ANTHROPIC_AUTH_TOKEN | Bearer token | Sent as Authorization: Bearer; use only if the endpoint requires it |
ANTHROPIC_MODEL | Default model | A model ID the endpoint supports, e.g. claude-opus-5-5 |
ANTHROPIC_DEFAULT_SONNET_MODEL / ANTHROPIC_DEFAULT_HAIKU_MODEL | Tier mapping | Routes Claude Code's background small-task requests to a model your endpoint actually has |
The most common failure
Most connection failures are not about endpoint compatibility — the variables simply never reached the current shell: a different terminal window, the wrong config file, or two settings overriding each other. Always start troubleshooting at the environment variables.
Method 1: settings.json (recommended, persistent)
Claude Code reads environment variables from ~/.claude/settings.json. This applies to every session and is the easiest format to standardize across a team. Example for EXAIV:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"env": {
"ANTHROPIC_BASE_URL": "https://exaiv.com/api/ai/v1/anthropic",
"ANTHROPIC_API_KEY": "YOUR_EXAIV_API_KEY",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1"
},
"model": "claude-opus-5-5"
}
Restart claude after saving. To scope the override to one project, put the same structure in .claude/settings.json at the project root.
Method 2: temporary environment variables (quick test)
No file changes needed — export in your current shell:
export ANTHROPIC_BASE_URL="https://exaiv.com/api/ai/v1/anthropic"
export ANTHROPIC_API_KEY="YOUR_EXAIV_API_KEY"
# Minimal verification
claude --print "say hi"
If it responds, the endpoint is live. For persistence, the two exports can go into ~/.zshrc or ~/.bashrc — but that affects every claude invocation. If you also hold an official subscription, prefer project-level settings.json so you don't accidentally spend third-party credits.
Where to find available models
The endpoint decides which models exist. EXAIV's full catalog (Claude, GPT, Gemini, DeepSeek, Kimi and more) is listed on the models page; switch models in Claude Code via ANTHROPIC_MODEL or the in-session /model command.
Troubleshooting: check in a fixed order
| Symptom | Check first |
|---|---|
| 401 unauthorized | Is ANTHROPIC_API_KEY exported in the current shell? Typos or stray spaces in the key? |
| 403 forbidden | Key disabled, or lacks permission for that model |
| 404 not found | Is the base URL path complete (EXAIV requires /api/ai/v1/anthropic)? Does the model ID exist on the endpoint? |
| 429 rate limited | Endpoint throttling — reduce concurrency or retry later |
| Connection timeout | Local proxy or firewall blocking; verify on another network |
Debugging order
Don't blame Claude Code first. Check in order: environment variables → base URL → key → model ID → network. Nine out of ten issues live in the first two layers.
Who benefits from a third-party setup
Not every Claude Code user needs this. Three scenarios where the payoff is clearest:
Users on unstable official routes. In some regions, reaching the official endpoint means frequent timeouts — and a mid-session stall while coding is a real productivity killer. Routing through a nearby compatible gateway shortens the path and noticeably improves session continuity.
Heavy users. Claude Code consumes far more tokens than ordinary chat — every tool call and file read counts against context. If you use it daily, pay-as-you-go pricing at a lower unit rate can make a meaningful monthly difference. Estimate the gap with your real usage rather than trusting anyone's marketing numbers, ours included.
Teams standardizing on one entry point. When a team runs Claude Code, Cursor, and internal scripts side by side, pointing every tool at one gateway with one set of keys and one bill is far easier to budget than separate accounts per tool. EXAIV serves both OpenAI-compatible and Anthropic-compatible endpoints, so one key covers tools on either protocol.
How pricing works: start with the trial pack
EXAIV bills in credits: you buy a credit pack up front, usage is deducted per call at each model's rate, and there is no subscription. The entry tier is the smallest pack listed on the pricing page — enough for a real validation loop:
- Register and generate an API key in the console
- Configure Claude Code as described above
- Run your daily tasks for an hour or two and watch the balance curve in the console
- Extrapolate to a monthly estimate, then decide whether to move up a tier
Each model has its own rate, so exact prices live on the pricing page in real time — which is also why this article never quotes a fixed per-call number: prices follow official changes, and the live page is always the accurate one.
Team adoption: one config, zero drift
The biggest team pitfall is everyone configuring things differently. What works:
Commit a settings template to the repo. Keep a keyless .claude/settings.example.json in the project root; new members copy it and fill in their own key. Five minutes to onboard.
Issue keys per person, never shared. Each member uses their own API key with usage visible in the console. Problems are easy to attribute, and offboarding means revoking one key without touching anyone else.
Use a wrapper script to separate contexts. If team members also hold official subscriptions, a small alias script that points at project-level config prevents official and third-party sessions from bleeding into each other's quotas.
Security basics
An API key is a wallet credential. Four ground rules:
- Keys never enter git. Add real config files to version-control ignore lists; only keyless templates belong in the repo
- Rotate on a schedule. Regenerate keys in the console periodically and revoke old ones; rotate immediately if you suspect a leak
- Least privilege. Don't paste keys into CI logs, frontend code, or chat threads
- Watch for anomalies. If balance burn rate deviates from your norm, revoke the key first and investigate after
Setup quick reference by OS
| macOS / Linux | Windows | |
|---|---|---|
| Settings file | ~/.claude/settings.json | %USERPROFILE%\.claude\settings.json |
| Temp variable | export ANTHROPIC_BASE_URL=... | $env:ANTHROPIC_BASE_URL="..." (PowerShell) |
| Persist in shell | ~/.zshrc / ~/.bashrc | System environment variables panel |
| Verify | claude --print "say hi" | same command |
Everything else — model mapping, troubleshooting order, security practices — is identical across platforms.
Why tier mapping matters more than you think
Claude Code doesn't only call your chosen main model. In the background it fires smaller requests — summarizing tool output, generating commit messages, handling quick lookups — and those requests are tagged as Sonnet-tier or Haiku-tier. If your endpoint doesn't have the exact default model for those tiers, the calls fail or fall back unpredictably.
That's what ANTHROPIC_DEFAULT_SONNET_MODEL and ANTHROPIC_DEFAULT_HAIKU_MODEL solve: they reroute tier-tagged requests to a model your endpoint actually serves. Setting both to your main model is the simplest reliable pattern; mapping Haiku-tier to a cheaper model is a common optimization once everything runs stably. The same logic applies inside a gateway: check the models page for what exists, then map tiers to models you know are there.
Timeouts and network tuning
Two variables solve most connectivity complaints:
API_TIMEOUT_MS— long agent turns can legitimately take minutes on complex tasks; a too-short client timeout kills otherwise-successful requests. If you see truncated turns without error output, raise it.- Proxy overlap — if your shell also sets
HTTP_PROXY/HTTPS_PROXY, requests may detour through a local proxy before reaching the gateway. When Base URL is correct but connections still fail, test with the proxy variables unset before changing anything else.
Neither variable is required by default — they're the first two knobs to turn when the setup is right but the network path is wrong.
A real troubleshooting walkthrough
Here is the most common failure pattern, end to end, so you can pattern-match your own:
A developer edits settings.json, runs claude --print "say hi", and gets 401 authentication_error. The instinct is to suspect the endpoint. Working the checklist instead:
- Environment variables — the key in settings.json is set, but the developer had also exported an old
ANTHROPIC_API_KEYin the current shell earlier that day. Shell environment variables take precedence over settings.json; the stale key was being sent.unset ANTHROPIC_API_KEYand retry — the call now returns text - Base URL — nothing to fix; it was correct from the start
- Key — the key itself was valid all along; it was simply being shadowed
- Model ID — the configured main model exists on the endpoint; but a background task referencing the default Sonnet model fails. Mapping
ANTHROPIC_DEFAULT_SONNET_MODELto the same model as the main one removes the last error - Network — never reached; the issue was layers one and three
Total time from frustration to working setup: about four minutes, once the checklist replaced guesswork. The lesson generalizes: each layer either works or points to the next — never debug two layers at once.
FAQ
Does Claude Code behave differently on a third-party API?
ANTHROPIC_API_KEY vs ANTHROPIC_AUTH_TOKEN — which one?
Is using a third-party endpoint allowed?
Anything different on Windows?
What happens when credits run out?
Can I keep an official subscription alongside a third-party setup?
After setup, can I switch to other models?
Can different projects use different keys?
Related reading
- Claude Code setup page — the on-site quick config
- Anthropic Messages API reference — request/response format
- Pricing — live model prices