Codex CLI
Point OpenAI Codex CLI at RouteMux with a custom model provider in ~/.codex/config.toml.
Codex CLI reaches a third-party endpoint through a custom model provider in its config file. It speaks the OpenAI Responses protocol and nothing else.
Configure
Add to ~/.codex/config.toml:
model_provider = "routemux"
model = "openai/gpt-5.5"
[model_providers.routemux]
name = "RouteMux"
base_url = "https://api.routemux.com/v1"
env_key = "ROUTEMUX_API_KEY"
wire_api = "responses"export ROUTEMUX_API_KEY="sk-..." # your RouteMux keyProvider keys only take effect in the user-level file
Codex ignores model_provider and model_providers in a project-scoped
.codex/config.toml. They have to live in ~/.codex/config.toml (or a profile file under
$CODEX_HOME). A provider block in a project directory is silently skipped, which looks
exactly like a wrong base URL.
wire_api has exactly one value
responses is the only supported value, and it is the default when you omit the field —
Codex has no Chat Completions mode. RouteMux serves /v1/responses, so this works, but it
also means Codex never touches /v1/chat/completions.
Pick your own provider id: openai, ollama and lmstudio are reserved and cannot be
overridden.
Base URL shape
base_url includes /v1. Codex appends only the operation path, so the request lands
on /v1/responses. Adding /v1 twice is tolerated — RouteMux routes /v1/v1/responses to
the same place — but the other direction (omitting /v1) is not.
Pick a model
GET /v1/models returns exactly the models your key can call. Use those slugs verbatim;
copy-paste is the main source of failure here, and a trailing space in a model id produces a
MODEL_NOT_FOUND whose suggestion looks identical to what you typed.
Verify
Test the protocol Codex actually uses, not Chat Completions:
curl https://api.routemux.com/v1/responses \
-H "Authorization: Bearer $ROUTEMUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-5.5","input":"ping"}'If this returns 200 and codex still fails, the problem is in the config file, not the key.
Why a hand-written curl costs more than you expect
Codex CLI always sends its own instructions. A bare curl that omits the field gets the
upstream's default Codex system prompt instead — measured at 21,334 characters, which billed
4,393 input tokens for an 11-token prompt. That is the test call being expensive, not the
integration. Send an instructions field if you want a cheap probe.
Timeouts on long runs
Codex's own stream_idle_timeout_ms defaults to 300000 ms. RouteMux's idle watchdog for
text is 180 s, so ours fires first: if the upstream sends no new chunk for 180 s the
request is aborted and recorded as a timeout. Streaming has no total time limit on our side —
a multi-minute agent turn is fine as long as tokens keep arriving.
Long sessions with images
A long Codex session accumulates screenshots in its history, and the whole history is resent on every turn. Two limits apply:
- Request bodies above 64 MiB are rejected outright.
- The budget for the upstream's first response header scales with body size, because prefill time grows with it. A 27 MB body gets a much longer grace period than a 1 MB one.
If a long session starts timing out while short prompts succeed, clear the conversation rather than retrying — the body is the variable.
Troubleshooting
| Symptom | Cause |
|---|---|
Error loading config.toml: wire_api = "chat" is no longer supported | You followed an older guide. Set wire_api = "responses". This is a config-load error, so every codex command fails until it is fixed — including ones unrelated to this provider. |
codex behaves as if unconfigured | Provider block is in a project-level .codex/config.toml, which ignores these keys. Move it to ~/.codex/config.toml. |
| 404 on every request | base_url is missing /v1, or points at a path instead of the API root. |
400 AUTH_AMBIGUOUS_API_KEY | Two different key values are being sent in two header fields. Clear whichever one you are not using. |
422 BILLING_INSUFFICIENT_CREDITS | Wallet lacks credit. Failed requests are not billed. |
| Model rejected | Not enabled for your key — GET /v1/models is authoritative. |
| A long session times out at a fixed duration, short prompts work | Body size, not the key. See above. |
Generating images
Codex CLI's built-in $imagegen rides your ChatGPT subscription session, not the
base_url configured above — so once Codex points at RouteMux (or any third-party
gateway), that built-in tool goes dark. There is nothing to fix in the config.
Install the routemux-images skill instead: it
calls POST /v1/images/generations over plain HTTP, which works regardless of what
the built-in tool is doing.
gh skill install rootfily-ai/routemux-skills routemux-images