# Codex

Codex is the terminal agent from OpenAI. It uses the OpenAI Responses API. Add the exchange as a provider in a Codex profile, and start Codex with that profile.

The quickest way is the Liquid CLI. Use the manual steps only when you must keep the settings in your own files.

## Start with the Liquid CLI

The [Liquid CLI](https://inference.ai.exchange/docs/cli.md) starts Codex with the exchange as its provider. It sets the base URL, the key and the model for that process only. It writes no file of yours.

```bash
curl -fsSL https://inference.ai.exchange/cli/install.sh | bash
liquid login
liquid codex
```

| To do this                             | Add this                       |
| -------------------------------------- | ------------------------------ |
| Rank the offers by price               | `--model liquid.auto:cheapest` |
| Search the web for each message (beta) | `--model liquid.auto:web`      |
| Limit what one request can cost        | `--cap 0.50`                   |

## Before you start

- A workspace with a balance and a `spend` key. See [API keys](https://inference.ai.exchange/docs/keys.md).
- Codex 0.95 or later. Codex speaks the Responses API only from 0.95. Run `codex --version` after you install:

```bash
npm install -g @openai/codex@latest
```

## 1. Create the profile

A Codex profile is the file `~/.codex/<name>.config.toml`. With `--profile <name>`, Codex applies it on top of `~/.codex/config.toml`.

- The first block writes the profile.
- The second block has the same settings for `~/.codex/config.toml`. The VS Code extension uses that file without `--profile`.

**Profile**

```bash
cat > ~/.codex/liquid.config.toml <<'EOF'
model = "liquid.auto"
model_provider = "liquid"
web_search = "disabled"
suppress_unstable_features_warning = true

[features]
api_key_model_discovery = true

[model_providers.liquid]
name = "Liquid Inference"
base_url = "https://router.inference.ai.exchange/v1"
env_key = "LIQUID_API_KEY"
env_key_instructions = "Create a key at https://inference.ai.exchange/keys"
model_catalog_url = "https://router.inference.ai.exchange/v1/codex/models"
EOF
```

**Make it the default**

```toml
# Above the first [section] of ~/.codex/config.toml
model = "liquid.auto"
model_provider = "liquid"
web_search = "disabled"
suppress_unstable_features_warning = true

# Anywhere after it
[features]
api_key_model_discovery = true

[model_providers.liquid]
name = "Liquid Inference"
base_url = "https://router.inference.ai.exchange/v1"
env_key = "LIQUID_API_KEY"
env_key_instructions = "Create a key at https://inference.ai.exchange/keys"
model_catalog_url = "https://router.inference.ai.exchange/v1/codex/models"
```

| Setting                              | Why it is set                                                                                                                                   |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `model`                              | The model Codex starts with. See [Choosing a model](#choosing-a-model).                                                                         |
| `model_provider`                     | Selects the `[model_providers.liquid]` table.                                                                                                   |
| `web_search = "disabled"`            | Web search runs on OpenAI servers. Without this line, the exchange removes the tool and sends the header `x-liquid-notice: web_search_dropped`. |
| `api_key_model_discovery`            | Makes Codex read the model list from `model_catalog_url`. Without it, Codex never fetches the list.                                             |
| `suppress_unstable_features_warning` | Hides the start-up warning about `api_key_model_discovery`.                                                                                     |
| `base_url`                           | Ends in `/v1`, because Codex appends `/responses`.                                                                                              |
| `name`                               | The name that Codex shows for the provider.                                                                                                     |
| `env_key`                            | The variable that holds the key, so the file does not. Codex sends it as a bearer token to `base_url` and `model_catalog_url`.                  |
| `env_key_instructions`               | The text Codex shows when the variable is not set. It tells you where to make a key.                                                            |
| `model_catalog_url`                  | The model list in the format of Codex. Each entry gives the context window and the `apply_patch` tool.                                          |

Do not add `wire_api`. Codex 0.95 removed `wire_api = "chat"`.

In `~/.codex/config.toml`, TOML puts each key after a `[section]` header into that section. So:

- Put the top-level lines above the first `[section]` header.
- If the file has a `[features]` table, add the line to that table. TOML does not allow the same table twice.

## 2. Export the key

Set the key in the shell that starts Codex. To keep it, add the line to `~/.zshrc` or `~/.bashrc`.

```bash
export LIQUID_API_KEY=sk-liquid-...
```

## 3. Run it

```bash
export LIQUID_API_KEY=sk-liquid-...
codex --profile liquid
```

## 4. Check it works

Send one request without the interactive session:

```bash
codex exec --profile liquid "Reply with the word ready"
```

Codex prints the answer. The request shows under **Receipts** on the **Credits** page, with Codex as the client. See [Quickstart](https://inference.ai.exchange/docs/quickstart.md).

## Choosing a model

In Codex, `/model` lists these models, in this order:

1. `liquid.auto`, then the other router models.
2. The presets of your workspace.
3. Exact models whose offers accept tools, with the most offers first. Codex sends tools on each turn.

If the offers accept a reasoning effort, `/model` also shows low, medium and high. Codex keeps the list for 5 minutes.

To choose a model for one session, pass `--model`:

```bash
codex --profile liquid --model gpt-oss-120b
```

A model on the book but not in the list still works. Codex then shows ``Model metadata for `<model>` not found``, uses a context window of 272,000 tokens and omits `apply_patch`.

The exchange refuses a name that is not on the book. For current names, use `GET /v1/models`. See [Market data](https://inference.ai.exchange/docs/market.md).

## The cap

`liquid.auto` has a cap of its own, so Codex needs to send nothing. To set your own cap, add a header to the `[model_providers.liquid]` table, because Codex cannot send the `exchange` block:

```toml
http_headers = { "x-liquid-cap-usd" = "1.00" }
```

This sets a cap of $1 on each request, for all models. See [Auto Router](https://inference.ai.exchange/docs/auto.md).

## Purchasing rules

Codex sends the `http_headers` of the provider with each request:

```toml
[model_providers.liquid]
# ...the settings from step 1...
http_headers = { "x-liquid-cap-usd" = "0.50", "x-liquid-ttft-ms" = "3000", "x-liquid-policy" = "economy" }
```

| Header               | Sets                                                                                |
| -------------------- | ----------------------------------------------------------------------------------- |
| `x-liquid-cap-usd`   | The most one request can be charged, in USD.                                        |
| `x-liquid-ttft-ms`   | The longest wait for the first token, in milliseconds.                              |
| `x-liquid-profile`   | The workload profile.                                                               |
| `x-liquid-policy`    | The Auto preference. Ranking by price ignores it.                                   |
| `x-liquid-retention` | `none` or `allowed`: whether a provider can keep the prompt.                        |
| `x-liquid-rules`     | Any other rule, as JSON. See [Rules in one header](https://inference.ai.exchange/docs/rules.md#rules-in-one-header). |

- If the worst-case charge is more than the cap, the exchange refuses the request. It does not shrink the request, except an output limit that it chose (see [Output length](#output-length)).
- A header that the exchange cannot parse gets `400 invalid_header`.
- No header sets the models. Save them in a preset, and set `model` to the preset name. See [Purchasing rules](https://inference.ai.exchange/docs/rules.md).

## Output length

Codex sends no output limit. The exchange uses 32,768 tokens.

- It lowers the limit to the largest limit of the offers that can take the request.
- If your balance or cap is too small, it halves the limit until an offer fits, down to 1,024 tokens. It never changes a limit that the client set. See [Errors](https://inference.ai.exchange/docs/errors.md).

An answer that reaches the limit ends with `max_output_tokens`. Codex shows `Incomplete response returned` and sends the request again. The exchange charges again. If this repeats, choose a model that allows longer answers, or raise the cap.

## What isn't supported

- **Hosted tools.** The exchange removes `web_search` and runs no search. To search, add `:web` (beta) to the model name. It refuses `file_search`, `code_interpreter` and `image_generation` with `400 unsupported_parameter`. Function tools, MCP tools and `apply_patch` work.
- **Stored responses.** The exchange refuses `previous_response_id`, `conversation` and `background: true`, and ignores `store`. Codex sends the full conversation each time, so this does not affect it.

## Control the cost

The exchange sets a cap on each request before the first token. To limit total spend, set a spending limit on the Codex key. When the context window fills, Codex asks for a summary, and the exchange charges for it like any request. See [API keys](https://inference.ai.exchange/docs/keys.md).

## Troubleshooting

Codex tries a `401`, `402`, `404` or `503` response five times (`Reconnecting... 1/5`). It shows a `400` response at once.

| Symptom                                                                            | Cause and fix                                                                                                                              |
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| ``Missing environment variable: `LIQUID_API_KEY`.``                                | Export the key in this shell and start Codex again.                                                                                        |
| `unexpected status 401 Unauthorized`                                               | The key is wrong, revoked or expired. Confirm on the **API keys** page that it is active and has the `spend` scope.                        |
| `unexpected status 404 Not Found: <model> is not provided …`                       | `model_not_found`. Choose a name from `/model` or `GET /v1/models`.                                                                        |
| `unexpected status 402 Payment Required`                                           | `insufficient_balance`. Add funds on the **Credits** page.                                                                                 |
| `"code":"auto_requires_price_bound"`                                               | The model is a router model with no cap. Add the header from [The cap](#the-cap).                                                          |
| `"code":"unsupported_parameter"` with `"param":"tools[…]"`                         | Codex sent a hosted tool. Turn off the feature that adds it. See [What isn't supported](#what-isnt-supported).                             |
| ``Model metadata for `<model>` not found``, or `/model` lists OpenAI models.       | `api_key_model_discovery = true` is missing from `[features]`, or the model is not in the list. See [Choosing a model](#choosing-a-model). |
| `` `wire_api = "chat"` is no longer supported. ``                                  | Delete the `wire_api` line from `[model_providers.liquid]`.                                                                                |
| `codex --version` shows a version before 0.95.                                     | Run `npm install -g @openai/codex@latest`.                                                                                                 |
| ``--profile `liquid` cannot be used while ~/.codex/config.toml contains legacy …`` | Move your settings from `[profiles.liquid]` or `profile = "liquid"` into `~/.codex/liquid.config.toml`, then delete them.                  |
| Codex uses your usual model and no request reaches the exchange.                   | The name after `--profile` matches no file, and Codex does not report it. Run `ls ~/.codex/*.config.toml`.                                 |
