Skip to main content
Command line

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.

One API token powers the REST API, the SDKs, ht-cli and the MCP server · 30-day trial · no credit card
ht-cli monitors list --state down
$ 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
Table on a terminal, JSON the moment the output is piped.
Commands139Generated from the OpenAPI document, so the CLI cannot drift behind the API.
Command groups14Monitors, contacts, alerts, reports, webhooks, status pages and more.
Install channels8Homebrew, curl, apt, dnf, Docker, Scoop, winget, release binaries.
Output formats3table, json, yaml - table on a terminal, JSON when piped.
Exit codes6One per failure class, plus 0 for success and 1 for anything else.
LicenceMITSource at github.com/HostTracker/cli.
Getting started

Up and running in three steps

  1. Install it. Pick any of eight channels; Homebrew is the fastest route on macOS and Linux.
    brew install HostTracker/tap/ht-cli
  2. Log in. Mint a token on the Integrations - API page, then let ht-cli store it.
    ht-cli auth login
    ht-cli auth status
    The token is written 0600 under the OS configuration directory; --profile staging keeps a second account beside the default one, and a CI job usually skips this step and exports HT_TOKEN instead.
  3. Run the first command. No further setup - the token is already in force.
    ht-cli monitors list
Command tree

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.

18 commands

monitors

Create, read, change and bulk-edit monitors - the core of the CLI.

3 commands

monitor-types

The catalogue of check types and their settings schema.

5 commands

results

Individual check results and their summaries.

5 commands

incidents

Downtime incidents, their checks and their comments.

6 commands

maintenance

Planned maintenance windows.

19 commands

contacts

Notification contacts, contact groups and confirmations.

21 commands

alerts

Who is alerted about which monitor, and what was sent.

19 commands

reports

Report subscriptions and generated reports.

8 commands

webhooks

Webhook endpoints, their deliveries and test sends.

18 commands

status-pages

Public status pages, their incidents, templates and subscribers.

5 commands

account

The account, its quota and its usage.

3 commands

monitoring-locations

The monitoring locations checks can run from.

5 commands

instant-checks

One-off checks run on demand, without a monitor.

4 commands

jobs

Long-running batch jobs started by the bulk operations.

hand-written

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.

Real commands

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.

CodeMeaning
2Usage - an unknown flag, a missing argument, a bad value.
3Auth or scope - the credential is missing, rejected or under-scoped.
4Not found - the address names nothing.
5Validation - the API refused the request: a bad body, a conflict, a precondition.
6Rate limit or quota - throttled, or the quota is exhausted.
7Network - the API could not be reached, or faulted.
Distribution

Install it your way

ChannelPlatformCommand
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.
Access, limits and safety

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.

PlanAPI accessReadsWrites
Free, Personal, WebmasterNot included--
30-day trialIncluded10 per minute, 10,000 per month5 per minute, 500 per month
BusinessIncluded60 per minute, 100,000 per month30 per minute, 20,000 per month
EnterpriseIncluded120 per minute, 1,000,000 per month60 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-Reset and RateLimit-Policy; a 429 carries Retry-After. Current usage is on the Integrations - API page and at GET /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.

30-day free trial - no credit card

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.