OpenAI-Compatible Base URL: What to Set, and the Four Ways It Goes Wrong (2026)
Every OpenAI-compatible provider gives you a base URL and assumes you know what to do with it. Most integration failures on day one are not authentication problems or model-name problems — they are a base URL that is one path segment or one slash away from correct, producing an error message that points somewhere else entirely.
The rule that resolves almost all of it: the base URL is the part the SDK appends its own path to. Everything else follows from knowing exactly what your client appends.
What the base URL replaces
An OpenAI SDK builds a request URL by concatenating a base with a fixed route:
<base_url> + /chat/completionsThe official OpenAI client's default base is https://api.openai.com/v1. That trailing /v1 is part of the base, not part of the route. So the final URL is https://api.openai.com/v1/chat/completions.
This single fact determines what you paste into your config. If your provider documents its endpoint as https://example.com/v1/chat/completions, then your base URL is:
https://example.com/v1Not https://example.com, and not the full endpoint path.
The four ways it goes wrong
1. Dropping /v1 when the SDK does not add it. Set https://example.com with the OpenAI Python or Node SDK and you get requests to https://example.com/chat/completions — usually a 404, sometimes an HTML error page that produces a JSON parse error in your client rather than a clean HTTP error. Symptom to recognise: your error mentions unexpected token or invalid JSON rather than a status code.
2. Including /v1 when the client already appends it. The mirror image, and more common with tools that wrap the SDK. The result is https://example.com/v1/v1/chat/completions. The tell is a 404 whose message echoes a doubled path segment — read the full URL in the error, not just the code.
3. Trailing slash. https://example.com/v1/ plus /chat/completions yields //chat/completions. Some gateways normalise this; some route it to a different handler; some return 404. It costs nothing to omit the trailing slash, so omit it.
4. Setting the base URL in one place and the environment variable in another. OPENAI_BASE_URL (and the older OPENAI_API_BASE) are read by the SDK at client construction. A base URL passed explicitly in code overrides the environment; a base URL exported in a shell that is not the one running your process does nothing at all. When behaviour differs between your terminal and your app, check which of the two the running process actually sees.
What each client expects
|
Client |
Where it goes |
Includes |
|---|---|---|
|
|
|
Yes — you supply it |
|
|
|
Yes — you supply it |
|
LangChain (OpenAI wrapper) |
|
Yes |
|
Raw |
You write the full URL |
You write the whole path |
|
Claude Code / Codex-style CLIs |
Provider config or env var |
Usually yes — check the tool's docs for whether it appends a version segment |
When a tool's documentation is ambiguous, the fastest resolution is not to read more documentation. It is to make one request and look at what the server received.
Verifying in one request
Before wiring anything into an application, confirm the base URL with a direct call to the route the SDK would build:
curl -sS https://example.com/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"<model-id>","messages":[{"role":"user","content":"ping"}],"max_tokens":8}' \
-w '\nHTTP %{http_code} final=%{url_effective} redirects=%{num_redirects}\n'Three things in that output matter as much as the body:
- HTTP status. 200 means base URL and route are right. 404 means the path is wrong — a base URL problem. 401 means the path is right and the key is the issue; that is progress, not a setback.
redirects. Anything above 0 means you are hitting a URL that forwards. Some clients drop theAuthorizationheader across a redirect, which then surfaces as a confusing 401. Use the final URL as your base.final. Read it for a doubled/v1or a//.
Once this curl returns 200, set your base URL to everything in that URL before /chat/completions.
Mapping errors back to the cause
|
What you see |
Most likely cause |
|---|---|
|
404 with a doubled path in the URL |
|
|
404, path missing a version segment |
|
|
JSON parse error / unexpected token |
Hit an HTML page, not the API — usually a wrong path |
|
401 on a route that used to work |
Redirect stripped the auth header, or key/base mismatch |
|
Connection refused / DNS failure |
Base URL host is wrong, or a proxy is intercepting |
|
200 but an unexpected model responded |
Base URL is right; the model alias is being remapped upstream |
For the layer beyond routing — where the URL is correct but parameters are silently ignored — see OpenAI Compatibility Issues: What "Compatible" Actually Covers. If the request reaches the server but is rejected, Anthropic API Key Not Working? Read the Status Code First walks the auth path. For a first end-to-end call, see How to Use the Claude API.
FAQ
Should the OpenAI base URL include /v1?
If your client appends only /chat/completions, yes — /v1 belongs in the base. The official Python and Node SDKs work this way. Confirm by making one curl request and reading the final URL.
What is the difference between OPENAI_BASE_URL and OPENAI_API_BASE?
OPENAI_API_BASE is the older variable name; OPENAI_BASE_URL is current in the modern SDKs. Some tools still read the old one. If a base URL appears to be ignored, set both, or pass it explicitly in code where it takes precedence.
Why do I get a 404 even though the endpoint works in curl?
Almost always because your curl used the full endpoint path while the SDK built a different one from your base. Compare the URL your curl hit against the URL in the SDK's error — the difference is the fix.
Does a trailing slash on the base URL matter?
It can. base/ plus /chat/completions produces a double slash, which some gateways route differently. Omit the trailing slash.
The short version
The base URL is whatever the SDK appends /chat/completions to — usually your provider's host plus /v1, with no trailing slash. Verify it with a single curl and read the status, the redirect count, and the final URL. A 404 is a path problem, a 401 means the path was right, and a JSON parse error means you reached a web page instead of an API.