# ht-cli: the HostTracker command line

**`ht-cli`** is HostTracker's official command-line client. Every operation of the [REST API v2](/integrations/rest-api/)
is a command - monitors, incidents, contacts, alerts, reports, maintenance windows, status pages, webhooks and
instant checks - generated from the same published OpenAPI document the API serves, so it cannot drift behind the
API. It is built on the [Go SDK](/integrations/sdks/), which gives it bearer auth, automatic idempotency keys on
writes, retries that honour `Retry-After` and the RFC 9457 problem-document errors. Current release: 0.1.1, MIT
licensed, source at [github.com/HostTracker/cli](https://github.com/HostTracker/cli).

:::note[Plan requirement]
The CLI calls the API with your API token, so your plan must include API access. See
[Rate limits and quotas](/integrations/rate-limits/#which-plans-include-the-api).
:::

## Install

Every channel installs the same binary.

| Platform | Command |
|---|---|
| Homebrew (macOS and Linux, shell completion included) | `brew install HostTracker/tap/ht-cli` |
| curl installer (Linux or macOS, installs into `~/.local/bin`) | `curl -fsSL https://raw.githubusercontent.com/HostTracker/cli/main/install.sh \| sh` |
| Windows (Scoop) | `scoop bucket add hosttracker https://github.com/HostTracker/scoop-bucket` then `scoop install ht-cli` |
| Docker (for a CI job, nothing to install) | `docker run --rm -e HT_TOKEN ghcr.io/hosttracker/ht-cli:latest monitors list` |
| Go 1.24 or newer | `go install github.com/HostTracker/cli/cmd/ht-cli@latest` |

**Debian and Ubuntu** (signed apt repository):

```sh
curl -fsSL https://hosttracker.github.io/apt/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/hosttracker.gpg
echo "deb [signed-by=/usr/share/keyrings/hosttracker.gpg] https://hosttracker.github.io/apt stable main" \
  | sudo tee /etc/apt/sources.list.d/hosttracker.list
sudo apt update && sudo apt install ht-cli
```

**Fedora and RHEL** (dnf repository):

```sh
sudo curl -fsSL -o /etc/yum.repos.d/hosttracker.repo https://hosttracker.github.io/apt/rpm/hosttracker.repo
sudo dnf install ht-cli
```

**Release binaries** for Linux, macOS and Windows (amd64 and arm64), plus `.deb`, `.rpm` and `.apk` packages for a
one-off install, are on the [releases page](https://github.com/HostTracker/cli/releases). Verify the archive
against `checksums.txt` and put `ht-cli` on your `PATH`. A winget package is waiting for review in the community
repository and is not available yet.

Check the install with `ht-cli version`. Outside Homebrew, `ht-cli completion bash|zsh|fish|powershell` prints a
completion script.

### Update

Update through the channel you installed with: `sudo apt upgrade`, `sudo dnf upgrade`, `brew upgrade ht-cli`,
`scoop update ht-cli`, or `docker pull ghcr.io/hosttracker/ht-cli`. The curl installer and release binaries are
reinstalls - run the installer again or replace the binary.

## Sign in

1. Mint a token under **Integrations -> API** (`/integrations/api`) with the scopes the commands you plan to run
   need - see [API authentication, tokens and scopes](/integrations/api-authentication/).
2. Run:

   ```sh
   ht-cli auth login
   ```

   It prompts for the token, verifies it against the API and stores it in a YAML file under your OS configuration
   directory, written with `0600` permissions. `ht-cli config path` prints where.

Other ways to supply the token:

- `--token <token>` on a single command.
- The `HT_TOKEN` environment variable - the usual choice in CI; no config file is needed.
- Named profiles for several accounts: `ht-cli auth login --profile staging` stores a second token, and
  `--profile staging` selects it per command.

`ht-cli auth status` shows what is configured and `ht-cli auth logout` removes it. `ht-cli config get|set` reads and
changes `base-url` and the default `output`.

## Commands

Commands are grouped by API resource (`monitors`, `contacts`, `status-pages`, `webhooks`, `jobs` and so on). The
command name follows the API operation: `listMonitor` becomes `ht-cli monitors list`, `getMonitor` becomes
`ht-cli monitors get <id>`, `bulkCreateMonitor` becomes `ht-cli monitors bulk-create`.

- Path parameters are positional arguments.
- Query parameters are flags. `--limit`, `--cursor`, `--sort`, `--expand` and `--fields` work wherever the
  operation takes them.
- A request body is `--json '<inline>'`, `--json @file.json` or `--json -` (stdin); `--set key=value` builds a
  simple body without writing JSON.
- `--idempotency-key` sets the header explicitly; otherwise the SDK adds one to every write.

A quick tour:

```sh
ht-cli monitors list                                  # a table on a terminal, JSON when piped
ht-cli monitors get <monitor-id>
ht-cli check run https://example.com --type http --wait
ht-cli monitors create --json @monitor.json
ht-cli monitors bulk-update --json @edit.json         # answers with a job id
ht-cli jobs wait <job-id>
ht-cli monitors list --output json | jq -r '.data[].url'
```

Hand-written convenience commands on top of the generated ones:

| Command | What it does |
|---|---|
| `ht-cli check run <url> [--type http] [--pool ...] [--wait]` | Runs an instant check; `--wait` follows it to the result. |
| `ht-cli jobs wait <job-id>` | Polls an asynchronous job until it finishes. |
| `ht-cli webhooks verify --secret <s> --headers-file <file> < body` | Verifies a webhook delivery's signature. |
| `ht-cli api GET /monitor --query limit=5 --query state=down` | Calls any API path directly - the escape hatch for anything without a named command. |
| `ht-cli docs` | Generates the command reference. |
| `ht-cli version`, `ht-cli completion <shell>` | Version and shell completion. |

Global flags: `--output json|yaml|table` (or `-o`), `--all` (follow `nextCursor` through every page),
`--base-url`, `--timeout`, `--no-retry`, `--verbose` (prints each request, its status, request id and rate-limit
budget to stderr, retries included).

## Output

The default is a table on a terminal and JSON when the output is piped, so `ht-cli monitors list | jq` needs no
flag. The table view shows scalar fields, folds nested objects into a short marker and renders Unix-second
timestamps as readable times. Anything a script depends on should ask for `--output json` explicitly.

## Exit codes

| Code | Meaning |
|---|---|
| 0 | The command did what it was asked. |
| 1 | A failure with no more specific code. |
| 2 | The command line was wrong: an unknown flag, a missing argument, a bad value. |
| 3 | The credential is missing, rejected or under-scoped (`invalid_token`, `missing_scope`). |
| 4 | The address names nothing (`not_found`). |
| 5 | The API refused the request: validation, a conflict, a precondition. |
| 6 | Throttled, or the quota is exhausted. |
| 7 | The API could not be reached, or faulted. |

A failure prints the problem document's `code`, `detail`, the offending members and the request id to stderr; with
`-o json` the whole problem document is printed. Exit code 6 covers two different causes: `rate_limited` is worth
retrying, `quota_exceeded` is not - only the printed code tells them apart. See
[Error codes](/reference/error-codes/#rest-api-v2-error-codes).

## Use in CI

Store the token as a secret, export it as `HT_TOKEN`, and call `ht-cli` like any other tool. A deploy gate:

```sh
export HT_TOKEN="$HT_TOKEN_SECRET"
ht-cli check run https://staging.example.com --type http --wait
```

Pausing a monitor around a deploy:

```sh
ht-cli monitors update <monitor-id> --json '{"enabled":false}'
# ... deploy ...
ht-cli monitors update <monitor-id> --json '{"enabled":true}'
```

For a planned change that should not alert or count as downtime, a
[maintenance window](/maintenance/create/) is usually the better tool than pausing.

Monitors as code:

```sh
ht-cli monitors list --output json --all > monitors.json   # export what you have
ht-cli monitors bulk-create --json @monitors.json          # create from a file (answers with a job)
```

A monitor is unique per `(url, type)`, so re-running a create for an address you already monitor answers
`409 duplicate_monitor` naming the existing id instead of creating a duplicate.

On GitHub Actions, the [HostTracker Check action](/integrations/github-action/) wraps the CLI for the common cases.

## Related

- [API authentication, tokens and scopes](/integrations/api-authentication/)
- [REST API v2](/integrations/rest-api/)
- [GitHub Action](/integrations/github-action/)
- [Official SDKs](/integrations/sdks/)
