Use Claude Code with your own API endpoint
Claude Code can talk to any service that speaks the Anthropic Messages API — two environment variables and it points somewhere else. But "compatible" is doing a lot of work in that sentence: some endpoints answer a test request and still fall over the moment an agent starts working. Here is what to check, in the order that saves you time.
1. The setup is two variables
ANTHROPIC_BASE_URL is the root of the API — Claude Code appends /v1/messages itself, so do not add the path yourself.
export ANTHROPIC_BASE_URL="https://your-endpoint.example.com"
export ANTHROPIC_AUTH_TOKEN="your-key"
claude
On Windows PowerShell the same two variables are set with $env::
$env:ANTHROPIC_BASE_URL = "https://your-endpoint.example.com"
$env:ANTHROPIC_AUTH_TOKEN = "your-key"
claude
ANTHROPIC_API_KEY instead of ANTHROPIC_AUTH_TOKEN. Try the other name before you start debugging the endpoint.
2. What the endpoint actually has to support
A chatbot that answers one question proves almost nothing. Claude Code is an agent, and it needs all of these:
- Streaming (SSE) — responses arrive as
message_start/content_block_delta/message_stopevents. An endpoint that only returns a single JSON body will not work. - Tool use — every real task means tool calls. The response must be able to return
tool_useblocks with a name and aninputobject. - System prompts — Claude Code sends a long system prompt. An endpoint that silently drops it will produce a model that ignores its instructions.
- Large
max_tokens— the agent asks for long completions. If your provider caps output far below what it advertises, tasks get cut off mid-edit.
Two things are not required: prompt caching and returned thinking blocks. Both improve cost and quality, but their absence does not break the client.
3. Verify it in one request
Before touching your environment variables, ask the endpoint directly. This is the smallest request that exercises the whole path:
curl https://your-endpoint.example.com/v1/messages \
-H "x-api-key: $YOUR_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "your-model-id",
"max_tokens": 128,
"messages": [{"role": "user", "content": "Say hello in one sentence."}]
}'
A working endpoint answers with Anthropic's shape — type: "message", a content array, stop_reason, and usage.input_tokens / usage.output_tokens. If you get an OpenAI-style chat.completion object instead, the endpoint is not speaking the Anthropic protocol and Claude Code will not work with it.
Then test the two things that actually break agents — add "stream": true to the body and confirm you receive SSE events, and add a "tools" array and confirm you get back a tool_use block.
4. The part most guides leave out: token burn
An agent resends the context on every turn. One ordinary task — read a file, edit it, run the tests, fix the failure — can move several hundred thousand tokens, and a long session can move millions. Two consequences:
- Size the plan, not the price per token. A cheap per-million rate on a plan that runs out in three days is more expensive than a bigger plan that lasts the month.
- Insist on a per-request usage log. If you cannot see input, output and cache tokens for each call, you cannot tell a model problem from a metering problem.
5. A checklist for choosing the endpoint
- Speaks the Anthropic Messages API at
/v1/messages(or an OpenAI-compatible API if your client supports that instead) - Streams, supports tool use, and passes system prompts through
- Takes a card — no separate account with the upstream model provider
- Shows per-request token usage, including cache hits and misses
- Issues an invoice and handles tax, if you expense the cost
- Lets you cancel from a console instead of emailing someone
Where Thelsy fits
We serve an Anthropic-compatible endpoint on the same host as our OpenAI-compatible one, so Claude Code runs on deepseek-flash through a monthly card subscription. Streaming, tool use and system prompts are all supported and tested; the usage log itemises input, output and cache tokens per request. When a plan's included tokens run out, calls stop — there is no automatic overage charge.