You put base_url in ~/.codex/config.toml, added wire_api = "chat", pointed it at Ollama or z.ai or your LiteLLM gateway, and either got a hard error or watched a session that never called any tools.
You went looking for what changed. You found guides insisting the config is fine, a vendor blog selling a translation gateway, and one GitHub discussion where an OpenAI maintainer says this whole recipe was removed four months ago.
Almost every guide that ranks for codex config toml was written before that removal, or by someone who did not re-test after it.
This piece is what came back after doing the work: the exact discussion and PR that killed the old recipe, which guides are still repeating it and when, the real threads of people hitting the wall, and the second config key that will fail silently even after you fix the first one.
Verified against the codex-rs source on main and the rust-v0.150.0-alpha.8 release (24 August 2026), live GitHub discussions and issues, and current vendor documentation on 25 August 2026. Anywhere a claim comes from a secondary source rather than the code, I say so.
TL;DR
wire_api = "chat" was removed in February 2026 and is now a hard error. The discussion is #7782 (opened 9 December 2025, 74 thumbs-down, 8 confused reactions on the announcement), and the removal PR is #10157. The current source has a removal-error constant that links back to that discussion and tells you to switch to wire_api = "responses".
ollama-chat was removed with it. The current provider handler expects Ollama to speak Responses. Ollama maintainers said they were "planning to add support for the Responses API" in December 2025. Check the current status before assuming it landed.
Two vendor blogs published in the same week gave the opposite answer. ofox.ai's 8 June 2026 FAQ still says "both 'responses' and 'chat' are accepted" and recommends wire_api = "chat" for third-party gateways. morphllm.com, one day later, says Responses is the only supported value. Same week, opposite answer, on a checkable binary question.
model_context_window = 1000000 is accepted, and then ignored. Codex reports back about 258,400 for gpt-5.5. No error, no warning. Setting it also breaks auto-compaction in Codex 0.116 and 0.117.
Every "Codex works with any OpenAI-compatible endpoint" claim is wrong. Chat-Completions-compatible is not Responses-compatible. LM Studio, LiteLLM, vLLM, z.ai / GLM, and llama.cpp all show up in issues with the same shape of failure. llama.cpp works because llama.cpp's server translates Responses into Chat Completions internally, which is llama.cpp's compatibility, not Codex's.
The one non-OpenAI recipe OpenAI ships is Azure. The advanced-config docs give a complete provider block using wire_api = "responses" and an api-version query param. It is the only third-party target with a working reference config on the OpenAI side.
Precedence between env vars, config keys, profiles and CLI flags is undocumented. CLI overrides land as a dotted-key layer in codex-rs/config/src/overrides.rs, and that is the only ordering statement anyone can point at in the source.
The removal, in one thread and one PR
The wire protocol conversation lives in openai/codex discussion #7782, opened by etraut-openai (Maintainer) on 9 December 2025. Verbatim from the opening post:
"As a result, the Codex team is deprecating support for the
chat/completionsAPI. Full removal is slated for early February 2026."
"The Codex CLI will be updated to emit a deprecation warning if configured to use the
chat/completionsAPI. In February 2026, this will transition to a hard error as support is fully removed."
Removal landed. bfroemel, in-thread on 5 February 2026: "and it's gone :/" linking PR #10157. A maintainer had confirmed in mid-January that the removal was scheduled for 1 February and that chat was live until then.
The current source carries removal constants rather than deprecation strings. From codex-rs/model-provider-info/src/lib.rs on main:
CHAT_WIRE_API_REMOVED_ERROR:
`wire_api = "chat"` is no longer supported.
How to fix: set `wire_api = "responses"` in your provider config.
More info: https://github.com/openai/codex/discussions/7782
OLLAMA_CHAT_PROVIDER_REMOVED_ERROR:
`ollama-chat` is no longer supported.
How to fix: replace `ollama-chat` with `ollama` in `model_provider`,
`oss_provider`, or `--local-provider`.
More info: https://github.com/openai/codex/discussions/7782The older path codex-rs/core/src/model_provider_info.rs at commit d886a86 still holds CHAT_WIRE_API_DEPRECATION_SUMMARY, the softer warning from the deprecation window. Both states are in the repo, so you can point at the exact commit where the language went from "will soon be removed" to "is no longer supported."
There is a documented instance of OpenAI's own docs teaching people the dead value a month after removal. Issue #13628, reported around 5 March 2026 and labelled CLI + custom-model + documentation, notes that the public config reference listed wire_api as chat | responses while the generated JSON schema had "default": "responses". The reporter's framing is the useful part: it "makes it hard to build an accurate config.toml reference from the official sources."
One correction from the same discussion, from jemshit on 24 January 2026: wire_api goes under [model_providers.x], not under [profiles.x]. People get this wrong.
The guides that are still telling you the removed answer
Naming names, because the piece is useless without them.
ofox.ai, 8 June 2026 (ofox.ai/blog/codex-cli-custom-model-providers-byo-setup/), in a FAQ headed "Does Codex CLI still support wire_api = 'chat' in 2026?":
"Yes, both 'responses' and 'chat' are accepted."
Four months after removal. It goes further and tells readers to "set wire_api = 'chat'" for third-party gateways, and to fix a 404 on /responses by switching to chat. That advice now produces a hard error. The post is also a funnel for ofox.ai's own gateway, so treat both facts as related.
morphllm.com, 9 June 2026 gets it right, one day later: "responses is the only supported value, and it is the default when omitted."
dev.to/rkttu, around 26 May 2026 also correct, and cites the source file: the WireApi enum in codex-rs/model-provider-info/src/lib.rs has one variant.
Same week, opposite answers, on a binary and checkable question. That is the state of the top-of-page result for anyone Googling how to configure Codex for a non-OpenAI provider.
What actually breaks when you point Codex at a non-OpenAI model
Every one of these is a real thread with a version number.
LM Studio. FVilli, 28 January 2026, LM Studio 0.3.39 + codex-cli 0.92.0. /v1/responses works via curl non-streaming. Codex streaming over Responses fails. Legacy chat works fine. Maintainer reply the same day: it worked three weeks earlier, so either Codex or LM Studio regressed. LM Studio is the officially recommended local path in the announcement thread, and it broke.
LiteLLM. FedorenkoCodes, 29 January 2026, codex 0.92.0 against a LiteLLM 1.75.8 and 1.80.15 Azure gateway. With wire_api = "chat" it chats but never calls tools. With wire_api = "responses" it does not connect at all. Still being asked about by enghalim on 23 April 2026. Read that pair together: the working config has no tools, and the tools config has no connection.
vLLM and llama.cpp. montvid, 10 February 2026: vLLM 15.1 does not work, and the latest compiled llama.cpp does not work with Responses. The following day he corrects himself, because llama.cpp "kind of works" thanks to its server converting Responses requests into Chat Completions server-side. Source: llama.cpp's own tools/server/README.md. So llama.cpp support is a shim inside llama.cpp, not support inside Codex.
z.ai / GLM. gaoconggit, January 2026: works on codex 0.80.0, breaks on later versions. Root cause he found: {"error": {"code": "1214", "message": "Incorrect role information"}} on glm-4.7.
Tool calling on custom providers. Issue #30523 reports that custom-provider dynamic tools end turns without a function_call. I have not verified the current state of that issue, so treat it as reported rather than known-open.
The 300-second stall. Issue #23807: "codex-cli stalls for exactly 300s between tool result and next model request (stream disconnected)." Marked as my own inference rather than sourced: 300s is exactly the documented stream_idle_timeout_ms default of 300000. Worth testing whether the stall is the idle timeout firing on a gateway that never sends keepalives.
A named tool-format incompatibility. A recent opper.ai post claims Codex ships some tools in OpenAI-specific formats, freeform grammar custom tools among them, and that non-OpenAI upstreams reject those payloads. They also mention features.multi_agent = false for third-party backends. INDEPENDENT vendor testimony, and the vendor sells a routing product, so it is interested. I could not trace features.multi_agent to the repo, so it stays flagged.
The shape underneath these is one thing: Codex is speaking Responses at an endpoint that has not implemented it, or has implemented it incompletely, or has implemented a translation layer that leaks on tools. Reading them as five different bugs will send you in circles. There is one bug, and it has five surfaces.
The 1M context window that isn't
This is the second key that will accept your config and ignore it. It is less loud than the wire-api removal, so more people run into it, and fewer people notice.
The keys exist. model_context_window and model_auto_compact_token_limit are real and documented. They do not do what the guides claim.
Issue #19185, around 23 April 2026, "config.toml context window settings are not respected." Windows, gpt-5.5, this config:
model_context_window = 960000
model_auto_compact_token_limit = 800000Result: Codex still uses about 258k. The reporter's ask is the sharp part. Either honour the value, or emit a validation error. Instead "the configured value is silently reduced/ignored."
Maintainer position, attributed to etraut-openai on issue #19409: Codex supports a 400K context window for gpt-5.5, does not support 1M, and the default input context for gpt-5.5 is 258,400 to leave compaction margin. I have this via a secondary write-up rather than directly from the issue, so treat as reported.
Some related shape from the same period, all secondary or partial and flagged:
- Issue #14133:
model_context_windowis honoured by terminalcodex execand silently ignored by Desktop GUI threads. Secondary source only. UNVERIFIED against the issue itself. - Issue #19208, around 23 April 2026: 1M worked on GPT-5.4, disappeared when GPT-5.5 shipped, despite GPT-5.5 marketing 1M. Config in the report includes
personality = "pragmatic", which is a live lead for a separate piece. - Issue #16068, around 28 March 2026, codex-cli 0.117.0 and 0.116.0, gpt-5.3-codex, macOS: setting
model_context_windowbreaks auto-compaction becausefill_to_context_windowresets the token counter. So the key does not just fail, it damages something adjacent. - Issue #31860: GPT-5.6 Sol catalog-capped at 372K, 353.4K effective, against a 1.05M model spec.
The guides disagree with each other over time. yigitkonur, 15 April 2026: "add these two lines to ~/.codex/config.toml" and you have 1M. trilogyai.substack.com, around 20 August 2026: "this guide needs more than one TOML setting" and uses a third key, model_catalog_json, pointing at a custom model catalog file.
model_catalog_json is UNVERIFIED against the current source. If it is real, it is the current working answer and it is barely written about. If it is not, that Substack is the newest guide to fail. Check the repo before you follow either.
One pricing detail from trilogyai worth flagging without repeating: they claim that past 272K input tokens OpenAI bills input at 2x and output at 1.5x for the entire request, not just the overage, citing the GPT-5.6 Sol model page. Verify on the model page before quoting.
The through-line with the wire-api removal is the one worth internalising. One key fails loudly and you have a chance to fix it. The other fails silently, and every guide telling you to raise your context window is describing a number Codex clamps without saying so. Both leave people debugging the wrong layer.
The provider block, field by field
Sourced from codex-rs/model-provider-info/src/lib.rs on main. I confirmed the file exists at that path and confirmed the removal constants and the WireApi enum. I did not independently enumerate every field, so spot-check the ones you actually put in a config.
Top-level fields on a [model_providers.<id>] block:
name, base_url, env_key, env_key_instructions, experimental_bearer_token, auth, aws, wire_api, query_params, http_headers, env_http_headers, request_max_retries, stream_max_retries, stream_idle_timeout_ms, websocket_connect_timeout_ms, requires_openai_auth, supports_websockets, supports_standalone_web_search.
Two nested blocks:
[model_providers.<id>.auth]withcommand,args,timeout_ms,refresh_interval_ms.[model_providers.<id>.aws]withprofile,region, and a refresh block.
Documented defaults from developers.openai.com/codex/config-reference: request_max_retries 4, stream_max_retries 5, stream_idle_timeout_ms 300000. wire_api defaults to responses. The three booleans default to false.
Azure is the only non-OpenAI target with a full reference block. developers.openai.com/codex/config-advanced gives it with base_url, env_key, env_key_instructions, wire_api = "responses", and an api-version query param. Everything else you configure, you configure without a working example on the OpenAI side.
There is an Amazon Bedrock Mantle base URL and client-agent header constant in the source (bedrock-mantle.us-east-1.api.aws/openai/v1), which suggests first-party Bedrock handling that nobody is writing about yet. Marked as a lead rather than a recipe.
Precedence across env vars, config keys, profiles, and CLI flags is not documented. codex-rs/config/src/overrides.rs shows CLI overrides applied as a separate layer using dotted keys. That is evidence of a layer, not a spec. Do not read a single unified ladder into this. Any guide that draws you one is inventing it, the same way the Claude Code advice invents a unified precedence stack across CLAUDE.md, skills, hooks and settings that also does not exist.
Where public consensus is wrong
Seven checkable corrections, most with an issue number and a date.
- "Set
wire_api = 'chat'for third-party gateways." Removed February 2026. Hard error. ofox.ai still says this on 8 June 2026. - "Point Codex at Ollama."
ollama-chatremoved. The Ollama Responses support promised in December 2025 needs a current status check before you assume it landed. - "Codex works with any OpenAI-compatible endpoint." Chat-Completions-compatible is not Responses-compatible. That is the whole failure mode.
- "llama.cpp works." llama.cpp translates Responses to Chat Completions server-side. The compatibility is theirs.
- "Add two lines for 1M context." Silently clamped to about 258K. No error. Broke auto-compaction in 0.116 and 0.117.
- "The docs say the default is chat." The docs said that, the schema said responses, and issue #13628 is the receipt.
- "You can reach Claude or Gemini by setting
base_url." Not natively. Responses-only enum in the source. Everything that works is a translation shim.
Frequently asked questions
- Does Codex CLI still support wire_api = 'chat' in 2026?
- No. The chat/completions wire protocol was deprecated in Codex discussion #7782 on 9 December 2025 and fully removed in PR #10157 in early February 2026. The current source in codex-rs/model-provider-info/src/lib.rs carries a removal-error constant that fires at startup if wire_api is set to 'chat', pointing you at the same discussion. The only supported value is 'responses', and it is the default when the key is omitted. Guides published after February 2026 that tell you otherwise, including ofox.ai's June 2026 FAQ, are wrong.
- How do I point Codex CLI at Ollama?
- You use the ollama provider, not ollama-chat. The ollama-chat provider was removed with wire_api = 'chat' in February 2026 and now hard errors, telling you to switch. The remaining ollama provider expects Ollama to speak the Responses API. Ollama maintainers said in December 2025 that they were planning to add Responses support; check the current Ollama release notes before assuming that landed, because the December 2025 announcement did not include a shipping date.
- Why is my model_context_window setting ignored?
- Because Codex accepts the value at parse time and silently clamps it at runtime. Issue #19185, reported around 23 April 2026, shows model_context_window = 960000 for gpt-5.5 still using about 258,400 tokens with no error and no warning. A maintainer response attributed to etraut-openai on the related issue #19409 says Codex supports a 400K context window for gpt-5.5, not 1M, and defaults gpt-5.5's input context to 258,400 to leave compaction margin. Issue #16068 also reports that setting model_context_window breaks auto-compaction in Codex 0.116 and 0.117 because fill_to_context_window resets the token counter.
- Can I use Codex CLI with Claude, Gemini, or other non-OpenAI models?
- Not directly. Codex CLI speaks one wire protocol, Responses, and the WireApi enum in codex-rs/model-provider-info/src/lib.rs has one variant. To reach a non-Responses backend you need a translation layer in front, and every reported success falls into that category: LiteLLM as a gateway, llama.cpp's server translating Responses into Chat Completions internally, or a vendor routing product. The only non-OpenAI target OpenAI itself ships a reference config for is Azure OpenAI, in the advanced-config docs, and Azure OpenAI speaks Responses natively.
- Where does wire_api belong in config.toml?
- Under [model_providers.<id>], not under [profiles.<id>]. This came up in Codex discussion #7782 on 24 January 2026 and is a common mistake. A profile can reference a model provider by id, but the wire protocol is a property of the provider itself. Setting wire_api inside a profile block will not do what you expect, and now that the only valid value is 'responses' anyway, the field is only worth setting explicitly if you are documenting intent.
- What is the precedence between env vars, config.toml, profiles, and CLI flags?
- Not documented as a single ordering. codex-rs/config/src/overrides.rs applies CLI overrides as a separate dotted-key layer, and env vars are read at various providers. Any guide that draws you a unified precedence ladder is inventing it. If a specific setting is not behaving as you expect, override it explicitly on the CLI for the run in question and file an issue if the behaviour still does not match the layer you expected to win.
The question the reference posts keep dodging
Every guide tells you which keys to add.
None of them tell you which keys will be quietly ignored.
That asymmetry is the actual problem. wire_api = "chat" is loud, so it will be noticed and eventually the guides will catch up. model_context_window is quiet, so a year from now people will still be pasting = 1000000 into their config and reporting back that Codex "works with 1M context on gpt-5.5", because it took the value without complaining. There is no /doctor in Codex that will read back the config and tell you which of your keys made it to runtime and which were parsed and dropped. That is the missing piece, and it is worth more than another provider recipe.
Until that lands, the working discipline is small and manual. Assume every key you set was accepted, silently ignored, or silently reduced. Confirm the runtime value before you build on top of it. When a config change appears to do nothing, treat "the config did nothing" as the primary hypothesis rather than a last resort.
The same rule applies on the Claude Code side, where I have written about instructions that look loaded and are not and about hooks that fire and do nothing. Codex CLI is the version of that failure at the config layer.
What I built for this
anvil is a set of Claude Code skills that treat context as a budget. It does not run against Codex. I mention it because the discipline is the same one this piece calls for: every line in a config or context file is paid for on every run, so the default answer to "should I add this?" is no, and there has to be a mechanism that removes lines as well as one that adds them.
For Codex today, the equivalent mechanism is you, checking what the runtime actually did with what you wrote.
Start by doing this
2 mins: Open ~/.codex/config.toml and grep for wire_api = "chat" and ollama-chat. If either is there, replace with wire_api = "responses" and ollama respectively. Both now hard error on startup with a link to discussion #7782.
5 mins: If you set model_context_window above 400,000 for gpt-5.5, expect it to be clamped to around 258,400. Start a session and confirm the runtime context window Codex reports back before you rely on the value. Note the Codex version, since 0.116 and 0.117 also break auto-compaction when this key is set.
10 mins: For any non-OpenAI provider block you have, name the translation layer in a comment above the block. Is it Azure (native Responses), LiteLLM (gateway), llama.cpp (server-side conversion), or a vendor router? If you cannot name one, that is your first debugging step. The failure mode looks like five different bugs and is one.
Then: if you are wondering what a context-as-budget discipline looks like on the Claude Code side, anvil is the mechanism, and docs/FILE_CONTRACT.md is the whole thing written down. Section 1 is the load-bearing one.