ht-cli: the HostTracker command line
ht-cli is HostTracker’s official command-line client. Every operation of the REST API v2
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, 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.
Install
Section titled “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):
curl -fsSL https://hosttracker.github.io/apt/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/hosttracker.gpgecho "deb [signed-by=/usr/share/keyrings/hosttracker.gpg] https://hosttracker.github.io/apt stable main" \ | sudo tee /etc/apt/sources.list.d/hosttracker.listsudo apt update && sudo apt install ht-cliFedora and RHEL (dnf repository):
sudo curl -fsSL -o /etc/yum.repos.d/hosttracker.repo https://hosttracker.github.io/apt/rpm/hosttracker.reposudo dnf install ht-cliRelease 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. 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
Section titled “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
Section titled “Sign in”-
Mint a token under Integrations -> API (
/integrations/api) with the scopes the commands you plan to run need - see API authentication, tokens and scopes. -
Run:
Terminal window ht-cli auth loginIt prompts for the token, verifies it against the API and stores it in a YAML file under your OS configuration directory, written with
0600permissions.ht-cli config pathprints where.
Other ways to supply the token:
--token <token>on a single command.- The
HT_TOKENenvironment variable - the usual choice in CI; no config file is needed. - Named profiles for several accounts:
ht-cli auth login --profile stagingstores a second token, and--profile stagingselects 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
Section titled “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,--expandand--fieldswork wherever the operation takes them. - A request body is
--json '<inline>',--json @file.jsonor--json -(stdin);--set key=valuebuilds a simple body without writing JSON. --idempotency-keysets the header explicitly; otherwise the SDK adds one to every write.
A quick tour:
ht-cli monitors list # a table on a terminal, JSON when pipedht-cli monitors get <monitor-id>ht-cli check run https://example.com --type http --waitht-cli monitors create --json @monitor.jsonht-cli monitors bulk-update --json @edit.json # answers with a job idht-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
Section titled “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
Section titled “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.
Use in CI
Section titled “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:
export HT_TOKEN="$HT_TOKEN_SECRET"ht-cli check run https://staging.example.com --type http --waitPausing a monitor around a deploy:
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 is usually the better tool than pausing.
Monitors as code:
ht-cli monitors list --output json --all > monitors.json # export what you haveht-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 wraps the CLI for the common cases.

