What is a base URL? For the OpenAI, Anthropic, Gemini SDKs
What a base URL is, the official one for the OpenAI, Anthropic and Gemini SDKs, how to set it in code or Claude Code, and how to fix 404 and 401 errors.
A base URL is the fixed start of every address an API answers on, such as https://api.openai.com/v1. Your SDK adds the path for each request, like /chat/completions. Change the base URL, and the same code sends its requests to another compatible service, as long as the key and the model id match it.
What is a base URL?#
Every request to an AI API goes to a full address made of two parts. The base URL is the part that stays the same for all requests: the scheme, the host and often a version, as in https://api.openai.com/v1. The path is the part that names the operation, as in /chat/completions for a chat reply or /models for the list of models.
base URL https://api.openai.com/v1
+ path /chat/completions
= request https://api.openai.com/v1/chat/completionsThe official SDKs keep the paths inside the library. You give them the base URL once, and they build each address from it. The key is not part of the address: it goes in a request header. The model id goes in the request body, or in the path for Gemini.
Base URL vs endpoint#
An endpoint is one full address with its HTTP method, such as POST /v1/messages for a Claude reply. The base URL is the shared start of all the endpoints. When a tool asks for a "base URL", an "API base" or a "custom endpoint", it usually means this shared start, not the address of a single request.
Why change the base URL?#
- A gateway or proxy. The same code goes through a service that controls keys, spending and logs.
- A compatible service. Another provider that speaks the same format as the official API.
- Tests. A local or staging server that answers like the real one.
The two official Python SDKs we checked pick the base URL in the same order: a value in your code wins over the environment variable, and the variable wins over the built-in default. The variable is OPENAI_BASE_URL in OpenAI's library and ANTHROPIC_BASE_URL in Anthropic's.
The official base URLs#
Checked on 2026-11-01 in each provider's docs and SDK source:
| Provider | Official base URL | The library or request adds | Key header |
|---|---|---|---|
| OpenAI | https://api.openai.com/v1 | /chat/completions, /responses | Authorization: Bearer |
| Anthropic | https://api.anthropic.com | /v1/messages | Authorization: Bearer or x-api-key, plus anthropic-version |
| Google Gemini | https://generativelanguage.googleapis.com/v1beta | /models/{model}:generateContent | x-goog-api-key |
The version sits in a different place for each provider. OpenAI's base URL ends in /v1. Anthropic's has no version, because the library adds /v1/messages itself. Gemini's ends in /v1beta. Many setup errors come from this one difference.
The base URL in the OpenAI library#
The OpenAI library takes the base URL as base_url in code or from OPENAI_BASE_URL, and the key from OPENAI_API_KEY. Keep /v1 at the end: the library adds only the operation, such as /chat/completions or /responses.
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.5abeer.ai/v1",
api_key=os.environ["KHABEER_API_KEY"],
)5abeer's OpenAI format is OpenAI-compatible: change the base URL and keep your code. It serves Chat Completions and Responses, and you can call Claude models in this format too. Each model's page in the models list shows the formats it supports. The same setup with environment variables, for macOS, Linux and Windows, is in The OpenAI library.
The base URL in the Anthropic library#
The Anthropic library takes base_url in code or ANTHROPIC_BASE_URL, and the key from ANTHROPIC_API_KEY. Leave out /v1: the library adds /v1/messages itself, and it sends the anthropic-version header for you.
import os
import anthropic
client = anthropic.Anthropic(
base_url="https://api.5abeer.ai",
api_key=os.environ["KHABEER_API_KEY"],
)5abeer's Anthropic format is compatible with the Anthropic Messages API, so code built on the Anthropic library keeps working. The steps are in The Anthropic library, and the request fields in Anthropic Messages.
The base URL in Claude Code#
Claude Code reads ANTHROPIC_BASE_URL too, so the rule is the same: no /v1 at the end. Anthropic's gateway guide, checked on 2026-11-01, adds two points:
- The key goes in its own variable.
ANTHROPIC_AUTH_TOKENsends it asAuthorization: Bearer, andANTHROPIC_API_KEYsends it asx-api-key. A key in the wrong variable reaches the gateway in a header it doesn't read, and the request fails with401. - The base URL alone doesn't switch your account. Setting only
ANTHROPIC_BASE_URLdoesn't replace a saved claude.ai login; without a gateway key, that login stays the active credential.
Our Claude Code guide puts your 5abeer key in ANTHROPIC_AUTH_TOKEN. To check the setup, run /status inside Claude Code: it shows an Anthropic base URL line only when a gateway address is set. Anthropic also warns against putting the key in a project's .claude/settings.json, because that file is committed and shared. Use ~/.claude/settings.json instead.
With a 5abeer subscription that includes Claude Code, the 5abeer AI app sets it up for you with no API key and no files to edit, as in Claude Code. Codex CLI takes its base URL in ~/.codex/config.toml; the steps are in Codex CLI with an API key.
The base URL for Gemini#
Gemini's own format puts the model in the path. The base URL is https://generativelanguage.googleapis.com/v1beta, a request goes to /models/{model}:generateContent, and the key goes in the x-goog-api-key header. Google also runs an OpenAI-compatible address, https://generativelanguage.googleapis.com/v1beta/openai/, for the OpenAI libraries, and says this support "is still in beta while we extend feature support".
On 5abeer, the Gemini format sits under /v1beta and needs a key for Gemini models: Claude and GPT keys don't work there. Gemini CLI reads its base URL from GOOGLE_GEMINI_BASE_URL. The full setup is in Gemini CLI, and the request shapes in Gemini generateContent.
Common base URL errors#
The error usually points to the part of the request that is wrong:
| What you see | Likely cause | Fix |
|---|---|---|
404 Not Found | /v1 is doubled or missing, so the path doesn't exist | OpenAI library: keep /v1. Anthropic library and Claude Code: remove it |
401 with API_KEY_REQUIRED or INVALID_API_KEY | The key is missing, mistyped, or in a header the service doesn't read | Copy the key again and check which variable or header carries it |
403 with MODEL_PLATFORM_NOT_ALLOWED | The key belongs to one provider and the model to another | Use a key for that model's provider, as in One key per provider |
ENOTFOUND or a refused connection | The host is mistyped or unreachable | Copy the base URL again from the table below |
| An HTML page instead of JSON, or an error saying the reply is empty or can't be read | The base URL points at a website, not the API | Use the API address, not the site address |
400, 401 and 403 errors don't clear when you retry, so fix the request first. Each code and its fix is in Errors and fixes, for example INVALID_API_KEY.
Test the base URL with one request#
Before you change a large project, send one request to the full address. If a reply comes back, the base URL and the key are right. In the OpenAI format:
curl --request POST "https://api.5abeer.ai/v1/chat/completions" \
--header "Authorization: Bearer $KHABEER_API_KEY" \
--header "Content-Type: application/json" \
--data '{"model":"claude-sonnet-5.5","messages":[{"role":"user","content":"Write a product idea in one sentence."}]}'{
"id": "chatcmpl-9f2",
"object": "chat.completion",
"model": "claude-sonnet-5.5",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you today?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 21,
"completion_tokens": 12,
"total_tokens": 33
}
}The key is read from KHABEER_API_KEY, so it never appears in your code.
And in the Anthropic format:
curl --request POST "https://api.5abeer.ai/v1/messages" \
--header "x-api-key: $KHABEER_API_KEY" \
--header "Content-Type: application/json" \
--header "anthropic-version: 2023-06-01" \
--data '{"model":"claude-sonnet-5.5","max_tokens":512,"messages":[{"role":"user","content":"Write a product idea in one sentence."}]}'{
"id": "msg_01Xh7",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-5.5",
"content": [
{
"type": "text",
"text": "Hello! How can I help you today?"
}
],
"stop_reason": "end_turn",
"usage": {
"input_tokens": 21,
"output_tokens": 12
}
}The key is read from KHABEER_API_KEY, so it never appears in your code.
These examples read the key from KHABEER_API_KEY and write out the full address, so you can see the base URL and the path joined.
5abeer's base URLs#
5abeer answers in three formats. Use the base URL that matches your library, and send the key in that format's header, as in Where the key goes in a request:
https://api.5abeer.ai/v1Authorization: Bearer <KEY>https://api.5abeer.aix-api-key: <KEY>https://api.5abeer.ai/v1betax-goog-api-key: <KEY>A 5abeer API key pays per token from your balance, and every model priced per token costs less than its official price. Compare the models on the API page, or by provider on Claude API, OpenAI API and Gemini API. Each key can have a spend limit, an expiry date and an IP allow-list, as in Control every key.
Plans are for the supported apps; to use the models from your own code, create an API key. The apps are on 5abeer apps and the plans on the pricing page. New to keys? Start with How to get an API key, and read What is a token to see how each request is billed.
FAQ#
Is a base URL the same as an endpoint?#
No. The base URL is the shared start, such as https://api.anthropic.com. An endpoint is one full operation, such as POST /v1/messages. The SDK joins the two for every request.
Do I add /v1 at the end of the base URL?#
It depends on the library. The OpenAI library expects /v1 in the base URL. The Anthropic library and Claude Code expect no version, because they add /v1/messages themselves. Gemini's own address ends in /v1beta.
Where do I set the base URL?#
In code, as the base_url argument, or in an environment variable: OPENAI_BASE_URL for the OpenAI library, and ANTHROPIC_BASE_URL for the Anthropic library and Claude Code. In the Python libraries, a value in code wins over the variable.
Do I need new code to switch the base URL?#
Usually not, if the new service speaks the same format. You change the base URL, the key and, if needed, the model id. Check any feature your code relies on, since a service may not support every option of the format.
Where does the API key go?#
In a request header, not in the base URL. On 5abeer that is Authorization: Bearer for the OpenAI format, x-api-key with anthropic-version for the Anthropic format, and x-goog-api-key for Gemini. Keep the key in an environment variable, not in your code or a shared file.
Why does Claude Code still use my claude.ai login?#
Setting only ANTHROPIC_BASE_URL doesn't replace a saved login. Put your key in ANTHROPIC_AUTH_TOKEN as in our Claude Code guide, then check the Anthropic base URL line in /status.
Sources#
Checked on 2026-11-01:
- OpenAI: API overview
- OpenAI: openai-python library
- Anthropic: API overview
- Anthropic: Python SDK and the anthropic-sdk-python library
- Claude Code: Connect Claude Code to an LLM gateway
- Claude Code: Other LLM gateways
- Google AI for Developers: Generating content
- Google AI for Developers: Getting started
- Google AI for Developers: OpenAI compatibility
Get started#
Copy the base URL for your library from the table above, create a key, and send your first request.
Related guides
- How to get an API key for Claude, GPT and GeminiWhat an AI API key does, where to create one at Anthropic, OpenAI and Google, what it costs to use, and how to keep it safe.
- What is a token in AI? Tokens, words and API cost explainedWhat a token is, how many words it holds in English and Arabic, and how tokens set the cost of every AI API request, with a worked example.
- Run Codex CLI with an API key: the complete guideHow to run OpenAI's Codex CLI on an API key instead of a ChatGPT sign-in, what it costs per token, and how to set up a custom provider in config.toml.
Ready to start?
Pick a plan that runs the official apps, or create an API key to use from your own code.