NormaHub knowledge base

Connecting Codex

Set up NormaHub as a Codex provider and get access to GPT, DeepSeek, Qwen and other models.

What is Codex

Codex is an AI coding assistant that runs in the terminal. It supports many providers through a single TOML configuration, so you can point it at any OpenAI-compatible endpoint instead of being locked to one vendor.

You can connect NormaHub as a provider and use GPT models (except Claude) directly in Codex, paying from your NormaHub balance. Russian version of this guide: Подключение Codex.

1. Get an API key

Create an API key in the NormaHub dashboard. Copy the value immediately — it is not shown again. For an autonomous coding agent, issue a dedicated key with its own spend limit: Codex generates many requests per session, and an unlimited key can surprise you at billing time.

2. Locate the Codex configuration

The Codex configuration lives in the following places:

  • Linux/macOS: ~/.codex/config.toml
  • Windows: %USERPROFILE%\.codex\config.toml

If the file does not exist, create it together with the ~/.codex/ directory.

3. Configure config.toml

Open or create the config.toml file and add the following configuration:

# BEGIN NORMAHUB CODEX ROOT
model = "gpt-5.6-sol"
model_provider = "normahub"
model_catalog_json = "/home/user/.codex/normahub-models.json"
# END NORMAHUB CODEX ROOT

# BEGIN NORMAHUB CODEX PROVIDER
[model_providers.normahub]
name = "NormaHub"
base_url = "https://api.normahub.cc/v1"
wire_api = "responses"
experimental_bearer_token = "your_api_key"
# END NORMAHUB CODEX PROVIDER

Replace your_api_key with the real key from your dashboard.

Parameter reference:

  • model — the default model
  • model_provider — the provider identifier
  • model_catalog_json — path to the file with the model catalog
  • base_url — the NormaHub API address
  • wire_api — the API format (responses for NormaHub)
  • experimental_bearer_token — your API key

4. Create the model catalog

Create the file ~/.codex/normahub-models.json with the models you want to use:

{
  "models": [
    {
      "slug": "gpt-5.6-sol",
      "display_name": "GPT 5.6 Sol",
      "description": "Available through NormaHub",
      "default_reasoning_level": "medium",
      "supported_reasoning_levels": [
        {"effort": "low", "description": "Faster responses"},
        {"effort": "medium", "description": "Balanced reasoning"},
        {"effort": "high", "description": "Deeper reasoning"}
      ],
      "shell_type": "unified_exec",
      "visibility": "list",
      "supported_in_api": true,
      "priority": 1,
      "context_window": 200000,
      "max_context_window": 200000
    },
    {
      "slug": "gpt-5.5-mini",
      "display_name": "GPT 5.5 Mini",
      "description": "Available through NormaHub",
      "default_reasoning_level": "medium",
      "context_window": 128000,
      "max_context_window": 128000
    }
  ]
}

Add models from the models catalog that you plan to use. Note: Codex does not support Claude models — use Claude Code for them.

5. Restart Codex

After saving the configuration, restart Codex completely. A running session keeps the old provider list in memory, so only a full restart picks up the new config.toml and catalog file. You can then select NormaHub models through the interface.

6. Verify the connection

Start Codex, select a NormaHub model and send a test request. If everything is configured correctly, you get an answer from the selected model. If the request fails instead, read the HTTP status first — it tells you whether the problem is the key, the balance, the model access, or a temporary outage.

Automatic setup

If you prefer not to configure everything by hand, use the ready-made install script from the GitHub repository. The script automatically downloads the model list and creates the configuration.

Common errors

  • 401 Unauthorized — invalid or revoked API key
  • 402 Payment Required — insufficient balance
  • 403 Forbidden — model not available for your key
  • 429 Too Many Requests — rate limit or spend limit exceeded
  • 503 Service Unavailable — model provider temporarily unavailable

When errors appear, check the balance and available models in the dashboard. The full code table and retry policy are covered in the API errors guide.

Troubleshooting

If the model list is empty, verify the catalog path in model_catalog_json letter by letter and make sure the JSON file parses — a single trailing comma breaks the whole list. If requests fail with 401, re-paste the key: it may have been revoked or copied with whitespace. A 403 on a specific model means the key is alive but that model is unavailable to it — pick another ID from the catalog. For 429, wait before retrying: hammering a limited key only extends the block. For 503, the upstream provider is temporarily down, so retry later rather than editing a working config.

Which models are supported

Codex through NormaHub supports GPT models:

  • GPT-5.6 Sol — flagship model with extended context
  • GPT-5.5 Mini — fast and economical model
  • Other GPT models from the NormaHub catalog

For Claude models use Claude Code instead of Codex.

Частые вопросы

Where do I get the model ID for Codex?

Use the exact ID from the models catalog or from GET /v1/models with your key. Capabilities such as reasoning levels and context size depend on the specific model — check them before switching the default.

Why do I get 401 Unauthorized?

The API key is invalid, mistyped, or revoked. Paste it again carefully and, if it persists, issue a new key in the dashboard while revoking the old one.

Codex does not list my NormaHub models. What is wrong?

Three typical causes: a wrong path in model_catalog_json, invalid JSON in the catalog file, or Codex still running with the old config. Fix the path, validate the JSON, then restart Codex completely.

Can I use Claude models in Codex?

No. Codex does not support Claude models through NormaHub. Use Claude Code for Claude models and keep Codex for GPT models.

What does 402 Payment Required mean?

Either the key owner's balance or the key's own spend limit is exhausted. These are different entities: funds may exist while the key limit is spent. Check both in the dashboard.