Skip to content
IQ Routing

IQ CLI

The IQ CLI is the local terminal for the gateway. Running iq with no arguments drops you into an interactive shell; everything else is a one-shot subcommand:

  • iq / iq shell -- interactive REPL. Type a prompt, get a response with routing telemetry, repeat.
  • iq prompt "..." -- single-prompt round-trip with a routing telemetry box (tier, model, focus mode, cache, latency split, cost).
  • iq batch prompts.txt -- run a prompt file end-to-end with a per-prompt line and an aggregate table at the close.
  • iq smoketest -- drive a canned routing-correctness corpus through the gateway and check which tier each prompt landed on.
  • iq agent "..." -- a dry-run planner. Proposes a plan; executes nothing.
  • iq generate-prompts -- emit a synthetic prompt file at the requested difficulty mix.
  • iq costlab -- score the CLI's local cost predictions against your own bills.

iq login and iq logout handle credentials -- see Sign in, below.

Install

Download the signed binary for your platform from the release assets shared with your account. Pick the latest release and grab the asset matching your OS and architecture. Each release ships a checksums file and a detached signature. Verify the download against the published checksum, then make it executable and put it on your PATH:

# After verifying the checksum:
chmod +x iq
sudo mv iq /usr/local/bin/iq

On Windows, download the .exe asset from the same release, verify its checksum, and move it onto your PATH.

Sign in

iq login

iq login opens the dashboard's CLI access tokens page in your default browser. Issue a token under Settings → CLI access tokens, paste it back at the prompt. The CLI stores the token at ~/.config/iq-routing/credentials.toml (%APPDATA%\iq-routing\credentials.toml on Windows) at mode 0600.

CLI access tokens carry the prefix iqp_. The CLI also accepts an org API key (prefix gw_live_) issued from the dashboard's Keys page, so either credential class works. The gateway verifies each class separately on the prefix, and a personal access token is scoped narrower than an org-level API key.

Single-prompt mode

$ iq prompt "Summarise the last quarter's earnings call in three bullets"

Routing
  Tier:           medium
  Complexity:     6.2 / 10
  Chosen model:   gpt-5.6-luna
  Focus mode:     balanced (no bias)
  Cache:          miss (new prompt)

Latency
  Total:          1842 ms
  Gateway-side:    34 ms
  LLM-side:      1808 ms

Tokens
  Prompt:           17
  Completion:      142

Cost
  This request:   $0.000482

Response
─────────────────────────────────────────────────────────────────────────
- Revenue grew 12 percent YoY, driven by the AI gateway segment.
- Margins compressed 80 bps as inference costs outpaced price increases.
- Guidance trims FY26 EPS by 3 percent to reflect the launch ramp.
─────────────────────────────────────────────────────────────────────────

Flags:

  • --raw -- print only the response body. No telemetry box. Useful for piping into another tool.
  • --json -- print the full response as JSON with the telemetry inlined under x_iq_routing.
  • --model -- pin a routing alias (auto, the default, plus cheap, frontier, and default) or a concrete provider/model string.
  • --timeout -- request timeout in seconds. Default 60.
  • --no-cost-line -- suppress the cost-prediction line printed under the telemetry box. The turn is still recorded; see Cost prediction, below, for the difference between this flag and turning the lab off entirely.

Interactive shell

Running iq with no arguments is the default entry point, and it is identical to iq shell. Each line you type is sent through the gateway as a new turn: the shell renders the same telemetry box as iq prompt, a cost-prediction line (see Cost prediction, below), and the response body, then prompts again. Turns are numbered (iq[1]>, iq[2]>, ...) and prior turns re-render dimmed above the active one so a screen recording shows which turn is live. Ctrl-D or Ctrl-C exits cleanly.

iq
# or start on a different routing alias:
iq shell --model frontier
$ iq
Connected to https://gateway.iq-routing.com.  Model: auto
Type :help for commands, :exit to leave.

iq[1]> Summarise the last quarter's earnings call in three bullets
── turn 1 (14:02:07) ────────────────────────────────────────────
Routing
  Tier:           medium
  Chosen model:   gpt-5.6-luna
  Cache:          miss (new prompt)
...
Response
────────────────────────────────────────────────────────────────
- Revenue grew 12 percent YoY, driven by the AI gateway segment.
...
────────────────────────────────────────────────────────────────

