I’ve been using Codex (I know, I actually prefer it over Claude Code) more lately and one of the issues I’d run into from time to time was quota.
You see, the nice thing about Codex’s default setup is that it uses my ChatGPT Plus subscription, no surprise there. The less nice thing is that, once I hit the daily or weekly limits, that’s kind of that.
So, since I already have Azure OpenAI deployments lying around, I wanted a simple way to switch over to paid tokens in my Azure subscription whenever needed, instead of waiting around for the tokens to come back. As an added boon, this means that the requests go through my Azure setup, with the data remaining in my Azure tenant, in whatever geography I see fit.
The config.toml setup
Whenever you want Azure OpenAI to be the default, add this to ~/.codex/config.toml:
model = "gpt-5.4"
model_reasoning_effort = "xhigh"
show_raw_agent_reasoning = true
personality = "pragmatic"
model_provider = "azure"
[model_providers.azure]
name = "Azure OpenAI"
base_url = "https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1"
env_key = "AZURE_OAI_API_KEY"
wire_api = "responses"
This is pretty much all I needed.
Some notes on the fields:
modelis the deployment Codex should use by default. I strongly recommend naming the deployment after the actual model if you can. Life is easier whengpt-5.4is calledgpt-5.4.model_provider = "azure"is the switch telling Codex to use the custom provider block below.base_urlshould end in/openai/v1.env_keyis the environment variable Codex will read for the API key. I prefer explicit names likeAZURE_OAI_API_KEY, because the generic Azure env vars tend to be picked up by everyone, and we can’t have any of that.wire_api = "responses"is the important bit that makes Codex talk to Azure OpenAI the way it expects to.
The model_reasoning_effort, show_raw_agent_reasoning, and personality settings are not Azure-specific, they’re just part of my current config.
Environment variable
I just keep the API key in an environment variable and let Codex read it from there:
export AZURE_OAI_API_KEY="<YOUR_API_KEY>"
Switching back
If you want to go back to the default provider, comment out the model_provider = "azure" line:
# model_provider = "azure"
At that point Codex will stop using the Azure block by default, but you can still enable it ad-hoc with:
codex -c 'model_provider="azure"' -m "gpt-5.4"
This is probably the mode I like most:
- use the default provider while the ChatGPT Plus quota is available
- switch to Azure OpenAI when I run out and just pay by token
Pretty much the best of both worlds.
One more thing 🙂
One slightly odd behavior I’ve noticed is that the Codex App (not the CLI) seems to stop showing the cloud threads when I switch to the Azure provider in config.toml.
If I comment out model_provider = "azure" and go back to the default setup, those discussions show up again.
I haven’t dug into this any further, and this may simply be how the hosted/cloud side is separated from custom providers. Still, it’s worth knowing so you don’t assume you’ve somehow nuked your chats by switching over to Azure.
Conclusion
Other than that, the setup is pleasantly boring.
You point Codex at an OpenAI-compatible Azure endpoint, tell it which env var holds the key, make sure the model name matches your deployment, and that’s about it.
For me, the real value is that I don’t have to pick a side:
- I can use the included quota from ChatGPT Plus when that’s enough
- I can switch to Azure OpenAI when I need more usage
- and if I’m doing this in a company setting, routing things through Azure is usually easier from a governance/privacy perspective as well, since the traffic stays within that Azure setup
Which, frankly, is how more of these tools should work.