Skip to content

Build master @ bc50cd5bunreleased — 31 commits past v1.282.0Last reviewed Last changed Grade fresh (aging >60d, stale >120d)Source / History

Start a Session on Another Model ​

A session normally runs on the Claude subscription. With --route openrouter it runs on a model you name, through OpenRouter, paid from the account's prepaid credits and capped by a monthly limit on this machine's own key. Without the flag nothing changes. The full rules are in the Model Routes reference.

Before you start ​

  • The OpenRouter management key is in this machine's keychain as OPENROUTER_MANAGEMENT_KEY.
  • This machine's entry in the operator repo's machines.json declares its limit: "routes": { "openrouter": { "monthly_limit_usd": 15 } }.

1. Mint this machine's key (once) ​

See what would be created. Nothing is changed.

bash
bob route mint --machine macbook-pro-16

You should see: DRY RUN: would create bob-macbook-pro-16 — limit $15.00 monthly.

Broken looks like: declares no OpenRouter limit (the limit is not in machines.json) or no OpenRouter management key on this machine.

Then create it:

bash
bob route mint --machine macbook-pro-16 --apply

You should see: minted bob-macbook-pro-16 — limit $15.00 monthly — stored at keychain:OPENROUTER_API_KEY. The key itself is never printed.

Broken looks like: was created but could not be stored. The key was deleted again; nothing is left to spend. Run the command again.

2. Start a session on the route ​

bash
claude --route openrouter

You should see, before the session opens: BoB: route openrouter — model anthropic/claude-sonnet-5.5 — key bob-macbook-pro-16 ($0.00 used of $15.00).

To choose the model, add its slug after a colon:

bash
claude --route openrouter:anthropic/claude-haiku-4.5

Broken looks like, each one before any session starts:

MessageMeaning
lists no model '<slug>'The slug is not one OpenRouter serves. The message prints the command that lists valid slugs.
is at its limitThis machine's key has spent its monthly limit.
is client tenant <id>'s projectA client project is never routed through your account.
no OpenRouter working key on this machineStep 1 has not been done here.

The same flag works for a headless groom:

bash
bob groom --route openrouter

3. See what the key has spent ​

bash
bob route status

You should see: openrouter: key bob-macbook-pro-16 — $0.04 used of $15.00 (monthly), $14.96 left.

Replace a key ​

A key's value cannot be read back from OpenRouter. If this machine has lost its key, or you want a new one, delete and mint again in one step:

bash
bob route mint --machine macbook-pro-16 --apply --replace

You should see: replaced bob-macbook-pro-16.

Keep a headless run going when a model fails ​

A route pins one model. A role names the kind of model a job needs and lists several, in order. When the first fails with a model failure — the usage limit, a 429, an overloaded API, a retired model — the job is started again on the next. A failing test or a GitHub rate limit is not a model failure and never moves a run. The rules are in Roles and failover.

See the roles and their order:

bash
bob route roles

You should see each role with its alias and candidates, starting with default (alias sonnet):, then 1. subscription sonnet, then 2. openrouter anthropic/claude-sonnet-5.5.

Run a headless groom on a role:

bash
bob groom --role default

You should see bob groom: role default first. The verdict line ends — role default on subscription sonnet. When it failed over, it ends with (fallback: see bob route failovers) and a BoB: failover — … line names what failed and why.

Broken looks like: --role default refused (an unknown role, or scripts/route/routing.json does not load), or every model failed over (every candidate failed: see the next command).

See what failed over on this machine:

bash
bob route failovers

Test failover without an outage ​

Mark the subscription down for one command. Nothing is sent to it:

bash
BOB_ROUTING_DOWN=subscription bob route run --role default -- claude -p "say ok"

You should see this line, then the answer from OpenRouter:

BoB: failover — role default: subscription sonnet failed (simulated: BOB_ROUTING_DOWN=subscription) — trying openrouter anthropic/claude-sonnet-5.5 (candidate 2 of 2)

This spends a few cents of this machine's OpenRouter limit.

Broken looks like: route_refused: no OpenRouter working key (step 1 has not been done on this machine) or is at its limit.

To test without spending anything, mark both routes down. Nothing runs and nothing is spent:

bash
BOB_ROUTING_DOWN=subscription,openrouter bob route run --role default -- claude -p "say ok"; echo "exit=$?"

You should see two failover lines, then every candidate failed over, then exit=3.

To switch a provider off for one run, use BOB_ROUTING_DISABLE=openrouter. To switch it off for good, set "enabled": false on its route in scripts/route/routing.json.