# Liquid CLI

Liquid CLI is the `liquid` command. It starts the coding agent that you already use, with the exchange as its provider, and manages your API keys and balance.

## Start in three commands

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

1. The installer checks the checksum and puts `liquid` in `~/.local/bin`. It supports macOS and Linux, on Intel and Arm.
2. `liquid login` opens your browser. After you approve, it makes an API key for this computer and saves it.
3. `liquid claude` starts Claude Code. `liquid codex`, `liquid opencode` and `liquid goose` start the other agents.

To limit spending, add `--cap`, the most that one request can cost in USD. The exchange charges the tokens used, never more than the cap.

```bash
liquid claude --model liquid/auto:cheapest --cap 0.50
```

## Start a coding agent

`liquid <tool>` starts the agent that is on your `PATH`. It sets the base URL, the key and the model in the environment of that process only. It writes no file of yours. `liquid tools` lists every agent. Any argument that `liquid` does not use goes to the agent unchanged:

```bash
liquid claude --model liquid/auto -p "explain this repository"
liquid codex --cap 0.50 exec "say ready"
```

| Flag          | Effect                                                  |
| ------------- | ------------------------------------------------------- |
| `-m, --model` | The model for this run. The default is `liquid model`.  |
| `--cap <usd>` | The most that one request may cost in this run, in USD. |

For Claude Code, the first argument can set two models as `main/sub`. The first runs the main agent. The second runs subagents and background calls. One model alone runs everything. With no argument, your saved model and `liquid.auto` do this, or `opus/auto` if you saved no model.

```bash
liquid claude opus/auto
liquid claude opus           # same as opus/auto
liquid claude glm/glm        # glm-5.3 for everything
```

| Alias    | Model               |
| -------- | ------------------- |
| `opus`   | `claude-opus-5-5`   |
| `fable`  | `claude-fable-5-1`  |
| `sonnet` | `claude-sonnet-5-5` |
| `haiku`  | `claude-haiku-5-5`  |
| `kimi`   | `kimi-k3`           |
| `glm`    | `glm-5.3`           |
| `argon`  | `gemini-4-argon`    |
| `astra`  | `gpt-6-astra`       |
| `qwen`   | `qwen3.8-max`       |
| `auto`   | `liquid.auto`       |

