Codex Gateway

llms.txt ↗

An OpenAI-compatible API powered by a ChatGPT subscription.

Overview

This gateway speaks the standard OpenAI wire format. Any library, bot, or tool that talks to OpenAI works here by changing two values — the base URL and the API key. No code changes, no SDK swap.

Base URL

Authentication

Send your key as a Bearer token on every /v1 request:

Authorization: Bearer sk-cgw-YOUR_KEY
The Bearer prefix is optional. A bare key works too, as does x-api-key: sk-cgw-…. Keys are created in the dashboard.

Quickstart

Chat completions

POST/v1/chat/completions

The standard endpoint. Supports multi-turn history, system messages, streaming, function calling, and image inputs.

FieldTypeNotes
modelstringSee Models. Ignored if the key is pinned.
messagesarrayRequired. system / user / assistant / tool.
streambooleanSSE chunks terminated by data: [DONE].
toolsarrayFunction definitions — see Function calling.
tool_choicestring/objectauto, none, required, or a named function.
temperaturenumberPassed through.
max_tokensnumbermax_completion_tokens also accepted.

Response is the usual OpenAI shape:

{
  "id": "chatcmpl-…",
  "object": "chat.completion",
  "model": "gpt-5.4",
  "choices": [{
    "index": 0,
    "message": { "role": "assistant", "content": "Hello!" },
    "finish_reason": "stop"
  }],
  "usage": { "prompt_tokens": 12, "completion_tokens": 3, "total_tokens": 15 }
}
The model field in the response is the model that actually ran. If a key is pinned, or you sent a legacy slug that was remapped, this is how you tell.

Streaming

Set "stream": true to receive server-sent events.

Each chunk carries a delta; the stream ends with data: [DONE].

data: {"choices":[{"delta":{"content":"Hel"},"finish_reason":null}]}
data: {"choices":[{"delta":{"content":"lo"},"finish_reason":null}]}
data: {"choices":[{"delta":{},"finish_reason":"stop"}]}
data: [DONE]

Function calling

Define tools exactly as you would with OpenAI:

When the model decides to call a tool you get finish_reason: "tool_calls" and a tool_calls array. Run the function, then append the result as a tool message and call again:

{ "role": "tool", "tool_call_id": "call_abc123", "content": "{\"temp\":34}" }

Simple endpoint

POST/v1/ask

For bots and scripts that do not want the chat envelope.

{ "text": "…", "model": "gpt-5.4", "usage": { "total_tokens": 42 } }

Other endpoints

EndpointPurpose
POST/v1/responsesOpenAI Responses-style shape.
GET/v1/modelsList available models.
GET/healthNo auth. Liveness + link state.

Models

ModelBest for
gpt-5.5Highest quality, complex reasoning
gpt-5.4Balanced default; strong multilingual and Arabic
gpt-5.4-miniCheapest and fastest — classification, extraction, structured JSON
gpt-5.3-codexCode-tuned
gpt-5.3-codex-sparkChatGPT Pro only, research preview
Legacy slugs keep working. gpt-4o, gpt-4, gpt-3.5-turbo, o1, o3 and friends are auto-mapped to the nearest model above, so existing code runs unchanged.
Pinned keys override the request. An API key can be locked to one model in the dashboard. Requests made with it ignore the model field entirely — useful for third-party tools that hardcode a slug you cannot edit.

Errors

Errors use the OpenAI envelope, so SDK error handling works unchanged.

StatusCodeMeaning
401invalid_api_keyMissing, unknown, revoked, or disabled key.
405method_not_allowedWrong verb — the Allow header names the right one.
429rate_limitedChatGPT plan quota exhausted. Back off; re-linking will not help.
503needs_relinkNo linked ChatGPT account, or its session was revoked. Needs a human in the dashboard.
504timeoutUpstream took too long.

Limits

For AI agents

Building with a coding model? Hand it /llms.txt — a plain-text spec of this whole API, written to be pasted straight into a model's context alongside your key.

Prompt to use: "Here is the API spec for my LLM gateway. Use it with key sk-cgw-… to add AI features to this project."