Codex error 403: causes and how to keep working

A 403 in Codex comes in three kinds: a region refusal, an account problem and gateway key restrictions. How to tell them apart by the error text and what to fix.

5 min · · errors · IDE

When a 403 error shows up in Codex, the worst part is that it has no single cause. The same response code comes both from OpenAI, when it refuses by country or account, and from a gateway, when a key is not allowed to use a model. They are fixed differently, so the first action is not "reconfigure everything" but to find out who exactly refused. Below: the diagnostic order, a table of causes and concrete Codex config fixes.

Codex error 403: where it comes from

HTTP 403 means "the request is understood but will not be carried out". In a Codex-plus-API setup, different links in the chain can refuse:

Who refusedWhat it looks likeWhat to do
OpenAI directly: regionthe error text mentions a country, region or territory where the service is not supportedthis is not fixed by Codex settings; point Codex at another provider (see below)
OpenAI directly: accounta refusal at sign-in, a request for confirmation such as a phone numberthese are the rules of the OpenAI account itself; Codex cannot affect them
Zukko gateway: model_not_allowed_for_keyJSON with this code; the model is not in the key's allowed listadd the model to the key or change the model in Codex
Zukko gateway: email_unverifiedJSON with this code; the email in the dashboard is not verifiedverify the email in the dashboard

It is easy to tell them apart by the text: Zukko errors end with the line "Поддержка — https://t.me/zukkopro?direct, напишите, пожалуйста" (Support: write to us on Telegram), and the code is in the error.code field. If there is no such line, the answer came from another link.

Step 1. Find out where Codex actually goes

If Codex is set up by default, it calls OpenAI, and then a 403 by region is entirely expected: regional restrictions are set by OpenAI, not by you or us. We do not suggest schemes for bypassing, faking a region or using other people's accounts: they break the service rules and can lead to a ban. The lawful route from Russia is a different provider in the config: access through the gateway, payment by SBP, a MasterCard card or crypto.

Open ~/.codex/config.toml (on Windows %USERPROFILE%\.codex\config.toml) and compare it with the standard one:

bash
model = "gpt-6.1-sol"
model_provider = "zukko"
model_reasoning_effort = "high"

[model_providers.zukko]
name = "zukko"
base_url = "https://api.zukko.pro/v1"
wire_api = "responses"
requires_openai_auth = true

Check three things. First: the line model_provider = "zukko" is in place and the name matches the [model_providers.zukko] header. Without it Codex goes to OpenAI. Second: base_url ends with /v1. Third: ~/.codex/auth.json with the key sits next to it:

bash
{ "OPENAI_API_KEY": "fetch_..." }

If you used to sign in to Codex through an account, this file may hold data from the earlier sign-in. Make a backup of the file and write the key in. According to the Zukko instructions a separate OpenAI account sign-in is not needed: the key is taken from auth.json. The automatic setup with backups is described in the Codex guide.

Step 2. About the phone number request

"Codex asks for a phone number" is most often tied to registering and verifying an account on the OpenAI side, not to Codex itself. That is an account condition, and there is no need to act around it. If you work through a gateway key, an OpenAI account is not used for requests, and such a step should not appear. If it still appears, Codex most likely did not read your config (step 1) or is run under another user with a different home directory.

Step 3. Test the key with a separate request

To separate a Codex problem from a key problem, send a request bypassing Codex:

bash
curl -i https://api.zukko.pro/v1/chat/completions \
  -H "Authorization: Bearer $ZUKKO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"model":"gpt-6.1-sol","messages":[{"role":"user","content":"ping"}],"max_tokens":16}'

Read the status code and the body:

  • 200. The key, model and balance are fine. So the 403 does not come from the gateway: go back to step 1 and check where Codex goes.
  • 403 model_not_allowed_for_key. The key has an allowed-model list and yours is not in it. Open the key in the dashboard and add the model to the list, or change model in config.toml. You can also change the model at launch: codex -m gpt-6.1-sol.
  • 403 email_unverified. Verify your email in the dashboard. With a Telegram sign-in no verification is required.
  • 401. The key has a typo or was revoked. 402. The balance is below $0.01. These are other errors, but at first glance they are often confused with 403.

If config.toml names a model that is not in the catalogue, the answer is 404 model_not_found. The current model list is public: GET https://api.zukko.pro/v1/models.

A common trap: a model Codex cannot use

According to the Zukko documentation, Codex goes through the Responses API, so GPT and Claude models fit. GLM models do not work in Codex. If you restricted a key to a GLM model to save money while Codex has GPT, you get exactly a 403. The fix is simple: for the Codex key allow the model you put in model.

It is worth knowing more about restricting keys: how to allow a key only the models it needs and error 403 model_not_allowed_for_key.

How to keep working while you sort it out

  1. Create a separate key for Codex with a daily limit and the list of models you really use. Then model_not_allowed_for_key appears where you expect it.
  2. Keep one verified model in config.toml and change it through codex -m rather than editing the file.
  3. After any config edit run a short task, for example "print the Node version in the project", and make sure an answer arrives.

To check spend, look at "Usage" in the dashboard: a request that reached the model shows up there, while a rejected 403 charges nothing.

FAQ

Why does Codex give a 403 when I have a balance?

Balance affects 402. For 403 the reason is different: region or account when calling OpenAI directly, the key's allowed-model list or an unverified email. Tell them apart by the response text and the error.code field.

Does Codex need a region bypass?

We do not advise or describe such schemes. For work from Russia use another provider in the config: access through the gateway, payment by SBP, a MasterCard card or crypto.

Can I use Codex without a ChatGPT subscription?

Yes, Codex reads its provider from the config, so you can point it at a compatible API and pay for tokens. Step-by-step setup is in the article Codex without a ChatGPT subscription.

The 403 appeared after I changed the model. What should I check?

The key's allowed-model list. The new model must be added to it, otherwise the gateway returns model_not_allowed_for_key.

zukko

Pay 25×
less

for Claude Code & ChatGPT

One fetch_* key and base URL api.zukko.pro — for Cursor, Claude Code, Codex, and any SDK.

Get API keyDocumentation

api.zukko.pro · fetch_*

Codex error 403: causes and how to fix it · Zukko