iq[2]> What was the margin figure again?
── turn 2 (14:02:41) ────────────────────────────────────────────
Routing
  Tier:           simple
  Chosen model:   gpt-5.6-luna
  Cache:          miss (new prompt)
...
cost  pred $0.000391* -> act $0.000348   -11.0%   in 9->9 tok   out 187->165 tok   gpt-5.6-luna as predicted
      in 9 tok below the 1024-token cache floor, no discount to keep or forfeit   (*local fallback, gateway estimate unavailable)
Response
...

iq[2]> :exit

Meta-commands (anything starting with :):

| Command | Effect | |---|---| | :help | List every meta-command. | | :exit, :quit, :q | Leave the shell. | | :key <api-key> | Use a different key for this session only. :key alone shows the masked current key; :key clear reverts to the credentials-file token. | | :gateway <url> | Point this session at a different gateway. :gateway alone shows the current URL; :gateway clear reverts. | | :model <alias> | Switch the routing alias mid-session (auto, default, cheap, frontier, or a literal provider/model). :model alone shows the current value. | | :cost, :cost off, :cost on | Show cost-line state plus predictor accuracy, or toggle the line. Recording continues regardless -- see Cost prediction, below. | | :reset | Clear the screen and reset the turn counter to 1. Does not touch credentials or cost history. | | :smoke [N] [--model alias] [--limit N] | Run the smoketest harness without leaving the shell. The positional N and --limit are interchangeable; passing both with different values is an error. | | :testkey | Print a reminder of how to paste a real key. Does not itself change the active key. |

Dropping a file to batch

Paste or drag a .txt, .md, .prompt, or .prompts file path into the prompt -- as the only token on the line, resolving to a file that exists -- to dispatch every line in it as a batch, at concurrency 4, without leaving the shell:

iq[3]> ~/Desktop/support-queue.txt
dropped file support-queue.txt (23 prompts, model=auto, concurrency=4, 6 match canonical corpus)

  1/23  ✓  exp=-        obs=cheap    gpt-5-nano          cache-miss  0.61s  $0.00009
       complexity=simple (1.8/10)  focus=balanced  tokens=22→64  req=a1b2c3d4
       > "How do I reset my password?"
...

Aggregate
  Total prompts:        23
  ...

The gateway's per-team rate limit is 240 requests per minute; the shell warns when a dropped file's prompt count would exceed that, since rows past the cap are likely to come back 429. Re-dropping the same file replays every row from cache in a fraction of the original time. exp= shows an expected tier only for prompts that match the built-in smoketest corpus verbatim; anything else shows exp=- and only the observed tier.

Batch mode

$ iq batch prompts.txt --concurrency=4 --out=results.jsonl

Reading prompts.txt: 20 prompts loaded
Concurrency: 4

  1/20  ✓  simple    gpt-5-nano   cache-miss   0.84s   $0.00012
  2/20  ✓  medium    gpt-5-mini   cache-miss   1.92s   $0.00048
  3/20  ✓  simple    gpt-5-nano   cache-hit    0.04s   $0.00000
  ...
 20/20  ✓  complex   opus-4-8     cache-miss   3.41s   $0.00284

Aggregate
  Total prompts:        20
  Successes:            20
  Failures:              0
  Cache hit rate:       35%
  Tier mix:             simple 8 · medium 9 · complex 3
  Latency p50:        1.42s
  Latency p99:        4.18s
  Total spend:        $0.0341
  Avg cost / prompt:  $0.00171

  Wrote results.jsonl with 20 rows.

Flags:

  • --concurrency=N -- in-flight requests. Defaults to 4. Caps at 16 (the safe per-org ceiling); higher values clamp with a stderr warning.
  • --out=results.jsonl -- write one JSONL row per prompt with the full response body and the telemetry inlined under x_iq_routing.
  • --model, --timeout -- same semantics as iq prompt.

The exit code goes non-zero when at least one prompt fails (any 5xx, timeout, or transport error). Failed prompts do not abort the run; the aggregate reports successes and failures together.

Prompt-file format

One prompt per line. Blank lines and #-prefixed lines ignored.

# easy
What is the capital of France?
Translate "good morning" to Spanish.

# medium
Given this CSV row, output a JSON object with the columns as keys: 1,Alice,30

