---
title: "zctl CLI: Installation and Account Management"
description: "Learn who should use zctl, when to use the CLI, how to install it, and how to manage ZRouter routers, keys, credits, usage, and limits."
icon: "terminal"
keywords: ["zrouterctl", "zctl", "ZRouter CLI", "CLI installation", "virtual routers", "account management", "CI automation"]
---

`zctl` is a standalone customer client. It connects to the same account APIs
as the dashboard, with the same account scope and feature availability. It does
not start a gateway or need a repository checkout.

## Who should use zctl?

`zctl` is for ZRouter account owners, developers, operations teams, and CI/CD
maintainers who need terminal access to their own account. Each command has the
same account permissions as the customer dashboard. The CLI does not grant
operator access or permission to manage other customers.

## When should you use the CLI?

Use `zctl` to create or update routers while coding, back up routing configuration,
apply a JSON configuration from a script, rotate account API keys, inspect usage
and request logs, or manage budgets and rate limits from a remote terminal.
Its JSON output and nonzero error exit codes support automation.

| Interface | Use it when |
| --- | --- |
| Customer dashboard | You want visual charts, forms, or an interactive playground. |
| zctl CLI | You work in a terminal or need repeatable account-management scripts. |
| [Account MCP tools](/docs/mcp) | You want a connected AI assistant to manage your account through supported tools. |

## What do you need before installing?

- Access to the ZRouter service at `https://zrouter.si`.
- A ZRouter account, or use `zctl register --email you@example.com` after installing.
- Linux, macOS, or Windows on x64 or ARM64 and access to the gateway over the network.
- For the macOS/Linux installer: `sh`, `curl`, and `sha256sum` or `shasum`.

You do not need Go, Node.js, a provider API key, or a repository checkout to run
an installed client. HTTP is allowed for a gateway on localhost during development.
Keep any gateway base path in the URL. Installing the CLI and managing an account
does not consume inference credit; requests to AI models use the platform's billing.

## Install

### npm

With Node.js 20 or later, install the `zrouterctl` npm package. The terminal command is `zctl`:

```bash
npm install -g zrouterctl
zctl login
```

You can also use `npx --package=zrouterctl@latest zctl login` without a global
installation. The npm package includes verified binaries for all six supported
platforms. No Go compiler or separate binary download is required.
Update with `npm install -g zrouterctl@latest`. To remove it, run `zctl logout`, then
`npm uninstall -g zrouterctl`.

### Direct downloads (no Node.js required)

