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"
env_key = "MINDSHUB_API_KEY"
wire_api = "responses"
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.)env_keynames the environment variable Codex reads the key from. It does not hold the key itself, and the key never goes in the config file.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
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. - 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. Remember env_key names the variable, not the value. |
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.