🧰 Tooling Guide

OpenClaw Models CLI Guide: status --check, list, set, scan, and Which Auth Commands Need the Gateway Stopped

•7 min read

openclaw models scan sounds like a read. Run it with live checks and it rewrites your fallback list.

The pages that rank for openclaw models are the official CLI reference (close to 6,000 words, translated into a long list of languages) and third-party mirrors that copy it section by section. They all walk the same order: status, list, set, scan, aliases, fallbacks, auth profiles. They are thorough. What none of them does is sort the commands by what they need from the Gateway, and that is where scripts break, because about half of models auth refuses to run while a Gateway owns the state directory and the other half delegates to it. That map is near the end. The commands come first.

Bare openclaw models is status

openclaw models with no subcommand runs models status, and openclaw models --json returns the same object as models status --json. Status explains the configured default, the fallbacks, and the auth behind each route. models list answers a different question (what models exist), and neither one looks at a chat session's own override. For that, type /model status inside the session.

Reading status without scaring yourself

The output has four sections, and they are easy to conflate:

Auth overview

Where credentials were found: environment, provider config, or the auth store. Finding one proves nothing about whether it works.

OAuth/token status

Stored profile health and expiry. Active cooldowns show up under Unavailable auth profiles with a reason and a recovery action.

Model route issues

Incompatible routes, missing route credentials, or readiness that could not be confirmed. This is the section to read first.

Runtime auth

Routes that run through a separate agent runtime such as Codex. Valid credentials with a disabled plugin report status: unavailable.

The word that sends people off to rotate keys they did not need to rotate is indeterminate. A file or exec SecretRef can appear in the overview while its route stays indeterminate, which only means this command path could not confirm readiness. The provider may be perfectly happy. Check the route diagnostic and the secret source (the secrets guide covers those) before you paste anything new. Same with marker(secretref-managed) labels: they name where a credential comes from and never contain the secret itself.

--check is the cron gate

Three exit codes, and they mean more than pass or fail.

openclaw models status --json --check > "$TMPDIR/models.json"
rc=$?
case $rc in
  0) ;;                                        # nothing wrong that status can see
  2) echo "a selected credential is expiring" ;;
  *) echo "model auth or runtime problem (exit $rc)" ;;
esac

Exit 1 covers missing or expired auth, an incompatible route, an unavailable runtime, and indeterminate readiness. Exit 2 is the early warning: something is expiring and nothing worse is wrong. Treat 2 as a ticket and 1 as a page. And catch everything else too, because a failure to resolve a config secret also exits nonzero and, in JSON mode, can hand you a command error instead of the status object. A script that only parses the JSON will miss it. Diagnostics go to stderr, so stdout stays clean for jq.

The docs are careful to say exit 0 does not prove a model request will succeed. Status without --probe never calls a model. With --probe it makes real, prompt-only requests (default timeout 8000 ms, concurrency 2, at most 8 tokens per check), which can cost tokens and trip rate limits, and a direct probe needs the Gateway stopped. That last part rules it out for a scheduled job on a live box. Keep --check in the cron job and save --probe for maintenance windows.

list, list --refresh, and refresh are three different things

openclaw models list returns published inventory without waiting for discovery. When a Gateway is running it reads that Gateway's catalog; if a provider's saved inventory has expired, you get the saved rows now and the Gateway refreshes in the background, so a model released this morning may only appear on the second call.

models list --refresh runs provider discovery first. openclaw models refresh (no list) downloads the hosted metadata catalog, rejects --agent because that catalog is global, and refuses to run until the local Gateway is stopped. The new metadata loads on the next start.

Two small things that cost me time. --provider wants the provider ID, moonshot, rather than the label Moonshot AI. And model refs split on the first slash, so OpenRouter models whose IDs contain a slash need the full prefix: openrouter/moonshotai/kimi-k2.

set and set-image write global defaults

openclaw models set <provider>/<model>
openclaw models set-image <provider>/<image-model>
openclaw models aliases add fast <provider>/<model>