Open [ZRouter CLI downloads](https://zrouter.si/cli) for Linux, macOS, and Windows.
For macOS or Linux:

```bash
curl -fsS https://zrouter.si/cli/install.sh -o install-zctl.sh
sh install-zctl.sh --url https://zrouter.si
export PATH="$HOME/.local/bin:$PATH"
```

The installer verifies SHA-256 and installs to `~/.local/bin` without sudo. Use
`--dir /your/bin` to choose another directory. Run the installer again to update.
### Windows installation

Download the x64 or ARM64 executable and `SHA256SUMS` from [CLI downloads](https://zrouter.si/cli). In PowerShell,
verify the file before running it, replacing the filename for ARM64:

```powershell
Get-FileHash .\zctl-windows-amd64.exe -Algorithm SHA256
Rename-Item .\zctl-windows-amd64.exe zctl.exe
.\zctl.exe login
```

Compare the hash with the entry for that exact filename in `SHA256SUMS`. Move
`zctl.exe` to a folder on your user PATH to run `zctl` from any terminal.

### Update or uninstall

These instructions apply to direct downloads. For npm installations, use the npm
update and uninstall commands above.

Run the installer again using the same `--url` and `--dir` to update. Windows
users can download and verify the replacement executable. To uninstall, first
run `zctl logout` to revoke the current credential, then remove the installed
`zctl` or `zctl.exe` file. Other authorized terminals remain signed in.

## Sign in

```bash
zctl login
```

The CLI opens your account dashboard. Sign in with your password, Google, or
GitHub if enabled. Verify the code displayed in your terminal, then explicitly
approve that terminal. Use `--no-open` when the terminal has no browser and open
the displayed URL on another device.

The CLI defaults to the hosted ZRouter service, so a new user can run `zctl login`
without a URL. After sign-in, it remembers the gateway. An explicit `--url` takes
precedence over `ZROUTER_URL`, then the saved gateway, then the hosted default.

To choose a gateway explicitly, including a separate self-hosted deployment:

```bash
zctl login --url https://zrouter.si
```

Keep any configured base path in that URL. For local development, use
`zctl login --url http://localhost:8080`.

For password sign-in, use `zctl login --email you@example.com`. The password
prompt is hidden. `zctl register --email you@example.com` creates an account and signs
in. Scripts can supply a password via `--password-stdin`. Passwords and provider
keys have no command-line value flags, to keep them out of shell history.

Credentials expire after 30 days and are stored in a private credential file:

| OS | Default location |
| --- | --- |
| Linux | `$XDG_CONFIG_HOME/zrouter/credentials.json` or `~/.config/zrouter/credentials.json` |
| macOS | `~/Library/Application Support/zrouter/credentials.json` |
| Windows | `%AppData%\zrouter\credentials.json` |

The file stores the gateway URL and CLI token, with mode `0600` on Unix. A saved
credential is used only for its original gateway. Override its location with
`--config FILE` or `ZROUTER_CONFIG`. Revoke terminals in the dashboard's **CLI
access** page or with `sessions revoke ID`. `logout` revokes the current
credential and removes its matching local file.

For CI, set `ZROUTER_URL` and `ZROUTER_TOKEN` using your secret manager. Use a CLI
management token (`zr_cli_...`). Inference API keys (`zr_live_...`) cannot manage
accounts. `login --token-stdin` imports an existing management credential after
verifying it. Management credentials cannot make inference requests. Create an API key for
those requests.

## Virtual routers

```bash
zctl models list
zctl routers list
zctl routers create assistant \
  --target openai/gpt-4.1 --target anthropic/claude-sonnet-4-5 \
  --strategy round_robin
zctl routers update assistant --description "Default assistant"
zctl routers edit assistant
zctl routers disable assistant
zctl routers enable assistant
zctl routers delete assistant
```

Use provider/model selectors returned by `models list`. `routers list` includes
this deployment's available strategies. A bare `--target other-router` points
to another router owned by your account. The server validates provider targets,
routing strategies, account ownership, and cycles.

`update` preserves every setting you omit, including disabled state, weights,
schedule configuration, failover, and session affinity. Explicit Boolean changes
use `--enabled=false`, `--failover=false`, or `--session-affinity=false`.

`edit` opens private JSON in `$VISUAL`, then `$EDITOR`, or `vi`. No changes are
sent until the editor exits successfully and JSON is valid. Router names cannot
be changed by update or edit. Create a new router to use a different name.

Use export/apply for backups, automation, and advanced routing settings:

```bash
zctl routers export assistant > router.json
zctl routers apply --file router.json
zctl routers update assistant --file partial-update.json
```

An editable configuration looks like this:

```json
{
  "name": "assistant",
  "strategy": "round_robin",
  "targets": [
    { "provider": "openai", "model": "gpt-4.1", "weight": 3 },
    { "provider": "anthropic", "model": "claude-sonnet-4-5", "weight": 1 }
  ],
  "description": "Default assistant",
  "enabled": true,
  "failover": true,
  "session_affinity": true
}
```

`apply` upserts a complete configuration. `update --file` merges fields present
in the file with the existing router. Advanced exports include `strategy_config`,
`strategy_plugin`, and `slowdown`. The CLI uses deployment-supported strategies,
including schedules and configured routing plugins. Namespaces come from the
server, users cannot choose another account's namespace.

The create response's `source`, for example `accounts/ACCOUNT_ID/assistant`, is
the model selector to send to the OpenAI-compatible API with an inference API key.

## Account management

```bash
zctl account
zctl balance
zctl pricing
zctl keys list
zctl keys create --name production
zctl keys revoke KEY_ID
zctl byok list
zctl byok set openai
zctl byok remove openai
zctl credits add --amount 25 --open
zctl credits history
zctl usage summary
zctl usage daily
zctl usage models
zctl logs requests --query 'limit=20'
zctl logs audit --query 'limit=20'
zctl sessions list
zctl sessions revoke SESSION_ID
```

Key creation shows the secret once. `byok set` prompts for the provider key, or
reads it with `--key-stdin`. Credit purchases return a secure Stripe checkout URL,
`--open` also opens it. Purchases start at $5 with no platform policy maximum,
subject to payment-provider and numeric precision limits. Usage and audit queries
accept the same filters as the account dashboard, with enforced account scoping.
`balance` and `pricing` return the account response, including balance in
microdollars (1 USD = 1,000,000) and transparent per-model rates.

## Budgets and rate limits

```bash
zctl budgets list
zctl budgets set --file budget.json
zctl budgets delete --file budget.json
zctl budgets reset --period 86400
zctl rate-limits list
zctl rate-limits set --file limit.json
zctl rate-limits delete --file limit.json
zctl rate-limits reset --period 60
```

A daily $20 budget:

```json
{ "budget_key": { "period_seconds": 86400 }, "amount": 20 }
```

A per-minute rate limit:

```json
{ "limit_key": { "period_seconds": 60 }, "max_requests": 100, "max_tokens": 50000 }
```

The CLI derives `scope`, `subject`, and `user_path` from your authenticated
account. Budgets and rate limits must be enabled in your workspace.
Commands output JSON and exit nonzero on errors. Run `zctl help` for the
command reference.

## Troubleshooting

| Problem | What to do |
| --- | --- |
| `zctl: command not found` | Add the installation directory to PATH or run the executable by its full path. |
| Sign-in expired or a terminal code is invalid | Run `zctl login` again and approve the new code within ten minutes. |
| No browser on the machine | Use `zctl login --no-open` and open the displayed URL on another device. |
| The saved sign-in does not work for another URL | Sign in to that gateway separately; credentials are bound to one gateway URL. |
| A router target or strategy is rejected | Run `zctl models list` and `zctl routers list` to check deployment availability. |
| Budgets, rate limits, or downloads are unavailable | Check feature availability in your workspace. If a download is unavailable, try again later or contact the team. |
| Checkout is unavailable | Credit purchases are not currently available. Try again later; account management remains available. |

## Frequently asked questions

### What is zctl?

zctl is ZRouter's standalone customer CLI for managing virtual routers, API keys,
provider connections, credits, usage, request logs, budgets, and rate limits.

### Do I need to clone the repository to install zctl?

No. Install from the `/cli` page on your gateway. The macOS/Linux installer
verifies a prebuilt binary, and Windows users can download an executable directly.

### Can I create and edit a virtual router from the CLI?

Yes. Use `zctl routers create NAME --target PROVIDER/MODEL`,
`zctl routers update NAME`, or `zctl routers edit NAME`. Updates preserve settings
you omit, and edit validates JSON before saving.

### Can I use zctl in CI or on a remote server?

Yes. Set `ZROUTER_URL` and `ZROUTER_TOKEN` through your CI secret manager.
The token must be an active CLI management credential. Browser sign-in can also
use `--no-open` on a machine without a browser.

### Can an inference API key sign in to the CLI?

No. A `zr_live_...` API key authenticates model requests. Account management
requires a CLI credential beginning with `zr_cli_...`, obtained through sign-in.

### How do I revoke a terminal's access?

Open CLI access in the customer dashboard, or use `zctl sessions list` and
`zctl sessions revoke SESSION_ID`. `zctl logout` revokes the current terminal.
CLI credentials expire after 30 days.
