Changing an API base URL is not enough to prove that Codex is using the provider you intended.
Codex is an agentic client. It needs more than a model that can return text. The provider must support the Responses API behavior Codex relies on, the API key must reach the process that launches Codex, the selected model must be available to that key, and the final request must arrive at the expected endpoint.
This guide shows a conservative setup for a custom Responses API provider, using XiuRouter as the concrete example. The same verification method applies to other compatible gateways.
The configuration has four separate decisions
A working Codex provider configuration answers four questions:
- Which model should Codex request?
- Which named provider should Codex use?
- Which base URL should receive the request?
- Which environment variable contains the API key?
Keep those decisions explicit. A minimal user-level configuration looks like this:
model = "YOUR_MODEL_ID"
model_provider = "xiurouter"
[model_providers.xiurouter]
name = "XiuRouter"
base_url = "https://router-api.xiu.ai/v1"
env_key = "XIUROUTER_API_KEY"
wire_api = "responses"
Use a model ID that is currently visible to your account. Do not copy a model name from an old screenshot or another user's configuration and assume your key can access it.
The important line is:
wire_api = "responses"
Codex uses the Responses API for its native agent workflow. A provider that only accepts Chat Completions requests may be useful for other clients, but it is not automatically a drop-in Codex provider.
OpenAI's Codex configuration reference also defines base_url, env_key, and wire_api as separate provider settings. Treat them as separate failure boundaries when debugging.
Keep the API key out of config.toml
The configuration should name an environment variable, not contain the secret:
env_key = "XIUROUTER_API_KEY"
For a terminal session:
export XIUROUTER_API_KEY="YOUR_KEY"
codex
For Codex Desktop on macOS, the application may not inherit variables from your terminal shell. Set the variable in the launch environment, then fully quit and reopen Codex:
launchctl setenv XIUROUTER_API_KEY "YOUR_KEY"
This distinction matters. A correct key in .zshrc can still produce a 401 if the desktop application was launched outside that shell.
Do not print the key during diagnosis. Check whether the variable exists and whether the request succeeds, not the secret value itself.
Start with a reversible configuration
Do not overwrite a working provider before the new route has passed a real task.
Keep the previous provider block in the file and change only the active model and model_provider lines. That gives you a fast rollback if the custom route fails during a longer agent run.
It is also safer to test the new provider in project-level configuration before promoting it to your user-wide default. OpenAI documents project configuration in .codex/config.toml, while user defaults live in ~/.codex/config.toml.
The practical rule is:
- project config for a bounded test;
- user config after the provider has passed;
- old provider retained until rollback is no longer needed.
A successful launch is not a successful integration
After Codex starts, run a small read-only task that requires tool use.
For example:
Inspect this repository, identify the test command, and summarize the main modules. Do not modify files.
This is more useful than asking the model to say hello. A plain text response proves only that one request returned text. A repository inspection exercises the agent loop, tool instructions, streaming, and follow-up turns without creating a destructive side effect.
Then verify the request on the provider side.
For XiuRouter, the usage record should show:
- the intended API key;
- the intended model;
- the Responses path;
- a successful status;
- usage and cost recorded for the request.
The expected path is:
/v1/responses
If no corresponding record appears, do not assume the request used the new provider. Codex may still be using an older active configuration, or the application may not have inherited the environment variable.
Diagnose failures by boundary
401 Unauthorized
Check the process environment first.
- Was Codex launched after the environment variable was set?
- Does the variable name exactly match
env_key? - Is the key valid for the current account?
- Is a project-level configuration overriding the user-level provider?
For Codex Desktop, quit the application completely after changing the launch environment.
The model is missing or rejected
Model visibility and key permissions are separate from protocol compatibility.
A gateway can support the Responses API while a particular key still lacks access to the selected model. Recheck the current model catalog and the key's scope instead of changing protocol settings at random.
The request hits the wrong URL
Inspect the final request path.
With:
base_url = "https://router-api.xiu.ai/v1"
wire_api = "responses"
the client should call /v1/responses.
If you see a duplicated path such as /v1/v1/responses, the base URL and endpoint path have both included the version prefix. Fix the configuration boundary that owns the duplicate instead of adding another redirect.
A simple prompt works, but an agent task fails
This usually means the test was too shallow.
Codex needs the Responses API behavior used by its real agent loop. Tool calls, streaming events, multi-turn state, and error handling can fail even when a one-shot text request returns 200.
Use the smallest real task that reproduces the failure. Record:
- Codex version;
- provider name;
- model ID;
- final request path;
- HTTP status;
- whether a usage record exists;
- the first failing agent action.
That evidence is much more useful than "the custom provider does not work."
The route works, but long tasks are unstable
Separate initial compatibility from runtime reliability.
Check whether failures correlate with:
- long streaming responses;
- tool-heavy loops;
- upstream model availability;
- rate limits;
- context size;
- client or network interruption.
Do not hide those failures by repeatedly retrying a destructive task. Reproduce them with a read-only task first.
A practical acceptance checklist
Before making the custom provider your default, confirm all of the following:
- Codex reads the intended configuration scope.
- The API key is supplied through the named environment variable.
- The selected model is available to that key.
- The final request path is
/v1/responses. - A read-only tool-using task completes.
- The provider records the expected key, model, status, usage, and cost.
- The previous provider is still available for rollback.
This is the difference between "the configuration looks right" and "the route has been verified."
XiuRouter-specific setup
XiuRouter's Agent integrations page generates a Codex configuration based on the selected app, operating system, API key, model permissions, and whether the user is creating a new setup or replacing an existing provider. It also keeps the verification step separate from the configuration step.
The public integration guide is here:
https://router.xiu.ai/en/integrations
The API compatibility reference is here:
https://docs.xiu.ai/router/api-compatibility
The OpenAI Codex configuration documentation is here:
https://developers.openai.com/codex/config-basic
https://developers.openai.com/codex/config-reference
The product-specific values may change. Recheck the current model catalog, key permissions, and integration output before copying a configuration into a production workflow.
Top comments (0)