Skip to main content

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

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_url must end in /v1. Codex appends /responses itself. (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.)
  • auth runs the given command and sends its output as the bearer token — printenv MINDSHUB_API_KEY reads 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 /model picker with your aliases; the simpler env_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, point command at 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.
  • name is 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. deepseek and kimi are markedly cheaper than opus for 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: false and resends its full input every turn, so none of it is stored server-side and previous_response_id never 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_window in config.toml if 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 — a reasoning item 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

SymptomCause and fix
404 or Not Foundbase_url must end in /v1.
401The 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 modelsThe 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_foundmodel isn't a catalog alias. Check GET /v1/models: it's kimi, not kimi-k3.
Requests fail only when streamingConfirm wire_api = "responses". A provider left on a chat wire will not work.
Replies truncate mid-answerThe model's internal reasoning used the output budget. Choose a model with adjustable reasoning effort, or raise the output cap.
429Throughput limit, not funding. Back off; see Rate limits.
"We're currently experiencing high demand" with no other detailCodex 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