Codex CLI
Codex CLI is OpenAI’s terminal coding agent. It reads a TOML config, so you can add MirAPI as a custom model provider without a plugin.
What you need
Section titled “What you need”| Element | Value |
|---|---|
| Base URL | https://api.mirapi.ai/v1 (Codex appends /responses itself) |
| API key | MIRAPI_API_KEY, referenced by env_key |
| Wire API | responses (the only value Codex currently accepts) |
Configure
Section titled “Configure”- Create a key in https://platform.mirapi.ai → API Keys and export it:
export MIRAPI_API_KEY=sk-...- Add a provider block to
~/.codex/config.toml(or$CODEX_HOME/config.toml):
model = "deepseek-chat"model_provider = "mirapi"
[model_providers.mirapi]name = "MirAPI"base_url = "https://api.mirapi.ai/v1"env_key = "MIRAPI_API_KEY"wire_api = "responses"- To leave the default config untouched, save this block as
~/.codex/mirapi.config.tomlinstead and launch the CLI with the profile flag:
codex -p mirapiVerify with a message
Section titled “Verify with a message”codex exec "Reply with exactly: connected to MirAPI"The reply should contain connected to MirAPI. Every HTTP error message ends with a MirAPI request id; keep it when you report an issue.
Configuration reference
Section titled “Configuration reference”| Key | Purpose | Value for MirAPI |
|---|---|---|
model |
Model ID the CLI requests | "deepseek-chat", verbatim from GET /v1/models |
model_provider |
Which provider block to use | "mirapi" |
name |
Display name in the CLI | "MirAPI" |
base_url |
Base URL Codex appends /responses to |
https://api.mirapi.ai/v1 |
env_key |
Environment variable holding the key | MIRAPI_API_KEY |
wire_api |
API dialect Codex speaks | "responses" (the only supported value) |
model_reasoning_effort |
Optional reasoning strength for reasoning models | "low", "medium", "high" |
Protocol and capabilities
Section titled “Protocol and capabilities”Codex speaks the OpenAI Responses API (POST /v1/responses) on MirAPI’s OpenAI-compatible surface at https://api.mirapi.ai/v1. Codex cannot reach Anthropic’s /v1/messages or Gemini’s generateContent, because wire_api = "responses" is the only dialect it accepts.
What works through this path when the chosen model supports it:
- Tool calling via the OpenAI
tools/tool_choiceformat. - Structured outputs via
response_format(json_schema / JSON mode). - Web search for models that advertise the capability in the catalog.
- Reasoning, with strength set by
model_reasoning_effort; reasoning tokens are billed as output. - Prompt caching, enabled automatically for OpenAI-compatible models.
Responses stream as standard SSE (data: lines, ending with data: [DONE]).
Errors and troubleshooting
Section titled “Errors and troubleshooting”| Status | Meaning | What to do |
|---|---|---|
| 401 | Key missing, invalid, or unknown | Fix the exported MIRAPI_API_KEY |
| 403 | Key valid but rejected (balance, whitelist, quota, or IP) | Resolve the cause, then retry |
| 413 | Payload too large | Reduce the request size |
| 429 | Rate limited | Jittered exponential backoff (1s→2s→4s, cap ~30s); no Retry-After header |
| 500 | Gateway or upstream error | Idempotent requests can be retried safely |
The gateway does not retry on your behalf. Errors use the OpenAI envelope {"error":{"message","type","param","code"}}, where type is new_api_error (gateway) or upstream_error (upstream failure, message sanitized). Every message ends with the MirAPI request ID; include it in support tickets.
Billing
Section titled “Billing”MirAPI billing is prepaid: you top up a USD balance in https://platform.mirapi.ai. There is no subscription, monthly fee, or minimum spend, and the balance never expires. Chat usage is metered per token (input, output, and cache read), and reasoning tokens count as output. When the balance runs out, requests return 403. Top up and the same key works again immediately. Reconcile usage in the Platform billing log, GET /api/usage/token (account-level summary), or GET /api/log/token (per-request detail).
Troubleshooting
Section titled “Troubleshooting”wire_apimust be"responses". The"chat"value was removed; a config with it fails to load.- The base URL must end in
/v1. Codex appends/responsesto whatever you give it, so a barehttps://api.mirapi.aiproduces a wrong path. - Model names are verbatim.
model = "deepseek-chat"must matchGET /v1/modelsexactly. - 403 from a valid key usually means the model is not on the key’s whitelist or the balance is exhausted. Top up or adjust the key, then retry.
- 401 usually means the CLI cannot read the key. Confirm that
MIRAPI_API_KEYis exported in the shell that starts Codex.