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"
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_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.)
  • env_key names 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.
  • 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

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.
  • 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. Remember env_key names the variable, not the value.
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