Prompt generator

iq generate-prompts --difficulty=mixed --count=20 --out=prompts.txt

Difficulty bands:

  • easy -- single-sentence factual lookups, single-step instructions. Target tier simple.
  • medium -- multi-step reasoning, structured output, short code snippets. Target tier medium.
  • hard -- long-context, ambiguous instructions, cross-domain synthesis. Target tier complex.
  • mixed -- 40% easy, 45% medium, 15% hard. Matches the observed production traffic distribution.

Counts cap at 1000 per file. The generator does not call the gateway; it is a pure offline emitter.

Smoketest

iq smoketest
iq smoketest --limit 10 --model frontier

iq smoketest drives a canned corpus of 100-plus prompts through the gateway and checks that each one landed in its expected tier's band (cheap, default, or frontier). It is a routing-correctness check, not a synthetic dry run: every prompt is a real request against your provider keys, so a full run has a real, if small, cost. Prompts dispatch sequentially, so the full corpus takes several minutes.

$ iq smoketest --limit 3
iq smoketest  3 prompts  gateway=https://gateway.iq-routing.com  model=auto

  PASS sp-cheap-01     expected=cheap    model=gpt-5-nano                          84ms
       > What is the capital of France?
  PASS sp-default-01   expected=default  model=gpt-5.6-luna                      1204ms
       > Write a Python function that takes a list of integers and returns the second largest. Handle ties and empty lists.
  FAIL sp-frontier-01  expected=frontier model=gpt-5-mini                         932ms  (routed to 'default' tier; expected 'frontier' (model: gpt-5-mini))
       > Design the architecture for a multi-tenant SaaS analytics product handling 50 million events per day. Cover ingestion...

Routing distribution (expected tier x observed tier)
...

totals: 2 pass  1 fail  3 distinct chosen-model values  runtime 14.2s

Flags:

  • --limit N / -n N -- cap the run at the first N prompts (a head-of-list subset) instead of driving the full corpus.
  • --model / -m -- band-map alias for the whole run: auto (default), frontier, cheap, or a literal provider/model string. Same alias semantics as iq prompt --model.
  • --timeout -- per-request timeout in seconds. Default 60.

The run fails (exit code 1) if any prompt's response is empty, missing telemetry, missing a chosen model, non-positive latency, missing cost on a non-cache-hit, or routed outside its expected tier's band -- or if the whole run produced fewer than four distinct chosen-model values. A 429 mid-run waits for the suggested retry window once and resumes rather than failing the prompt outright, since a full run can brush against the gateway's 240 RPM per-team cap.

:smoke [N] [--model alias] [--limit N] runs the same harness inside the interactive shell without spawning a separate process; see Interactive shell, above.

Agent (dry-run planner)

iq agent "Find every TODO comment in the src/ directory and summarise them"
iq agent "Check whether api.example.com is up" --tools http_fetch

iq agent is a single-turn, dry-run planner. It sends your instruction plus a small catalog of advisory tool schemas (read_file, http_fetch) to the gateway and prints the model's proposed plan: either a numbered list of tool calls or a prose explanation.

The agent never executes anything. No file is read, no URL is fetched, no code runs. The tool schemas exist so the model can propose concrete, well-formed steps -- the operator reads the plan and runs whatever looks right by hand. Do not build automation on top of this command expecting the proposed steps to have actually happened; nothing downstream of the plan is real until you make it real.

$ iq agent "Find every TODO comment in the src/ directory and summarise them"
iq agent (planner / dry-run)  session=iqa_4f9c2e1a08b7c391  model=auto  tools=http_fetch,read_file
instruction: Find every TODO comment in the src/ directory and summarise them

Routing telemetry
  model=gpt-5-mini  cache-miss  0.81s  $0.00031  complexity=medium (5.1/10)  tokens=41→96

Proposed plan (advisory only -- nothing executed)
  1. read_file(path='src/index.ts')
  2. read_file(path='src/utils.ts')

Model commentary:
Run these two reads, then grep the results for "TODO" and summarise
each hit with its surrounding context.

Run any of these steps yourself if they look right; the agent never
executes tools.

Flags:

  • --model / -m -- routing alias or literal provider/model. Same semantics as iq prompt --model.
  • --tools -- comma-separated list of tool names the planner may propose. Built-ins: read_file, http_fetch. Defaults to both.
  • --theme -- light (default) or dark.

