Skip to content

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.

Updated November 1, 2026Markdown version

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.

How the address is built
base URL   https://api.openai.com/v1
+ path     /chat/completions
= request  https://api.openai.com/v1/chat/completions

The 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:

ProviderOfficial base URLThe library or request addsKey header
OpenAIhttps://api.openai.com/v1/chat/completions, /responsesAuthorization: Bearer
Anthropichttps://api.anthropic.com/v1/messagesAuthorization: Bearer or x-api-key, plus anthropic-version
Google Geminihttps://generativelanguage.googleapis.com/v1beta/models/{model}:generateContentx-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.

Python
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.

Python
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_TOKEN sends it as Authorization: Bearer, and ANTHROPIC_API_KEY sends it as x-api-key. A key in the wrong variable reaches the gateway in a header it doesn't read, and the request fails with 401.
  • The base URL alone doesn't switch your account. Setting only ANTHROPIC_BASE_URL doesn'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 seeLikely causeFix
404 Not Found/v1 is doubled or missing, so the path doesn't existOpenAI library: keep /v1. Anthropic library and Claude Code: remove it
401 with API_KEY_REQUIRED or INVALID_API_KEYThe key is missing, mistyped, or in a header the service doesn't readCopy the key again and check which variable or header carries it
403 with MODEL_PLATFORM_NOT_ALLOWEDThe key belongs to one provider and the model to anotherUse a key for that model's provider, as in One key per provider
ENOTFOUND or a refused connectionThe host is mistyped or unreachableCopy 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 readThe base URL points at a website, not the APIUse 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."}]}'
Response
{
  "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."}]}'
Response
{
  "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:

OpenAI-compatiblehttps://api.5abeer.ai/v1Authorization: Bearer <KEY>
Anthropic-compatiblehttps://api.5abeer.aix-api-key: <KEY>
Geminihttps://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:

Get started#

Copy the base URL for your library from the table above, create a key, and send your first request.