Anthropic base URL in Python — working examples
Pointing the Anthropic Python SDK at a custom endpoint is one constructor argument. This page shows the four patterns you actually need: sync, streaming, async, and raw HTTP.
https://aicomp.ai/v1).
Create one free →
curl https://aicomp.ai/v1/models \
-H "Authorization: Bearer sk-your-gateway-key"
A JSON list of model IDs means the key is good. Invalid token means it was copied wrong.
Install
pip install anthropic
The basic pattern
from anthropic import Anthropic
client = Anthropic(
base_url="https://aicomp.ai/v1", # your endpoint
api_key="sk-your-gateway-key", # not an Anthropic-issued key
)
resp = client.messages.create(
model="claude-sonnet-5",
max_tokens=256, # required on this API
messages=[{"role": "user", "content": "Summarise this in one sentence: {text}"}],
)
print(resp.content[0].text)
Two things to note. max_tokens is required — omit it and the request fails validation. And the text lives in content[0].text, not in a choices array.
Streaming
with client.messages.stream(
model="claude-sonnet-5",
max_tokens=512,
messages=[{"role": "user", "content": "Write a haiku about deployment."}],
) as stream:
for chunk in stream.text_stream:
print(chunk, end="", flush=True)
Streaming fails loudly if the endpoint does not support SSE, so it is a good compatibility check before you migrate real traffic.
Async
import asyncio
from anthropic import AsyncAnthropic
client = AsyncAnthropic(base_url="https://aicomp.ai/v1", api_key="sk-your-gateway-key")
async def main():
resp = await client.messages.create(
model="claude-sonnet-5",
max_tokens=256,
messages=[{"role": "user", "content": "say OK"}],
)
print(resp.content[0].text)
asyncio.run(main())
Raw HTTP, no SDK
import requests
r = requests.post(
"https://aicomp.ai/v1/messages",
headers={
"x-api-key": "sk-your-gateway-key",
"anthropic-version": "2023-06-01",
"content-type": "application/json",
},
json={
"model": "claude-sonnet-5",
"max_tokens": 256,
"messages": [{"role": "user", "content": "say OK"}],
},
timeout=60,
)
print(r.status_code, r.json())
Note the headers: this API authenticates with x-api-key, not Authorization: Bearer, and it expects an anthropic-version header. Getting these wrong is the most common 401 when moving from an OpenAI-shaped integration.
Reading usage
print(resp.usage.input_tokens, resp.usage.output_tokens)
Log these per request. Output tokens cost several times more than input, so a model that talks more than it needs is measurably more expensive even at the same rate.
Rates for the models above
| Model | Gateway rate in / out per 1M tokens | Official list in / out per 1M tokens | Diff |
|---|---|---|---|
| claude-haiku-4-5 | $0.5 / $2.5 | $1 / $5 | 50% |
| claude-sonnet-5 | $1 / $5 | $2 / $10 | 50% |
| claude-opus-5 | $2.5 / $12.5 | $5 / $25 | 50% |
Rates checked 2026-09-16. Gateway rates move with upstream promotions — verify the current number in your dashboard before committing to a budget.
Troubleshooting
| Error | Fix |
|---|---|
| 401 authentication_error | Wrong header. Use x-api-key, and include anthropic-version. |
404 on /messages | Doubled /v1. Check what your base URL already ends with. |
| validation error on max_tokens | It is required on this API. Set it. |
| not_found_error: model | Copy the model ID exactly from the /models listing. |
| Connection reset / SSL error | Usually a proxy. Verify with curl from the same machine. |
FAQ
How do I set a custom base URL with the Python Anthropic SDK?
Pass base_url to the Anthropic client constructor along with your api_key. Everything else — the messages call, the parameters, the response parsing — stays the same.
Should the base URL end in /v1?
Include the version segment once. If your endpoint already ends in /v1, do not add it again in the request path, or you will get a 404 from the doubled segment.
Does streaming work with a custom base URL?
Yes, if the endpoint supports SSE. Use the same stream context manager you would against the official API.
Can I use the OpenAI Python SDK with an Anthropic endpoint?
Only if the endpoint exposes an OpenAI-compatible layer for those models. Otherwise use the Anthropic SDK, which is what the examples below do.
Why do I get an SSL or proxy error?
Almost always a corporate proxy or a local firewall rather than the endpoint. Test with curl from the same machine first — if curl works and Python does not, it is your HTTP client configuration.