MindsHub in Codex
Codex is OpenAI's terminal coding agent. It speaks the Responses API, so it runs against MindsHub as a custom model provider and can drive any model in the catalog, not just OpenAI's. Codex on Claude Sonnet 5 or Kimi K3 is a small config change.
Newly supported, and not yet proven over a long session. The Responses wire format Codex needs is implemented and tested, but we have not driven a full Codex session end to end against production. Expect the setup below to work; please tell us if something in a longer session does not. One rough edge we already know about is in Troubleshooting.
Prerequisites
- Codex CLI installed. See OpenAI's install docs.
- A MindsHub API key from the console (how keys work). Create a dedicated key for Codex so it's easy to revoke.
Check your key first
Before touching Codex, confirm the key and the Responses endpoint work:
curl https://api.mindshub.ai/v1/responses \
-H "Authorization: Bearer $MINDSHUB_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "gpt", "input": "say OK"}'
A 401 means authentication failed; fix that first. A healthy response is a Responses body with "output_text": "OK".
Configure Codex
Add MindsHub as a model provider in ~/.codex/config.toml:
model = "gpt"
model_provider = "mindshub"
[model_providers.mindshub]
name = "MindsHub"
base_url = "https://api.mindshub.ai/v1"
wire_api = "responses"
auth = { command = "printenv", args = ["MINDSHUB_API_KEY"] }
Then export the key and run it:
export MINDSHUB_API_KEY="mdb_..."
codex
The four provider fields:
base_urlmust end in/v1. Codex appends/responsesitself. (This is the opposite of the Claude Code setup, where the base URL is the bare host; the two agents follow their own vendors' conventions.)authruns the given command and sends its output as the bearer token —printenv MINDSHUB_API_KEYreads the key from your environment, so the key still never goes in the config file. Command-backed auth is also what makes Codex ask MindsHub for its model catalog, which is what fills the in-session/modelpicker with your aliases; the simplerenv_key = "MINDSHUB_API_KEY"setting authenticates identically but leaves the picker on Codex's built-in list. Codex rejects a provider that sets both. (On Windows, pointcommandat anything that prints the key, e.g.powershell -Command "$env:MINDSHUB_API_KEY".)wire_api = "responses"is required. Codex removed its Chat Completions mode in early 2026.nameis a display label only.
The top-level model is the default for new sessions, and it takes a catalog alias such as gpt, sonnet, kimi, or deepseek, not a provider model ID.
Switch models
Per run:
codex --model sonnet # Claude Sonnet 5, in Codex
codex --model kimi # Kimi K3
codex --model deepseek # DeepSeek V4-Pro-0813
codex --model gpt-codex # GPT 5.3 Codex
Or keep a few profiles in config.toml and select one with --profile:
[profiles.claude]
model = "sonnet"
model_provider = "mindshub"
[profiles.cheap]
model = "deepseek"
model_provider = "mindshub"
codex --profile cheap
Inside a running session, type /model to open Codex's model picker. With the auth command config above, the picker lists the MindsHub catalog — each alias, its label underneath, and the reasoning effort levels it supports — instead of Codex's built-in OpenAI list.
Any alias from GET /v1/models works. Because every model resolves through the same key, switching costs you nothing but the edit.
Verify it
Ask Codex something trivial in a session, then confirm MindsHub metered it. The row should show the alias you ran:
curl "https://auth.mindshub.ai/v1/usage/summary/?range=period&group_by=model" \
-H "Authorization: Bearer $MINDSHUB_API_KEY"
If a row appears for your alias, the integration is working end to end: request, generation, and metering.
Cost and billing
- Codex shows token counts, not costs. Its session stats carry no MindsHub prices, so the usage summary is the only real number.
- Everything lands on one balance. Codex, Claude Code, VS Code, and your application traffic all draw the same prepaid wallet and appear in the same per-model summary.
- Agents are token-hungry. Long system prompts and large file contexts add up; see the price list and pick accordingly.
deepseekandkimiare markedly cheaper thanopusfor bulk work. - Prompt caching helps. Codex resends context each turn; the prompt cache absorbs most of that at about a tenth of the input price on most models.
Scope and limits
- Codex keeps its own context. It sends
store: falseand resends its full input every turn, so none of it is stored server-side andprevious_response_idnever comes into play. Chaining is available to other clients; see Conversation state. - Auto-compaction uses a conservative window. Codex compacts a long session when it approaches the model's context window, and MindsHub publishes a floor rather than a per-model figure, so compaction can fire earlier than a large-window model strictly needs. Raise it for a session with
model_context_windowinconfig.tomlif you'd rather keep more history. - Sampling parameters are adapted per model. If Codex sends a sampling parameter the target model doesn't take, MindsHub drops it and serves the request rather than failing, and reports it in
X-MindsHub-Dropped-Params. See Core concepts. - Reasoning round-trips, but isn't displayed live. With
include: ["reasoning.encrypted_content"]— which Codex sends — areasoningitem comes back carrying an opaque blob, so a reasoning model's tool loop stays valid across turns. Any summary arrives with that item at the end of the turn rather than streaming as it is produced, so Codex shows no live "thinking" text. Raw chain-of-thought is never exposed. Reasoning tokens bill as output.
Troubleshooting
| Symptom | Cause and fix |
|---|---|
404 or Not Found | base_url must end in /v1. |
401 | The key is wrong or revoked, or MINDSHUB_API_KEY isn't exported in the shell running codex. The auth command only reads the variable; it never stores the key. |
/model shows only OpenAI models | The provider is using env_key instead of the auth command block, so Codex never asks MindsHub for its catalog. Switch to the config above and restart Codex. |
model_not_found | model isn't a catalog alias. Check GET /v1/models: it's kimi, not kimi-k3. |
| Requests fail only when streaming | Confirm wire_api = "responses". A provider left on a chat wire will not work. |
| Replies truncate mid-answer | The model's internal reasoning used the output budget. Choose a model with adjustable reasoning effort, or raise the output cap. |
429 | Throughput limit, not funding. Back off; see Rate limits. |
| "We're currently experiencing high demand" with no other detail | Codex maps most non-2xx responses to one generic retryable error and retries the turn silently before reporting this, so the real cause is hidden. It is usually a rate limit or an exhausted balance: check usage and balance, and try the same request with curl to see the actual error body. |
See also
- Coding agents: Claude Code and Codex side by side, with model-choice guidance.
- Responses API: the format Codex speaks, in full.