Every turn carries an X-IQ-Session-Id header (iqa_<16-hex-chars>), so the dashboard's Sessions view rolls the telemetry under one row even though the agent itself never loops.

Cost prediction

iq costlab report
iq costlab params

The cost lab predicts, before a turn is dispatched, what it is about to cost, then scores that prediction against the bill once it lands. The prediction comes entirely from your own historical usage -- the rates and output lengths the lab has already measured from your past turns -- not from a live price quote from the gateway. Every prediction the lab can currently produce is labelled local_fallback (rendered with a trailing *) for that reason: it is the CLI's own model of what a turn will cost, built by watching your bills, and it is honest about being an estimate rather than a quote.

Because the predictor learns from your own history, it has nothing to say on a fresh install, or the first time it sees a given model: it needs at least one billed turn on a model before it can predict the next one.

The cost line

iq prompt and iq shell print one line under the telemetry box for every turn, once the lab has enough history to say something:

  • Nothing at all when there's no prediction to make (fresh install, or a model with no prior billed turn) or no bill to score it against.
  • A one-line cache-hit note -- cost cache hit, $0.000000 served -- when the turn was served from cache. Classification is skipped on a cache replay, so there is nothing to predict.
  • Otherwise, a line showing the predicted cost, the actual cost, the signed percentage they differ by, the input/output token counts predicted vs. observed, and whether the model that ran matches the model the prediction assumed. A second, indented line follows when it applies, carrying up to three notes: the router switched models (what staying would have cost, if known), the prompt fell under the 1024-token cache-write floor (so there was no cache discount to report either way), and -- today, always -- the local-fallback marker.
cost  pred $0.000391* -> act $0.000348   -11.0%   in 9->9 tok   out 187->165 tok   gpt-5.6-luna as predicted
      in 9 tok below the 1024-token cache floor, no discount to keep or forfeit   (*local fallback, gateway estimate unavailable)

Two independent ways to quiet it down:

  • iq prompt --no-cost-line or :cost off in the shell -- turns off the display only. The turn is still recorded, so the history stays complete.
  • IQ_COSTLAB=off (env var), or enabled = false under [costlab] in the lab's config.toml -- turns off the whole lab. No line, and no row gets recorded either.

iq costlab run

iq costlab run --limit 12
iq costlab run --input my-prompts.txt --model cheap

Drives a corpus through the gateway live, predicting each turn before it dispatches and recording a residual row after. Without --input it uses the first 12 prompts of the built-in smoketest corpus. Like iq smoketest, this dispatches real requests against your provider keys -- it is not a simulation. Turns run one at a time on purpose: the predictor assumes the previous turn's model is still the incumbent, so concurrent dispatch would race that assumption and corrupt the accuracy numbers that come out of it.

Flags:

  • --input / -i -- a prompt file (one per line). Omit for the built-in corpus.
  • --limit / -n -- cap at the first N prompts.
  • --model / -m -- routing alias or literal provider/model.
  • --timeout -- per-request timeout in seconds. Default 60.

The lab must be enabled (see above) for run to record anything; it prints an accuracy table for the rows it just recorded when it finishes.

iq costlab report

iq costlab report
iq costlab report --trend --worst 5 --rates

Scores every residual row recorded so far -- from iq prompt, iq shell, and iq costlab run alike, since they all write to the same local log -- against the bills that came in.

Residuals
  Rows:                          142
  Scoreable:                     118
  Cache replays (excluded):       24
  Switched away from incumbent:    9
  Inside disclosed band:          81%
  Mean signed error:            +4.2%
  Median absolute error:          9.6%
  Predicted total:          $0.048210
  Actual total:              $0.051006

Flags:

  • --last N -- score only the most recent N rows.
  • --trend -- MAPE by calibration epoch, calibrated vs. the seed vector, so you can see whether calibration actually helped.
  • --worst N -- the N worst mispredictions and what each one assumed.
  • --rates -- measured vs. assumed per-model rates, with the drift between them.
  • --json -- emit the same stats as JSON.

iq costlab params

iq costlab params
iq costlab params --history output_len_multiplier

Shows the parameter vector currently in force -- every tunable's current value, its bounds, which calibration epoch last moved it, and how much evidence backed that move. --history <param> shows every recorded change to a single parameter.

