Codex CLI & Codex APP
Last updated August 26, 2026
Codex CLI and the desktop app connect to RouterOne over the OpenAI protocol, sharing one config.toml.
Codex uses the OpenAI protocol, and RouterOne implements both the Chat Completions and Responses endpoints natively. The CLI and the desktop app share one configuration (~/.codex/config.toml and the same environment variables), so setting it up once covers both.
Recommended: let CC Switch do it
CC Switch supports Codex — add a provider with https://gateway.routerone.ai/v1 as the Base URL and both the CLI and the desktop app pick it up. Open a fresh terminal / restart the desktop app after switching, since both read their configuration at startup.
The manual route is below.
1. Install
npm install -g @openai/codex
# or
pnpm install -g @openai/codexDownload the desktop app from its official page. There is no extra configuration screen after installing — it reads the file below.
2. Create an RouterOne key
Create one on the keys page in the console. The key remains viewable there after creation, so you do not need to rotate it just to retrieve it again.
3. Configure
Keep the key in an environment variable
export ROUTERONE_API_KEY=your RouterOne keyPut it in ~/.zshrc or ~/.bashrc. Do not write the key into config.toml — that file often gets backed up or committed along with project configuration.
Edit ~/.codex/config.toml
~/.codex/config.toml
model_provider = "routerone"
model = "openai/gpt-5.6"
[model_providers.routerone]
name = "RouterOne"
base_url = "https://gateway.routerone.ai/v1"
env_key = "ROUTERONE_API_KEY"
wire_api = "responses"| Field | Notes |
|---|---|
model_provider | Points at the block below; the two names must match |
base_url | Keep the /v1 — OpenAI-family clients append /chat/completions or /responses directly, and one segment short is a 404 |
env_key | The name of the environment variable, not the key. Put the key here and it looks up a variable by that name, finds nothing, and reports an authentication failure |
wire_api | responses or chat. Both are implemented natively; responses is the default and usually the better first choice |
4. Start it
source ~/.zshrc # or ~/.bashrc
cd my-project
codexJust open the desktop app — it reads the same file.
Choosing models
Change model in config.toml, or switch inside the app.
Model names are canonical IDs and are not limited to OpenAI's models:
model = "anthropic/claude-opus-5"What matters is that the model's upstream serves the wire_api you picked — each model's page lists the protocols actually available for it.
Pinning a provider or choosing a strategy
A model often has several providers. To pin one, append a colon (openai/gpt-5.6:openai); without a pin you can choose the ordering for the call with an @ suffix (:@price for cheapest first, :@latency for lowest latency). Full details in the API reference.
Troubleshooting
Authentication failure / invalid key
First check that env_key holds a variable name rather than the key itself. Then:
echo $ROUTERONE_API_KEYIf that prints a value, check whether the key is still enabled in the console and whether the workspace has balance.
Cannot connect
curl https://gateway.routerone.ai/v1/models -H "Authorization: Bearer $ROUTERONE_API_KEY"A model list coming back means the network and the key are fine, so config.toml is not being read.
Configuration is not picked up
- CLI:
source ~/.zshrc, then open a fresh terminal - Desktop app: quit completely and reopen — it reads configuration at startup
- Confirm the file really is at
~/.codex/config.toml, not in the project directory
Model unavailable
Model IDs need the vendor prefix. Also, not every model supports every protocol — with wire_api = "responses" you need a model whose upstream serves Responses, and the same goes for chat. Each model's page says which, and an unsupported combination fails with a clear error.
It works after switching to chat
That means the upstream for your model only serves Chat Completions. Leave wire_api on chat; both endpoints are implemented natively, so this is not a downgrade.