If you want Codex to use DeepSeek, the first reaction is usually to change ~/.codex/config.toml:
|
|
This idea does hold true in some old versions or common OpenAI SDK scenarios, but when put on the current Codex CLI, it is easy to run into an underlying problem: Codex’s custom model supplier uses the OpenAI Responses protocol, and the DeepSeek official interface mainly provides OpenAI-compatible Chat Completions calling methods.
My current machine is codex-cli 0.111.0. You can see in codex --help that it supports the configuration entries --config, --model, and --profile; the OpenAI official Codex configuration reference is also very clear: model_providers.<id>.wire_api currently only supports responses, and the default is responses when omitted. .
The calling path given by DeepSeek official documentation is https://api.deepseek.com/chat/completions, and the example is also client.chat.completions.create(...). So the problem is not that DeepSeek cannot be called by the OpenAI SDK, but that the request semantics sent by Codex and the semantics understood by DeepSeek’s native interface are not exactly the same thing.
This is why after directly changing base_url to https://api.deepseek.com, the following phenomena may occur:
- The request path does not match, directly 404 or the return format is incorrect.
- Parsing failed during multiple rounds of dialogue, tool invocation, and patch generation.
tool_callsThe sequence, message structure, and streaming event format do not match.- It seems that the model can reply a sentence, but when it comes to Codex to actually work, it starts to report errors.
A more stable approach is to put a “translation layer” between Codex and DeepSeek. There are two common routes. Method 1: DeepSeek local routing using CC Switch
The role of the local gateway is not to simply forward, but to convert Codex Responses requests into Chat Completions that DeepSeek can handle, and then convert ordinary JSON, SSE streams, inference content, and tool calls back to Responses events that Codex can parse.
CC Switch offers this clear official project path starting from 3.16. The order of operations is:
- Install the current version of CC Switch from the official Releases.
- Switch to the Codex page at the top and add a new Provider.
- Select the built-in DeepSeek preset and fill in the DeepSeek API Key.
- Keep the default automatically enabled
Needs Local Routing. - Enable local routing on the Routing page of settings and enable takeover for Codex.
- Exit completely and restart Codex so that the model directory is reloaded.
When routing is enabled, the Codex local address given by the official guide is usually:
|
|
Do not write this port as a fixed truth; refer to the current interface of CC Switch and the generated user level ~/.codex/config.toml. CC Switch will manage the model directory and authentication fields. Manually copying the TOML in the old tutorial will easily conflict with the current version.
After entering the Codex, first use /model to check whether the DeepSeek preset is displayed, and then send a minimum request. Then check the number of requests or logs on the CC Switch Routing page; only if the requests are indeed routed locally can you prove that other providers are not misused. Actual environment record
When this article was reviewed, the results of local execution were:
|
|
codex --help Also shown are --config, --model and --profile available. The current machine does not have CC Switch installed and DeepSeek Key is not configured, so this article does not claim to have completed the end-to-end DeepSeek generation test; the above interface steps are from the CC Switch project documentation. The reader’s own acceptance should save the Codex version, CC Switch version, request logs, and tool invocation results. Method 2: Use OpenRouter BYOK for online bridging
If you don’t want to run a local translation layer, you can evaluate OpenRouter’s Responses API Beta with BYOK. BYOK binds its upstream supplier Key to OpenRouter, and OpenRouter is responsible for routing; the OpenRouter API Key is still used for Codex access.
OpenRouter currently marks the Responses API as Beta and notes that it is a stateless implementation. Interface capabilities and Codex required events may still change, so this route should be verified before deciding whether to use it for long-term work.
The most common thing to write wrong here is the environment variable. Codex accesses OpenRouter, so env_key should usually be OPENROUTER_API_KEY, not DEEPSEEK_API_KEY. DeepSeek Key needs to be added in the BYOK or provider key settings of OpenRouter.
Configuration example:
|
|
startup method:
|
|
PowerShell:
|
|
Then add the DeepSeek provider key in the OpenRouter backend and restrict the OpenRouter API Key that allows the use of this BYOK Key. The model ID must be based on the current model directory of OpenRouter. You cannot directly copy the DeepSeek official model name and assume it is available.
Before starting the Codex, verify the Responses endpoint itself:
|
|
This request is successful, which only proves that the basic Responses call is available. File reads, patches, streaming responses, and tool calls must also be verified in the staging repository to determine if it meets the Codex workflow.
This path eliminates the need for local gateway maintenance, but adds an online middle layer, and Responses is still in Beta. When troubleshooting, save the error information of Codex, OpenRouter and upstream DeepSeek separately. Do you want to continue using the model name deepseek-chat?
In the description of DeepSeek official documentation in May 2026, the recommended model names have appeared deepseek-v4-flash and deepseek-v4-pro, and it is suggested that deepseek-chat and deepseek-reasoner compatible aliases will be abandoned after 2026-07-24.
Therefore, it is recommended to give priority to testing in the new configuration:
|
|
If you use OpenRouter, you need to write it according to the OpenRouter model naming, for example:
|
|
The actual available name depends on the gateway or OpenRouter model page you are using. When the model name is incorrect, errors usually appear as model not found, 404, or the provider cannot find the corresponding endpoint. Why is it not recommended to directly change DeepSeek official base_url?
You could of course try writing:
|
|
But this is more like a debugging experiment and is not suitable as a stable solution. Because Codex will talk to the custom provider according to the Responses protocol, and the official DeepSeek example uses /chat/completions. If DeepSeek or Codex completes the compatibility layer in the future, this direct connection may become simple; until then, the bridge layer is more reliable. What should I do if I still use OpenAI after changing the configuration?
First confirm the configuration file location. The global configuration should be in:
.codex/config.toml in the
|
|
project is not suitable for machine-level provider configurations such as model_provider and model_providers. OpenAI official documentation also reminds that project-level configuration will not cover these local provider and certification-related fields.
Do not treat codex logout as the first step in general troubleshooting. Official login status and third-party Provider configuration are different issues; exiting hastily will only increase recovery costs. First check the profile, model_provider, model directory and local routing log in use.
You can also use temporary parameters to do a quick verification:
|
|
or:
|
|
If this takes effect, it means that the configuration itself is readable; if it does not take effect, first check whether the profile name, TOML syntax, and environment variables are only valid in the current shell. Troubleshooting Checklist
401: The Key is incorrect, orenv_keypoints to the wrong environment variable.404:base_urlor the model name is wrong, or the Responses request may be sent to an address that only supports Chat Completions.tool_calls, patch, streaming parsing error: most likely the protocol bridging is incomplete.- Still showing the default OpenAI model: confirm the user-level configuration, profile and
/modelresults, do not delete the login state first. - New windows that are opened after setting environment variables in PowerShell fail:
$env:...It only takes effect for the current session. If you need to save it for a long time, change the user environment variables.
- OpenRouter BYOK does not take away its own DeepSeek Key: Check whether the OpenRouter background provider key is bound, whether the current OpenRouter API Key is allowed to be used, and whether fallback is enabled. Conclusion
Let Codex use DeepSeek. It’s not that you can’t change config.toml, but you can’t just change base_url and expect everything to be automatically compatible.
The two ways that can currently be verified are:
- Use CC Switch local routing to convert Responses and Chat Completions.
- Use OpenRouter Responses API Beta and combine it with BYOK routing to your own DeepSeek Key.
Neither method can rely solely on “returning a sentence” as the success criterion. At a minimum, verify that model selection, streaming output, file modifications, tool calls, error recovery, and keys actually go to the expected Provider.
References: