Docs
ANTHROPIC_BASE_URL
The environment variable that points Claude Code and the Anthropic SDKs at an endpoint other than api.anthropic.com — the full variable reference, per-client setup, and the two traps that produce almost every failure.
ANTHROPIC_BASE_URL tells the Anthropic SDKs and Claude Code which host to send API requests to, replacing the default https://api.anthropic.com. Set it to an origin with no path — the client appends /v1/messages itself — and pair it with ANTHROPIC_AUTH_TOKEN, which becomes the Authorization: Bearer header.
# The origin only — no trailing /v1, no trailing slash.
export ANTHROPIC_BASE_URL=https://api.kunavo.com
export ANTHROPIC_AUTH_TOKEN=sk-kn-...Open a new terminal afterwards: Claude Code and the SDKs read these variables at process start, so a session that was already running keeps the old endpoint.
https://api.kunavo.com/v1 produces requests to /v1/v1/messages and every call returns 404. The OpenAI SDK uses the opposite convention and does want /v1 in its base_url — that difference is the single most common configuration mistake here.Every variable, and what it does
The full list Claude Code reads is in Anthropic's environment-variable reference. These are the ones that matter when you are redirecting the endpoint.
| Variable | Value | What it controls |
|---|---|---|
ANTHROPIC_BASE_URL | https://api.kunavo.com | The origin every request goes to. No path, no trailing slash. |
ANTHROPIC_AUTH_TOKEN | sk-kn-… | Credential sent as Authorization: Bearer. This is the one a gateway wants. |
ANTHROPIC_API_KEY | sk-ant-… | Credential sent as the x-api-key header, the form api.anthropic.com expects. Set this one OR the token above, not both. |
ANTHROPIC_MODEL | claude-sonnet-4-6 | The main model Claude Code uses for the conversation. |
ANTHROPIC_DEFAULT_HAIKU_MODEL | claude-haiku-4-5 | The cheap model Claude Code uses for its own background calls — the single biggest cost lever after caching. |
GET /v1/models.Per-client setup
Claude Code
Put the exports in the shell profile Claude Code starts from, then open a new terminal. Nothing about the install or the workflow changes.
# ~/.zshrc (or ~/.bashrc) — applies to every Claude Code session.
export ANTHROPIC_BASE_URL=https://api.kunavo.com
export ANTHROPIC_AUTH_TOKEN=sk-kn-...
# Optional: pin which models Claude Code reaches for.
export ANTHROPIC_MODEL=claude-sonnet-4-6
export ANTHROPIC_DEFAULT_HAIKU_MODEL=claude-haiku-4-5Run /status inside Claude Code to confirm which endpoint the current session is using. Step-by-step, including where to generate the key: set an API key in Claude Code.
Anthropic SDK (Python / TypeScript)
The SDKs read the same environment variables, and both settings can also be passed to the constructor — useful when one process talks to more than one endpoint.
from anthropic import Anthropic
# The Anthropic SDK appends /v1/messages, so pass the origin — not .../v1.
client = Anthropic(
base_url="https://api.kunavo.com",
auth_token="sk-kn-...", # sets the Authorization: Bearer header
)
msg = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=512,
messages=[{"role": "user", "content": "Say hi"}],
)
print(msg.content[0].text)OpenAI SDK — the other convention
If your code already speaks OpenAI, you do not need ANTHROPIC_BASE_URL at all. Point base_url at the OpenAI-compatible path — with the /v1 this time — and call the same Claude models through /v1/chat/completions.
from openai import OpenAI
# The OpenAI SDK is the other convention: it wants the /v1 in the base_url.
client = OpenAI(
api_key="sk-kn-...",
base_url="https://api.kunavo.com/v1",
)
r = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{"role": "user", "content": "Say hi"}],
)
print(r.choices[0].message.content)Cline, Roo Code, Kilo Code, Cursor
Editor agents mostly expose the same two settings in their own UI rather than through the environment: a "base URL" or "custom endpoint" field and an API-key field. The rules do not change — origin without /v1 for an Anthropic-style provider, and the key in the API-key field. Per-client walkthroughs: Cline, Roo Code, Kilo Code.
Check that it worked
One curl proves the base URL and the credential at the same time. A 200 with a JSON body means both are right.
# 200 and a JSON body means the base URL and the token are both right.
curl -sS https://api.kunavo.com/v1/messages \
-H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
-H "content-type: application/json" \
-d '{"model":"claude-haiku-4-5","max_tokens":16,
"messages":[{"role":"user","content":"ping"}]}'
# In Claude Code, /status shows the endpoint the session is actually using.When it does not work
| Symptom | Cause | Fix |
|---|---|---|
| 404 on every request | /v1 left on the end of ANTHROPIC_BASE_URL | Set the origin only. The client appends /v1/messages. |
| 401 / invalid x-api-key | Credential set as ANTHROPIC_API_KEY when the endpoint authenticates with bearer tokens | Use ANTHROPIC_AUTH_TOKEN instead — the difference in full |
| Still hitting api.anthropic.com | Variables exported after the session started, or set in a profile that shell does not read | Open a new terminal; confirm with echo $ANTHROPIC_BASE_URL in the same shell that launches the client. |
| 404 model_not_found | Model id the endpoint does not serve | Set ANTHROPIC_MODEL to an id from GET /v1/models |
| Claude Code says the credit balance is too low | Requests are reaching the endpoint and being billed to the key, not the subscription | Expected — top up, or unset the token to return to the plan. See insufficient credit |
What this does to a Pro or Max subscription
While a credential variable is set, Claude Code bills the key rather than the logged-in subscription: plan limits stop applying and usage is charged to whoever owns the key. The subscription itself is untouched — remove the variable, open a new terminal, and Claude Code goes back to the plan. The two never combine, and the cost arithmetic between them is in Claude Code pricing.
Next
FAQ
What is ANTHROPIC_BASE_URL?
ANTHROPIC_BASE_URL is the environment variable that tells the Anthropic SDKs and Claude Code which host to send API requests to, instead of the default https://api.anthropic.com. Set it to an origin with no path — the client appends /v1/messages itself — and pair it with ANTHROPIC_AUTH_TOKEN, which becomes the Authorization: Bearer header. Any Anthropic-compatible endpoint works; on Kunavo the value is https://api.kunavo.com.
Should ANTHROPIC_BASE_URL include /v1?
No. ANTHROPIC_BASE_URL takes the origin only — https://api.kunavo.com, not https://api.kunavo.com/v1 — because the Anthropic SDKs and Claude Code append the /v1/messages path themselves. Including /v1 produces requests to /v1/v1/messages, which return 404. The OpenAI SDK follows the opposite convention and does want /v1 in its base_url, which is why the same gateway is written two different ways depending on which client is calling it.
What is the difference between ANTHROPIC_AUTH_TOKEN and ANTHROPIC_API_KEY?
ANTHROPIC_AUTH_TOKEN sends the credential as an Authorization: Bearer header, while ANTHROPIC_API_KEY sends it as the x-api-key header that api.anthropic.com expects. A gateway that authenticates with bearer tokens needs ANTHROPIC_AUTH_TOKEN; setting ANTHROPIC_API_KEY instead is the most common cause of a 401 after changing ANTHROPIC_BASE_URL. Set one, not both — when both are present the behaviour depends on the client version.
How do I set a custom base URL in Claude Code?
Export ANTHROPIC_BASE_URL and ANTHROPIC_AUTH_TOKEN in the shell profile Claude Code starts from (~/.zshrc or ~/.bashrc), then open a new terminal so the variables are inherited. Claude Code reads them at startup, so a session that was already running keeps the old endpoint. Run /status inside Claude Code to confirm which endpoint the current session is using.
Does setting ANTHROPIC_BASE_URL disable my Claude Pro or Max subscription?
While a credential variable such as ANTHROPIC_AUTH_TOKEN is set, Claude Code bills the key rather than the logged-in subscription, so Pro and Max plan limits no longer apply and usage is charged to whoever owns the key. The subscription itself is unaffected and unset — remove the variable and open a new terminal, and Claude Code goes back to the plan.