Your monitoring, one command away.
ht-cli is HostTracker's uptime monitoring CLI: 139 commands in 14 groups, generated straight from the same OpenAPI document that drives the REST API v2 reference, plus a small hand-written layer for authentication, output and CI. It is built on the official Go SDK, so retries, idempotency and error handling are the SDK's behaviour, not a second implementation of them.
$ ht-cli monitors list --state down --limit 3
ID NAME TYPE STATE URL
0192f3c1-6d0a-7b41-9c22-5b1f4a0e77aa api gateway http down https://api.example.com/health
0192f3c1-7f2b-7c58-8d31-2ac9e5b31c04 checkout http down https://example.com/checkout
0192f3c1-9a44-7d6e-b0a7-71d2c8f9e155 eu edge ping down edge-eu.example.com
3 shown, 3 matched
Up and running in three steps
- Install it. Pick any of eight channels; Homebrew is the fastest route on macOS and Linux.
brew install HostTracker/tap/ht-cli - Log in. Mint a token on the Integrations - API page, then let ht-cli store it.
The token is written 0600 under the OS configuration directory;ht-cli auth login ht-cli auth status--profile stagingkeeps a second account beside the default one, and a CI job usually skips this step and exportsHT_TOKENinstead. - Run the first command. No further setup - the token is already in force.
ht-cli monitors list
Fourteen command groups, one shape
Command names follow the operation they stand for - the verb, then what qualifies it once the group's own noun is dropped - so the shape is the same whether you last ran a command five minutes ago or five months ago.
monitors
Create, read, change and bulk-edit monitors - the core of the CLI.
monitor-types
The catalogue of check types and their settings schema.
results
Individual check results and their summaries.
incidents
Downtime incidents, their checks and their comments.
maintenance
Planned maintenance windows.
contacts
Notification contacts, contact groups and confirmations.
alerts
Who is alerted about which monitor, and what was sent.
reports
Report subscriptions and generated reports.
webhooks
Webhook endpoints, their deliveries and test sends.
status-pages
Public status pages, their incidents, templates and subscribers.
account
The account, its quota and its usage.
monitoring-locations
The monitoring locations checks can run from.
instant-checks
One-off checks run on demand, without a monitor.
jobs
Long-running batch jobs started by the bulk operations.
auth, config, check run, jobs wait, webhooks verify, api, completion, version
The layer generated commands cannot cover: login and profiles, local settings, a one-off check that waits for its result, an offline signature check, a raw escape hatch to any endpoint, and shell completion.
From the terminal and from CI
Pause a monitor before a deploy, resume it after
ht-cli monitors update <monitor-id> --json '{"enabled":false}'
# ... deploy ...
ht-cli monitors update <monitor-id> --json '{"enabled":true}'
Assert a site is up, from a pipeline
ht-cli check run https://example.com --type http --wait
The HostTracker Check GitHub Action wraps the same command for a workflow step and downloads a pinned, checksum-verified ht-cli release with no separate install:
- name: The deployed site answers, everywhere
uses: HostTracker/check-action@v1
with:
token: ${{ secrets.HT_TOKEN }}
mode: assert-up
url: https://example.com
pools: europe,northAmerica
Export every monitor to a file
ht-cli monitors list --output json --all > monitors.json
Monitoring as code
A monitor is a JSON document. Keep the definitions in the repository and apply them with one command; running it again does not create duplicates of what the account already has.
ht-cli monitors bulk-create --json @monitors.json
Wait on a bulk job
A bulk edit is asynchronous - it answers with a job id rather than blocking until every row is done.
job=$(ht-cli monitors bulk-update --json @edit.json -o json | jq -r .jobId)
ht-cli jobs wait "$job"
Verify a webhook signature, offline
ht-cli webhooks verify --secret "$HT_WEBHOOK_SECRET" --headers-file headers.txt < body.json
What the exit code tells a script
0 means the command did what it was asked, and 1 is a failure with no more specific code; everything from 2 to 7 names a distinct reason, so a script can branch on the number without parsing any text.
| Code | Meaning |
|---|---|
| 2 | Usage - an unknown flag, a missing argument, a bad value. |
| 3 | Auth or scope - the credential is missing, rejected or under-scoped. |
| 4 | Not found - the address names nothing. |
| 5 | Validation - the API refused the request: a bad body, a conflict, a precondition. |
| 6 | Rate limit or quota - throttled, or the quota is exhausted. |
| 7 | Network - the API could not be reached, or faulted. |
Install it your way
| Channel | Platform | Command |
|---|---|---|
| Homebrew | macOS, Linux - shell completion included |
brew install HostTracker/tap/ht-cli
|
| curl installer | macOS, Linux - checksum-verified against the release |
curl -fsSL https://raw.githubusercontent.com/HostTracker/cli/main/install.sh | sh
|
| apt repository | Debian, Ubuntu - signed, amd64 and arm64 |
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
|
| dnf repository | Fedora, RHEL - amd64 and arm64 |
sudo curl -fsSL -o /etc/yum.repos.d/hosttracker.repo https://hosttracker.github.io/apt/rpm/hosttracker.repo && sudo dnf install ht-cli
|
| Docker (GHCR) | any platform, nothing to install for a CI job |
docker run --rm -e HT_TOKEN ghcr.io/hosttracker/ht-cli:latest monitors list
|
| Scoop | Windows |
scoop bucket add hosttracker https://github.com/HostTracker/scoop-bucket && scoop install ht-cli
|
| winget | Windows - manifest pending review in the community repository |
winget install HostTracker.ht-cli
|
| Release binaries | Linux, macOS, Windows - amd64 and arm64, SBOM + checksums |
Download from the releases page, verify checksums.txt.
|
One token. Stated limits. Nothing hidden behind "generous".
The same personal API token authenticates the REST API v2, every official SDK, the ht-cli command line client and the MCP server. Mint it once on your HostTracker profile, pick the scopes it may use, and point any of the four at it.
| Plan | API access | Reads | Writes |
|---|---|---|---|
| Free, Personal, Webmaster | Not included | - | - |
| 30-day trial | Included | 10 per minute, 10,000 per month | 5 per minute, 500 per month |
| Business | Included | 60 per minute, 100,000 per month | 30 per minute, 20,000 per month |
| Enterprise | Included | 120 per minute, 1,000,000 per month | 60 per minute, 100,000 per month |
- Scoped tokens. A token carries only the scopes you tick - monitor, contact, webhook, check, status page, report, incident, maintenance, job, account - each as read or write. Grant what the integration needs and nothing else.
- Long-lived, not revocable. Tokens are JWTs with a lifetime you choose (10 years by default) and cannot be revoked before they expire; an account-wide API switch disables every token at once. Treat a token like a password: keep it out of source control, and add an IP allow-list and a per-token request cap when you mint it.
- Limits you can read. Every response carries
RateLimit-Limit,RateLimit-Remaining,RateLimit-ResetandRateLimit-Policy; a 429 carriesRetry-After. Current usage is on the Integrations - API page and atGET /account/quota. - Safe retries. Writes accept an
Idempotency-Key, so a retried request is never a duplicate; long operations return a job you can poll or have delivered to a webhook.
Full details: authentication and limits in the docs. Plans and prices: pricing.
Frequently Asked Questions
On macOS and Linux the fastest route is Homebrew: brew install HostTracker/tap/ht-cli. Linux also has a signed apt repository for Debian and Ubuntu, a dnf repository for Fedora and RHEL, a one-line curl installer that verifies its own checksum, and a standalone .deb, .rpm or .apk if you would rather not add a repository at all. Windows installs through Scoop today, with a winget manifest awaiting review in the community repository. Every channel installs the same binary, and release archives for Linux, macOS and Windows on both amd64 and arm64 are on the GitHub releases page with a checksums file and an SBOM if you need one.
Mint a token on your HostTracker profile, then run ht-cli auth login: it prompts for the token, verifies it against the API and stores it in a YAML config file under the OS configuration directory, written 0600 because it holds a credential. Named profiles let several accounts coexist - ht-cli auth login --profile staging keeps a second token beside the default one, and --profile selects which to use per command. A CI job usually skips the login step entirely and exports HT_TOKEN as an environment variable instead, which ht-cli reads with no config file at all.
Three: table, json and yaml, chosen with --output or -o. Left unset, ht-cli picks for you - a table when the output goes to a terminal, json the moment it is piped or redirected - so ht-cli monitors list | jq needs no flag and neither does reading the same command yourself. The table view is a reading aid: it shows scalar fields, folds a nested object or array into a short {n} or [n] marker, renders Unix-second timestamps as readable instants, and prints how many rows matched. Anything a script depends on should ask for json explicitly rather than rely on the pipe detection.
Yes - it is built for exactly that. Export HT_TOKEN as a secret rather than logging in interactively, use --output json for anything a later step parses, and ht-cli check run <url> --wait for a synchronous pass/fail gate on a deploy. The official HostTracker Check GitHub Action (HostTracker/check-action@v1) wraps ht-cli for the common cases - check, assert-up and create-monitor modes - and downloads a pinned, checksum-verified release of the CLI itself, so a workflow needs no separate install step.
It is the API, packaged as commands. Every one of the 139 generated commands is a thin wrapper over one REST API v2 operation, built on the same Go SDK a developer would use directly - the bearer token, the automatic Idempotency-Key on writes, the retry ladder for 429 and 503, and the RFC 9457 problem-document errors are the SDK's behaviour either way. ht-cli api is the escape hatch for anything not covered by a named command: ht-cli api GET /monitor --query limit=5 --query state=down reaches the raw surface directly, which also makes it the fastest way to reproduce a call from the reference documentation at a terminal.
0 means the command did what it was asked, and 1 is a failure with no more specific code. Everything else names the reason: 2 is a command-line mistake (an unknown flag or a bad value), 3 is a missing, rejected or under-scoped credential, 4 means the address named nothing, 5 means the API refused the request outright, 6 means throttled or out of quota, and 7 means the API could not be reached. A 429 response is deliberately split between 6's two causes - rate_limited is worth retrying, quota_exceeded is not - and only the printed problem code, not the exit code alone, tells them apart; --verbose prints every request's status and rate-limit budget to stderr.
Whichever channel installed it manages the update: sudo apt upgrade on the apt repository, sudo dnf upgrade on the dnf one, brew upgrade ht-cli through Homebrew, scoop update ht-cli on Windows, or a fresh docker pull of the ghcr.io/hosttracker/ht-cli image. The curl script and the release-binary route are reinstalls - rerun the installer, or download the newer archive and replace the binary on PATH. ht-cli version prints what is currently installed if you need to check before deciding.
Yes. A monitor is a JSON document, so ht-cli monitors create --json @monitor.json or the bulk equivalent, ht-cli monitors bulk-create --json @monitors.json, turns a file in your repository into live monitoring - and running it again does not duplicate anything the API already recognises. The HostTracker Check GitHub Action's create-monitor mode does the same from a workflow, looking for an existing monitor with the same url and name before creating a new one. Export the current state back to a file at any time with ht-cli monitors list --output json --all, which is the fastest way to start the file from monitors that already exist.
Keep exploring HostTracker's monitoring
Drive monitoring straight from your own code
The REST API v2 ht-cli itself is built on - 182 operations behind the same token, no CLI required.
Prefer a typed client library?
Official SDKs for TypeScript, Python, Go and .NET, generated from the same specification as ht-cli.
Ask an assistant instead of a shell
Give Claude Code, Cursor, VS Code or Windsurf the same 300+ checkpoints through the MCP server.
Drive your monitoring from the shell
Install ht-cli, log in once, and every HostTracker operation is a command - in your terminal and in your pipelines.