--pin <epoch> freezes resolution on a specific past epoch without touching anything else in the log -- the rollback path after a bad calibration. --unpin releases the pin so the highest epoch wins again. Both are pure appends: nothing already on disk is ever rewritten or deleted, so the epoch that caused the problem stays there to be inspected.

iq costlab calibrate

iq costlab calibrate
iq costlab calibrate --param output_len_multiplier --since 2026-08-01

Fits one calibration epoch from the residual rows recorded since the parent epoch's window ended, and appends it to the local parameter log. It never re-reads rows an earlier epoch already consumed, and it computes exactly one epoch per invocation -- there is no loop-to- convergence mode, so every fit is a single, readable, auditable step. A parameter with too little evidence in the window is left unmoved and the epoch records why, rather than silently keeping its old value with no explanation.

Flags:

  • --dry-run -- print the exact epoch that would be appended, without appending it. Nothing is sent anywhere; this only previews the local file write.
  • --param <name> -- fit only the named parameter this epoch.
  • --since <date> -- override the window start (YYYY-MM-DD or an ISO timestamp, read as UTC).
  • --include-fallback -- also admit rows whose own prediction came from the local fallback. Off by default, since that would be the predictor grading its own homework.

iq costlab reset and diff

iq costlab reset --confirm re-seeds every parameter back to its built-in default by appending a reset row -- it does not delete anything, but it does open a fresh resolution scope, so calibration epochs written before the reset stop influencing the vector currently in force (they stay on disk and stay readable). Running reset without --confirm just prints a warning and does nothing.

iq costlab diff V1 V2 compares two calibration epochs parameter by parameter, showing which cells changed and by how much (--json for the same diff as JSON).

Where it's stored

The lab's state lives under the same per-user config directory as your credentials, honouring IQ_CONFIG_DIR if you set it:

  • ~/.config/iq-routing/costlab/residuals.jsonl -- one row per completed turn.
  • ~/.config/iq-routing/costlab/params.jsonl -- the calibration history.

(%APPDATA%\iq-routing\costlab\ on Windows.) Both files are append-only JSONL, so they are safe to tail or feed into your own analysis. iq logout does not touch this directory -- signing out does not cost you your calibration history.

Tokens, scopes, and revoke

The CLI authenticates with a personal access token issued from Settings → CLI access tokens. Default scopes:

  • read:routing -- view routing decisions.
  • write:prompt -- send prompts via the CLI.

Wider scopes (read:audit, write:settings) are opt-in at issue time. Tokens display the plaintext exactly once at issue. The dashboard shows only the prefix on subsequent reads.

iq logout removes the local credentials file. To revoke server-side, open Settings → CLI access tokens and click Revoke on the token row.

Bundle mode (Enterprise)

There is no self-hosted distribution on the self-serve plans. The standalone gateway bundle is the Enterprise on-prem option, arranged with us rather than downloaded, and it ships the CLI as part of the single-binary install. iq-gateway prompt "..." posts to the local gateway at http://localhost:8000; the same telemetry box renders.

iq-gateway serve            # boots the gateway + opens the dashboard
iq-gateway prompt "..."     # uses the local gateway

Some of the bundle's deeper analytics surfaces render a Limited mode banner, because they depend on reporting queries the bundle's embedded storage does not support. Routing, caching, and per-request telemetry all run end to end in the bundle; only the aggregate analytics views are reduced.

Troubleshooting

  • Token in {path} is not a recognised IQ credential -- the saved value carries no known prefix. Re-run iq login and paste an org API key (gw_live_...) or a CLI access token (iqp_...).
  • Credentials file is group- or world-readable -- POSIX safety check. Run chmod 0600 ~/.config/iq-routing/credentials.toml.
  • Gateway returned 401 -- the token expired or was revoked. Run iq login to reissue.
  • Telemetry box shows telemetry unavailable -- the gateway you are pointed at is older than the telemetry header, or telemetry has been turned off for that deployment. Update to a current gateway version, or re-enable the telemetry header on the deployment you are calling.

See also

  • /docs/quickstart -- SDK integration via OpenAI/Anthropic clients.
  • /docs/api-reference -- REST surface details.
  • /integrate -- drop-in code snippets and a Use the IQ CLI panel.