You can use a model id on either side of the `/`, and `--model` accepts an alias. The `auto` alias is the [Auto Router](https://inference.ai.exchange/docs/auto.md) model. It does not turn on the auto mode of Claude Code. Add `--permission-mode auto` for that.

To save your own alias, run `liquid model alias <name> <model>`. You cannot reuse the name of a built-in alias.

```bash
liquid model alias fast haiku      # save `fast` for claude-haiku-5-5
liquid model alias fast off        # remove it
```

OpenCode takes the same `main/sub` argument. The second model runs the `general` and `explore` subagents and small calls. If a folder with that name exists, OpenCode opens it as the project, and the name sets no model.

`liquid claude` keeps its settings and history in `~/.config/liquid/claude`, apart from a plain `claude`. See [A separate config directory](https://inference.ai.exchange/docs/connect-claude-code.md#a-separate-config-directory). Each `liquid claude` and `liquid opencode` session also has the [Liquid MCP server](https://inference.ai.exchange/docs/connect-mcp-server.md), so the agent can buy images, speech and video.

For a desktop app or an SDK, run `liquid connect cursor` to print the setup. To run any program with the exchange in its environment, use `exec`:

```bash
liquid exec -- python app.py
```

To send one request from a shell or a script, use `api`. It adds the key and the origin, so a script never holds either:

```bash
liquid api GET /v1/models
liquid api POST /v1/chat/completions -d '{"model":"liquid.auto","messages":[{"role":"user","content":"hi"}]}'
liquid api POST /v1/audio/transcriptions -F file=@clip.wav -F model=whisper-large-v3
```

The reply goes to stdout as the exchange sends it, a stream included. `-d @file` reads the body from a file and `-d @-` from stdin. A body is JSON unless `-H 'Content-Type: ...'` says otherwise. `-F name=@file` sends a multipart form, as `curl -F` does. A reply that is not 2xx exits with 1 and prints the status to stderr. The command takes a path and never a URL, because the host is the point: the key goes to the exchange alone.

When a tool ends, `liquid` prints the request count, the cost and the largest charge against your cap. It prints this only at a terminal with a saved key.

## Choose a model

```bash
liquid model                        # list the models, then pick the default
liquid model liquid/auto:fastest    # save a default that ranks offers by speed
liquid model liquid/auto:smartest+web  # also search the web (beta)
liquid model --list                 # print a table, with no prompt
liquid model --json                 # print the list as JSON
```

At a terminal, `liquid model` shows a searchable list with the name, kind (model, router model or preset) and context window.

To rank the offers, add `:premium`, `:balanced`, `:economy`, `:smartest`, `:fastest` or `:cheapest`. See [Axis routing](https://inference.ai.exchange/docs/axis-routing.md) and [Purchasing rules](https://inference.ai.exchange/docs/rules.md).

`+web` searches the web for each message. Web search is in beta and adds a small fee to each search. The command offers it only when the exchange has a search service. In the menu, press `w` on the ranking list to turn it on or off.

## Set a cap and other settings

```bash
liquid cap 0.50                     # the most one request may cost
liquid cap off
liquid zdr off                      # allow providers that may keep content
liquid zdr on                       # use only providers that keep no content (the default)
liquid config                       # a menu, or a table without a terminal
liquid config rank economy          # how router models rank offers
liquid config effort high           # reasoning effort; `off` removes a setting
liquid config ttft 2000             # the slowest first token, in milliseconds
liquid config rules region_policy=eu  # one purchasing rule; name=off removes it
liquid config rules '{"region_policy":["eu"]}'  # or all rules, as JSON
liquid config context 1m            # the context window to tell Claude Code
liquid config claude-share instructions,plugins  # what liquid claude shares
```

A setting applies to every tool that `liquid` starts. A flag on one run, such as `--model` or `--cap`, takes priority. Only some tools use some settings:

- `rank` and `cap` reach every tool. `rank` applies only to a router model name that has no ranking of its own.
- `effort` reaches Codex. Claude Code chooses its own effort.
- `context` reaches Claude Code. Claude Code does not know a model with a `cc.anthropic/` prefix, so without it, it assumes 200k tokens and compacts the session too early.
- `claude-share` reaches Claude Code. It takes `instructions`, `plugins` and `settings`, or `none`.
- `ttft` and `rules` reach Claude Code, Codex, OpenCode, Pi, Z Code and curl, as headers. `rules` sends the JSON as the `x-liquid-rules` header and cannot set `exchange.candidates.models.allow` or `exchange.rank.strategy`. See [Purchasing rules](https://inference.ai.exchange/docs/rules.md).

## Manage keys, balance and jobs

```bash
liquid keys list
liquid keys create ci --scope spend --spend-limit 20 --period month
liquid keys revoke <key-id>
liquid workspace balance
liquid workspace usage --days 30
liquid job
liquid job <job-id>
```

- The `keys` commands need a token from `liquid login --keys`. A key that you do not save with `--save` is shown once. See [API keys](https://inference.ai.exchange/docs/keys.md) for scopes and limits.
- `liquid workspace balance` shows what the workspace can spend. `usage` shows the last 1 to 90 UTC days, in total and for each model. Both accept `--json`.
- `liquid job` lists settled jobs, newest first. At a terminal, type to filter and press Enter for details. `--days` (1 to 90, default 7) widens the list. It uses your saved API key, which needs the `spend` or `read` scope.

## Run `liquid` with no command

The command opens a menu to start a tool, pick a model, read the workspace and set the cap. With at least 80 columns and 24 rows, the full-screen menu opens. Press `/` or Ctrl-K to search. Otherwise you get a classic list. Use `--classic` or `--tui` for one run, or `liquid config ui classic|tui|auto` to save the choice.

## Reference

### Sign in

`liquid login` saves a token for the command, then makes an API key named after your computer and saves it for the coding agents. The key can spend the balance of the workspace. The token cannot place jobs.

Only an owner or an admin can approve a token that makes keys, and that token lasts one day. A member saves a key that an owner or admin made:

```bash
liquid login --key sk-liquid-...
```

A computer with a saved key gets a read-only token for 30 days. Add `--keys` to let it manage API keys, and `--write` to let it change guardrails.

The command saves settings in `~/.config/liquid/config.toml`, with mode `0600`. `LIQUID_API_KEY` and `LIQUID_BASE_URL` override the file. `liquid logout` removes the saved keys and tokens of every workspace. `liquid logout <workspace>` removes those of one workspace.

### A key for each run

An agent that holds the saved key can send it to any host that it guesses. So `liquid <tool>` and `liquid exec` do not give the agent the saved key. Each run asks the exchange for a **session key**, made by the saved key, and gives the agent that. A session key has the scope, the preset and the addresses of the saved key. It ends when the run ends, and after 24 hours in any case, so a leak costs at most the rest of one run. The saved key stays in the config file and never enters the agent's process.

Session keys show in the key list with the name of the run, such as `liquid opencode 2026-11-06 19:04`. A revoke of the saved key revokes its session keys. A session key cannot make another, so `liquid` inside a run uses the key of the run. The exchange makes no session key for a key with a spend limit, because the limit counts one key, and the run then uses the saved key and says so.

Each run also tells the agent where the key works. `LIQUID_BASE_URL` holds the origin of the exchange next to `LIQUID_API_KEY`. Claude Code gets a note at the end of its system prompt, and OpenCode an instruction file at `~/.config/liquid/opencode/AGENTS.md`, that the key works only at that origin and that `liquid api` sends a request from a shell.

To give the agent the saved key itself, run `liquid config session-key off`.

### Switch between workspaces

Each sign-in is for one workspace. The command keeps the token and key of each one. A workspace shows as `Organization › Workspace`.

```bash
liquid whoami                    # where commands act now
liquid workspace list            # every saved workspace
liquid workspace use acme        # switch by handle, name, or a part of either
liquid --workspace acme claude   # act in another workspace for one command only
LIQUID_WORKSPACE=acme liquid job # the same, from the environment
```

To add a workspace, run `liquid login` and pick it on the approval page. Then make a new API key or paste one that you have, because the exchange shows a secret once. In the menu, press `w` to switch. A command with `--workspace` does not change the saved workspace, and a command that writes settings refuses it.

### One key for each workspace

An API key spends the balance of one workspace. The command keeps one saved key for each workspace, and the agents use the key of your sign-in workspace.

- **You sign in to a different workspace.** The command uses the saved key of that workspace, or makes one. A token that cannot make keys makes none. Run `liquid login` again or use `liquid login --key`.
- **An agent starts.** The command asks the exchange which workspace the key spends from. If it differs from your sign-in workspace, or the exchange cannot answer, no agent starts. If the exchange names no workspace, the agent starts with a warning.
- **You set `LIQUID_API_KEY`.** The command does the same check when you are signed in.
- `liquid claude` does not start if a `.claude/settings.json` or `.claude/settings.local.json` file (current folder, parent folders or home) sets `ANTHROPIC_AUTH_TOKEN`, `ANTHROPIC_API_KEY` or `ANTHROPIC_BASE_URL` in `env`. Such a value can replace the key and router.

### Install and update

Set `LIQUID_INSTALL_DIR` to change the install directory (default `~/.local/bin`). Set `LIQUID_CLI_VERSION`, for example `1.6.0`, to install that version. `liquid update` replaces `liquid` with the newest version after it checks the checksum. Other commands check once a day and print one line if a newer version exists. Set `LIQUID_NO_UPDATE_CHECK=1` to turn off the check.

### Narrow the model list

`liquid model apply` sets the filters that Claude Code and Codex use when they read the model list. Paste a link from the models page, or name the filters:

```bash
liquid model apply 'https://app.example.com/models?tab=text&provider=acme&min_context=128k'
liquid model apply cost_tier=low provider=acme
liquid model apply off
```

`kind`, `cost_tier`, `input`, `output`, `contested` and `byok` take a fixed list of values. The command refuses any other value and shows the list. Other keys take names, globs or numbers.

`byok=true` keeps only the models of the clouds that you connected with your own keys, and `byok=false` leaves them out. Like `provider`, it needs an API key. The command skips page settings in a link that are not filters, such as the sort order, and tells you which. For one run, use `liquid claude --filter cost_tier=low`.

### Usage events

When a command ends, `liquid` sends one anonymous usage event. It holds the command name, the tool id, the `liquid` version, your operating system and processor, the exit code and run time, whether a key is saved, and a random install id. It never holds a prompt, an argument, a file path, a model name, a key or a token. The install id is not linked to your account. The first run sends nothing. To turn the events off:

```bash
liquid telemetry off          # saved in the config file
export LIQUID_TELEMETRY=off   # for one shell or one CI job
export DO_NOT_TRACK=1         # the common opt-out flag
```

`liquid telemetry status` shows the state and the install id.
