Anthropic SDK custom base URL: point Python and Node at any Claude API
The official Anthropic SDK doesn't just work with Claude's own endpoint — it works with anything that speaks the same /v1/messages protocol. apillms exposes an Anthropic-compatible base URL, so you can keep using the SDK you already know and switch models (or providers) without rewriting your code.
This guide shows how to configure the Anthropic SDK in Python and Node.js to call apillms, including system prompts, multi-turn conversations, streaming, cURL, and basic troubleshooting.
Why use the Anthropic SDK against a different base URL
If you've already built an app around anthropic.messages.create(), you don't need a new client library to try other models. The Anthropic SDK lets you override the base URL and the API key it sends, so the same code path can hit apillms instead of api.anthropic.com. From there you get access to Claude models plus GPT, DeepSeek and Kimi models through the same request shape.
This is different from the OpenAI-compatible route covered in the Python quickstart and Node quickstart — those use /v1/chat/completions. This post is specifically about the Anthropic-style /v1/messages endpoint and SDK.
Get your API key
Each apillms account has exactly one API key, created automatically when you sign up. Log in at /login, open /keys, and click Show key to copy it. New accounts start with 50 free credits, so you can run the examples below without adding a payment method first.
If you ever think the key is exposed, use Roll key on the same page — this disables the old key immediately and issues a new one. Update any script or environment variable that referenced the old key before you roll it, or requests will start failing with an authentication error.
Base URL and endpoint
For the Anthropic SDK, the base URL is https://apillms.com — note there's no /v1 suffix, unlike the OpenAI-compatible base URL. The SDK appends the path itself, sending requests to /v1/messages.
| Protocol | Base URL | Path used by SDK |
|---|---|---|
| Anthropic-compatible | https://apillms.com | /v1/messages |
| OpenAI-compatible | https://apillms.com/v1 | /chat/completions |
Mixing these up is the most common setup mistake: if you add /v1 to the Anthropic SDK's base_url, the SDK will end up calling /v1/v1/messages and the request will fail.
Python example
Install the official SDK and point it at apillms:
pip install anthropic
It's a good idea to keep the key out of your source code. Export it as an environment variable:
export APILLMS_KEY="YOUR_APILLMS_KEY"
import os
import anthropic
client = anthropic.Anthropic(
api_key=os.environ["APILLMS_KEY"],
base_url="https://apillms.com",
)
message = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
messages=[
{"role": "user", "content": "Explain what a base URL override does."}
],
)
print(message.content[0].text)
Swap model for any id on the model list, e.g. claude-opus-5-5, gpt-5.5, deepseek-v4-flash, or kimi-k3 — the same client and code path work across all of them, since the Anthropic /v1/messages shape is model-agnostic on apillms.
Adding a system prompt and multi-turn history
The Anthropic SDK takes the system prompt as a top-level system parameter, separate from the messages array:
message = client.messages.create(
model="claude-sonnet-5",
max_tokens=1024,
system="You are a terse code reviewer. Answer in bullet points.",
messages=[
{"role": "user", "content": "Review this function for bugs."},
{"role": "assistant", "content": "Paste the function and I'll review it."},
{"role": "user", "content": "def add(a, b): return a - b"},
],
)
print(message.content[0].text)
Each call is stateless — if you want a multi-turn conversation, keep appending the user and assistant turns to the messages list yourself, exactly as you would against Anthropic's own API.
Node.js example
npm install @anthropic-ai/sdk
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
apiKey: process.env.APILLMS_KEY,
baseURL: "https://apillms.com",
});
const message = await client.messages.create({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Explain what a base URL override does." }],
});
console.log(message.content[0].text);
Set the environment variable the same way as in Python:
export APILLMS_KEY="YOUR_APILLMS_KEY"
And swap models the same way — only the model string changes, nothing else about the request shape.
Streaming
Both SDKs support streaming the same way they do against the official Anthropic endpoint — just use the streaming helper method. apillms responds with the same event format, so no extra parsing logic is needed.
const stream = await client.messages.stream({
model: "claude-sonnet-5",
max_tokens: 1024,
messages: [{ role: "user", content: "Stream me a haiku." }],
});
for await (const event of stream) {
if (event.type === "content_block_delta") {
process.stdout.write(event.delta.text ?? "");
}
}
In Python the equivalent is the context-manager form:
with client.messages.stream(
model="claude-sonnet-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Stream me a haiku."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
Raw HTTP, if you skip the SDK
If you'd rather call the endpoint directly with cURL:
curl https://apillms.com/v1/messages \
-H "x-api-key: YOUR_APILLMS_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello"}]
}'
This is useful for quickly checking that your key and base URL are correct before wiring them into application code, or for debugging from a server that doesn't have the SDK installed.
Troubleshooting common errors
- 401 / authentication error: the key is wrong, missing, or was rolled on /keys without updating the environment variable. Re-copy the key with Show key and re-export it.
- 404 on the messages path: usually means
/v1was added twice — double-checkbase_urlis exactlyhttps://apillms.comwith no trailing/v1. - Unknown model id: check the spelling against the list on /models; model ids are case-sensitive and change over time as new ones are added.
- Request fails outright: failed requests are not billed, so you can retry freely while debugging without worrying about wasted credits.
Caching and cost
Prompt caching is on automatically with per-user cache keys, and cache reads bill at the lower cache price. For $0.274 per 1M input tokens and $0.046 per 1M cache-read tokens on claude-sonnet-5, a single chat message (1,000 input + 500 output tokens) costs about $0.002, or $2.24 for 1,000 such messages. An agent-style turn with 100,000 cached tokens, 5,000 fresh input tokens and 1,000 output tokens costs about $0.014, or $13.69 for 1,000 such turns. For context, OpenRouter's listed price for the same model is $2 / $10 per 1M input/output tokens — see the live numbers at /compare and estimate your own usage at /pricing.
If you'd rather compare models than prices, gpt-5.5 on apillms costs $0.532 per 1M input tokens and $3.19 per 1M output tokens, with the same chat message costing about $0.004 (so $4.26 for 1,000 messages) — both work through the identical messages.create() call, you only change the model string.
Where this fits with other setups
If you're also running Claude Code against apillms, see Set Up Claude Code with apillms for the dedicated installer. If you want to understand what's driving token usage in agentic workflows, Why Claude Code Burns Tokens and How to Cut the Bill covers that in detail. And if you're deciding which model to call from this SDK in the first place, Claude vs GPT vs DeepSeek vs Grok compares them for coding tasks and cost.
Takeaway: point the Anthropic SDK's baseURL at https://apillms.com, keep your existing messages.create() calls, and swap the model field to try Claude, GPT, DeepSeek or Kimi models without changing your integration.
Try apillms
One API key for Claude, GPT, Grok, DeepSeek and Kimi. OpenAI- and Anthropic-compatible, prompt caching included, pay-as-you-go from $5 with PayPal or card. Credits never expire.
FAQ
Do I need a different SDK to use apillms with Anthropic-style requests?
No. The official Anthropic SDK works as-is — you only need to override the base URL to https://apillms.com and use your apillms API key.
What's the difference between the Anthropic base URL and the OpenAI-compatible one?
The Anthropic-compatible base URL is https://apillms.com (no /v1) and the SDK calls /v1/messages. The OpenAI-compatible base URL is https://apillms.com/v1 and calls /chat/completions.
Can I use non-Claude models through the Anthropic SDK?
Yes. Since the endpoint accepts any model id on apillms, you can request gpt-5.5, deepseek-v4-flash, kimi-k3 and others through the same Anthropic-style messages.create() call.
What happens if my request fails or I use the wrong model id?
Failed requests are not billed, so you can safely retry while fixing the base URL, key, or model id. A 404 usually means /v1 was duplicated in the base URL, and an unknown model id means the name doesn't match the current list on /models.