set writes agents.defaults.model.primary and set-image writes agents.defaults.imageModel.primary. Neither takes --agent. An unknown provider exits nonzero without touching config. A known provider with a model the local catalog has never heard of saves anyway, with a warning, which is the right call for a model that shipped yesterday or one you host yourself.

If you want the strict version, openclaw config set agents.defaults.model rejects a reference it cannot resolve. That strictness is text-only, though. config set does not validate agents.defaults.imageModel at all, so for image models the CLI's warning is the only check you get. The config CLI guide has the rest of that comparison. Skip the provider prefix and OpenClaw tries a configured alias, then a unique configured-provider match, then the default provider with a deprecation warning. Just type the prefix.

scan writes config

A probed models scan replaces agents.defaults.model.fallbacks with the models it selected, replaces the image fallbacks when it picked image-capable ones, and adds them all to agents.defaults.models, even without --set-default, even with --json, so if you spent an afternoon ordering fallbacks by hand as described in the model failover guide, run openclaw models scan --no-probe to look and nothing else.

The Gateway-stopped map

Here is the part the reference spreads across several paragraphs. The CLI never writes around a live Gateway and never retries a failed Gateway write locally, so each auth command either talks to the running Gateway or demands exclusive ownership of the state directory.

Works with the Gateway running

models auth paste-api-key, as long as you omit --profile-id. models auth login and login-github-copilot, which render the Gateway's wizard in your terminal but refuse --profile-id, --force, --set-default, and Copilot's --yes.

Needs the Gateway stopped

Every other models auth subcommand, including paste-token, list, and order get. Also models refresh and a direct models status --probe.

models auth list is the one that surprises people. It is a read. It still needs exclusive ownership, because its loaders can initialize persistent state. I think that is the wrong trade for a command whose whole job is to show you what is saved, but it is how the CLI works today, so on a running Gateway open the Models page in the Control UI instead.

The safe key rotation on a live box:

printf "%s\n" "$OPENAI_API_KEY" | openclaw models auth paste-api-key --provider openai

The Gateway saves it and refreshes its catalog without a restart, and replacing a key clears that profile's cooldown and failure counters so the next request tries it immediately. If the CLI cannot authenticate to the Gateway, set OPENCLAW_GATEWAY_TOKEN or OPENCLAW_GATEWAY_PASSWORD and retry. Device pairing does not substitute here.

Two agents, one auth store per agent

Inspection without --agent uses agents.defaults.systemAgent.agentId, or the only agent if there is one. Auth mutations demand --agent once you have two, which is another reason to set a System Agent before you follow the agents CLI guide to add a second one. models auth order set stores a per-agent profile order in SQLite that outranks the auth.order.<provider> config key, which explains the afternoon you spend editing config while the CLI ignores you. order clear hands control back.

models auth logout <profileId> --yes cleans up after itself. It removes the profile from auth.profiles and every auth.order list, and deletes an order entry it would otherwise leave empty, because an empty authored order means "select no profiles" and would quietly disable the provider.

Personal accounts

models auth writes to the machine where you typed it, and pointing your laptop at a remote Gateway URL does not change that; models accounts is the per-person store on a shared Gateway and needs an identity-bearing endpoint such as Tailscale Serve, which the Tailscale guide sets up.

Final verdict

Put models status --check in cron, treat exit 2 as a ticket, and never run a probed scan on a config you care about. Before any models auth command in a script, decide whether the Gateway is up or down, because the command already decided for you.

⚡

Ready to build?

Get the OpenClaw Starter Kit — config templates, 5 production-ready skills, deployment checklist. Go from zero to running in under an hour.

$14 $6.99

Get the Starter Kit →

Also in the OpenClaw store

🗂️
Executive Assistant Config
Buy
Calendar, email, daily briefings on autopilot.
$6.99
🔍
Business Research Pack
Buy
Competitor tracking and market intelligence.
$5.99
⚡
Content Factory Workflow
Buy
Turn 1 post into 30 pieces of content.
$6.99
📬
Sales Outreach Skills
Buy
Automated lead research and personalized outreach.
$5.99

Get the free OpenClaw quickstart guide

Step-by-step setup. Plain English. No jargon.