How to Connect Codex CLI to Other Models: A Custom Provider Setup
A step-by-step guide to pointing OpenAI's Codex CLI at non-default models, from OpenAI-compatible gateways like OpenRouter to local runtimes, using the model and model_providers settings in config.toml, with the exact fields, a worked example, and the gotchas to check.
Codex CLI ships configured for OpenAI's own models, but it is not locked to them. Because Codex talks to models over a standard wire protocol, you can point it at almost any OpenAI-compatible endpoint: an aggregator like OpenRouter, a cloud gateway, a relay service, or a model running locally on your own machine. This guide walks through exactly how that works, the configuration fields involved, a complete worked example, and the mistakes that waste the most time.
This is the Codex counterpart to the provider routing many developers already do in other tools. If you would rather manage all of this through a visual app than hand-edit files, our guide to CC Switch covers a desktop manager that handles Codex, Claude Code, and others; this article explains the underlying configuration that such tools write for you.
1. How Codex Thinks About Models
Two settings decide which model answers and how Codex reaches it. The model setting names the model itself. The model_provider setting names a provider, which is a small block of configuration describing where the model lives and how to authenticate. Providers are defined in tables named model_providers, one per provider, each with its own id.
The reason this works with so many services is that Codex speaks OpenAI's API shape. Any endpoint that implements an OpenAI-compatible API can therefore stand in for the default. Connecting a new model is mostly a matter of telling Codex the right base URL, the right authentication, and the right model name.
2. Where the Configuration Lives
Codex reads its configuration from config.toml in your user-level Codex directory, which is ~/.codex/config.toml on macOS and Linux.
One detail catches people out: the model_provider and model_providers settings only take effect in that user-level file. If you put them in a project-local .codex/config.toml, Codex ignores them and prints a warning at startup. Keep provider definitions in your home directory, not in a repository.
A second constraint: a few provider ids are reserved for built-in providers and cannot be redefined. The reserved ids are openai, ollama, and lmstudio. If you want a custom provider, give it a different id. If you only need to change the base URL of the built-in OpenAI provider, there is a dedicated openai_base_url setting rather than a custom block.
3. Anatomy of a Provider Block
A provider block is a small table. The essential keys are name, base_url, and env_key.
The name is a human-readable label that shows up in Codex. The base_url is the API root for the service; for OpenAI-compatible gateways it usually ends in /v1. The env_key is the name of an environment variable that holds your API key. This is worth stressing: env_key is the name of a variable, not the key itself. Codex reads the key from that environment variable at runtime and sends it as a bearer token, so you never paste the secret into the config file.
Several optional keys tune the connection. The wire_api key chooses the protocol, with a value of either responses or chat. The query_params and http_headers keys let you attach extra URL parameters or headers, which some gateways such as Azure require. The request_max_retries, stream_max_retries, and stream_idle_timeout_ms keys control retry and timeout behavior for flaky connections.
4. The wire_api Choice: responses or chat
The wire_api setting deserves its own note because it is the field most likely to produce a confusing error. A value of responses uses the newer Responses API; a value of chat uses the older Chat Completions API. Different gateways support different protocols, and picking the wrong one produces errors that look like authentication or endpoint problems rather than a protocol mismatch.
There is no universally correct answer here. Check the documentation for the specific provider you are connecting and set wire_api to the protocol it expects. OpenRouter, used in the example below, expects responses.
5. Worked Example: An OpenAI-Compatible Gateway
Here is a complete setup for routing Codex through OpenRouter, a gateway that exposes many models behind one OpenAI-compatible endpoint. The same shape works for other gateways; only the base_url, env var, and model names change.
First, add the following to ~/.codex/config.toml. Each line is shown on its own:
model = "openai/gpt-5.3-codex"
model_provider = "openrouter"
model_reasoning_effort = "high"
[model_providers.openrouter]
name = "OpenRouter"
base_url = "https://openrouter.ai/api/v1"
env_key = "OPENROUTER_API_KEY"
wire_api = "responses"
A few things to notice. The model value uses the gateway's own slug format, which includes a provider prefix such as openai/ before the model name; use whatever model id the gateway currently lists, since these change over time. The model_provider value matches the id in the model_providers table. The env_key names an environment variable rather than holding the key.
Next, export the key in the shell that will launch Codex, then start it from your project directory:
export OPENROUTER_API_KEY="your-key-here"
codex
The export must happen in the same shell session, or in your shell profile, so that the variable is present when Codex starts. If you launch Codex from an editor or a different terminal, make sure the variable is set there too.
6. Connecting a Local Model
You do not need a hosted gateway at all. Codex has built-in support for local runtimes through the reserved ollama and lmstudio provider ids, and it offers a shortcut for running open-weight models locally: launching with the open-source flag, codex --oss, routes Codex to a local model served by Ollama.
Running locally trades the model bill and the network round-trip for your own hardware and a smaller model. No API key leaves your machine, which is a real privacy advantage for sensitive code. For when local and open-weight models are the right call, and what they actually cost in practice, see our guide on open-source and local AI tools.
7. Switching Models Without Rewriting Config
Editing config.toml is fine for a default, but you will often want to switch per task. Codex supports command-line overrides so you can choose a model for a single run without touching the file, and it supports named configuration profiles that bundle a model and provider together so you can keep several setups side by side and select one when you start. The exact flags and profile syntax are documented in the official Codex configuration reference; check it for the current options, since the CLI moves quickly.
The broader point is that connecting a model and choosing a model are separate steps. Define your providers once, then switch between them as the task demands.
8. Verifying and Troubleshooting
After saving the configuration, start Codex and run a small prompt to confirm the model answers. If it does not, work through the usual suspects.
Authentication failures almost always mean the environment variable named in env_key is not set in the shell that launched Codex. Echo the variable to confirm it is present. Protocol errors that mention the endpoint or an unexpected response shape usually mean wire_api is set to the wrong value for that gateway. A startup warning that your settings are being ignored means the provider configuration is in a project-local file instead of the user-level ~/.codex/config.toml. And a base URL that omits the trailing /v1 expected by an OpenAI-compatible gateway will produce not-found errors. Treat these specifics as a snapshot and confirm them against the current Codex configuration basics, since fields and defaults change between releases.
One non-technical caution matters most. Switching the model behind Codex changes which model answers, not whether the answer is correct. A cheaper or unfamiliar model may be more confidently wrong, and an agent that edits files and runs commands acts on that output. Keep reviewing diffs, keep running your project's checks, and keep a human approval gate on anything that touches authentication, payments, migrations, or publishing. For how the tools themselves differ, see our comparison of AI coding assistants; for provider routing aimed at developers in China, see using Chinese LLMs in Claude Code.
Conclusion
Connecting Codex to other models comes down to three decisions: where the model lives, set with base_url; how to authenticate, set with env_key pointing at an environment variable; and which protocol to speak, set with wire_api. Put those in a model_providers block in your user-level config.toml, point model_provider and model at it, export your key, and Codex will talk to a gateway or a local runtime as readily as it talks to its default.
The configuration is small, but the discipline around it is not optional. Keep secrets in environment variables rather than the config file, verify the wire protocol your provider expects, and remember that a different model is still output you have to review. Used that way, Codex becomes a flexible front end to whatever model fits the task and the budget.