The three values you need
Every OpenAI-compatible client asks for the same three things. Here they are for this service.
| Setting | Value |
|---|---|
| Base URL | https://api.getcodexapi.com/v1 |
| API key | Your key from the API key page |
| Model | uncensored |
The key is sent as Authorization: Bearer YOUR_KEY. The two endpoints you can call are POST /v1/chat/completions and GET /v1/models. This is an independent service running one open-weight model, not OpenAI's Codex, so do not paste OpenAI's own endpoint or an OpenAI key into the same setting.
Check the connection with curl
Before you edit any app config, confirm the key and URL work from a terminal. Listing models is the cheapest check, since it needs no prompt:
curl https://api.getcodexapi.com/v1/models \
-H "Authorization: Bearer YOUR_API_KEY"
You should get a JSON list that includes the model uncensored. Then send one real completion:
curl https://api.getcodexapi.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"messages": [{"role": "user", "content": "Say hello in five words."}]
}'
If both calls work, the problem in any later failure is in your client config, not the service. Response headers include X-Request-Id, which is useful to keep if you ever need to trace a specific call, and X-Balance-USD, which shows your remaining credit.
Python with the OpenAI SDK
The official openai package takes the base URL in the client constructor. Nothing else about your code changes.
from openai import OpenAI
client = OpenAI(
base_url="https://api.getcodexapi.com/v1",
api_key="YOUR_API_KEY",
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "Explain what a base URL is in two sentences."},
],
)
print(resp.choices[0].message.content)
If you would rather keep config out of the code, the SDK also reads OPENAI_BASE_URL and OPENAI_API_KEY from the environment:
export OPENAI_BASE_URL="https://api.getcodexapi.com/v1"
export OPENAI_API_KEY="YOUR_API_KEY"
With those set, OpenAI() with no arguments picks them up. This is handy because many third-party tools built on the SDK inherit the same variables without any code change.
Node.js
The JavaScript SDK uses the same option name, spelled baseURL.
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.getcodexapi.com/v1",
apiKey: process.env.API_KEY,
});
const stream = await client.chat.completions.create({
model: "uncensored",
messages: [{ role: "user", content: "Write a haiku about version control." }],
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? "");
}
Streaming comes back as server-sent events with stream: true, and usage is included at the end. Keep in mind that a streamed request holds one of your concurrency slots until the stream finishes, so a stream you abandon without closing keeps counting against the limit.
Apps that have a settings screen
Desktop tools and editors usually label the field one of three ways: "Base URL", "API Base" or "OpenAI-compatible endpoint". All of them want the same string. A few notes that save time:
- Pick the OpenAI or "custom OpenAI-compatible" provider type, not a vendor-specific one.
- Type the model name by hand if the app has a free-text box.
uncensoredis the exact ID. - If the app has a "test connection" button, it usually calls the models list, which this API supports.
- Some apps cache the model list from a previous provider. Remove the old entry and add a new one if the dropdown looks wrong.
For a worked example in a specific editor, see the guide on connecting Cursor, or the coding API page for the overall picture. Full parameter reference is in the API docs.
Once the connection works, save the exact values somewhere you can find them again: the URL, the model name and the date you created the key. Teams often lose an hour later to a copy of the config that still holds an old value. A single shared example file in the repository, with a placeholder instead of the real key, prevents that.
Common mistakes and fixes
The URL ends up as /v1/v1
Some clients append /v1 on their own. If your requests fail and the client log shows a path with /v1/v1/chat/completions, drop the /v1 from the base URL you entered. The reverse also happens: a client that does not add it needs it in your setting. The log of the request path settles the question quickly.
You put the full endpoint in the base URL
The base URL stops at /v1. Do not enter /chat/completions there. The SDK adds the path for each call.
A trailing slash or a typo in the host
Most SDKs tolerate a trailing slash, but a few older tools build paths by plain concatenation and end up with a double slash. Remove it if you see odd 404 responses.
Wrong key, or the key of another service
An OpenAI key will not work here, and ours will not work there. Authentication errors almost always mean a copy-paste problem, such as a missing character or a space at the end.
It works in curl but not in your app
If curl succeeds and the application fails with the same URL and key, the difference is in the environment. Check whether the app runs behind a proxy or inside a container with no outbound access, whether it reads an older environment variable such as a stale OPENAI_BASE_URL left over from another project, and whether a config file overrides the value you set in code. Printing the final URL the client will call, just before the request, settles most of these cases within a minute.
HTTP 429
This means a limit was hit. The error code rate_limited is requests per minute, and concurrency is too many requests at once. A full key allows 8 concurrent requests and 300 per minute; a trial key allows 2 and 60. On temporary overload you also get a 429 with a Retry-After: 5 header, so wait five seconds and try again.
LangChain and keeping the URL in one place
Frameworks built on the OpenAI client take the same values. In LangChain's OpenAI integration the arguments are named like this:
from langchain_openai import ChatOpenAI
llm = ChatOpenAI(
model="uncensored",
base_url="https://api.getcodexapi.com/v1",
api_key="YOUR_API_KEY",
)
print(llm.invoke("Name three uses of a base URL.").content)
Whatever the framework, do not scatter the URL through your code. Put it in one environment variable or one settings file, and read it from there. That way, moving between a test key and a production key, or between machines, means changing a single line. It also keeps keys out of your repository: store the key in an environment variable or a secrets manager, never in a committed file.
If you were looking for OpenAI's own endpoint for its Codex products, this is not it. Their base URL and authentication are documented by OpenAI, so follow their current docs for that. The address on this page belongs to an independent service and only accepts keys issued here.
What you can send once connected
The endpoint supports streaming, tool calling (tools, tool_choice, with results returned as role: "tool" messages), and JSON mode through response_format: {"type": "json_object"}. The parameters temperature, top_p, stop, seed and the penalties are passed through. The context window is 100,000 tokens for prompt plus completion, and the maximum request body is 8 MB.
It is text only. There is no image or audio generation, no embeddings and no fine-tuning, so a client feature that depends on those will not work against this base URL. Usage is billed per token at $0.15 per 1M input and $0.50 per 1M output; the pricing page has worked examples.
