Sentinel CLI
The Sentinel CLI manages monitors, groups, incidents, team members, webhooks, status pages, billing, and notification channels from your terminal, and it probes any URL from every monitoring region on demand. It's built for automation, CI/CD pipelines, and server management, and it speaks the same REST API the dashboard uses.
Installation
Requires Node.js 18 or newer.
npm install -g @rootstuff/sentinel
sentinel --version
sentinel --help
Or run it without installing: npx --yes @rootstuff/sentinel check https://example.com
The CLI is open source: rootstuff/sentinel-cli on GitHub, published as @rootstuff/sentinel on npm. Bug reports and pull requests are welcome on GitHub.
Authentication
Create an API token under Account → API tokens, then save it. The CLI also reads
SENTINEL_TOKEN from the environment
and accepts --token on any command,
which is what you'll want in CI.
sentinel auth login --token YOUR_TOKEN
sentinel auth whoami # Verify the token, show user and current team
sentinel auth status # Show config without a network call
sentinel auth logout
Tokens carry permissions (read, create, update, delete), and every command runs against the token's current team. The free plan includes read-only API access; paid plans include full access.
Global Check
sentinel check probes a URL from
every monitoring region right now, without creating a monitor, and prints a per-region table with a
verdict. It exits 0 only when every region reached the URL and 1
otherwise, so a single line turns it into a deploy gate.
sentinel check https://example.com
sentinel check https://example.com --regions ash,nbg --timeout 10
sentinel check https://example.com --allow-partial # exit 0 if at least one region reached it
sentinel check https://example.com --format json
On-demand checks are included in every paid plan. On the free plan the command prints the plan message and exits 1.
Monitor Commands
# List and filter monitors
sentinel monitors list
sentinel monitors list --status offline --format json
sentinel monitors list --type heartbeat --search backup --page 2
# Create and manage
sentinel monitors create --url https://example.com --interval 1
sentinel monitors get 1
sentinel monitors update 1 --interval 0.5
sentinel monitors delete 1 --yes
# Control monitoring
sentinel monitors check 1 # Immediate check
sentinel monitors pause 1 # Pause monitoring
sentinel monitors unpause 1 # Resume monitoring
--interval is in minutes:
0.5 means every 30 seconds, and the
floor depends on your plan. Create and update expose the whole monitor field set: monitor type, sub-checks,
regions, group, HTTP method, accepted status codes, redirects, timeout, headers, body, expiry thresholds, the
settings objects for keyword, JSON, payment and Lighthouse checks (as JSON), and the heartbeat, cron and port
fields. Update only changes the flags you pass.
# Sub-checks from two regions, alert 30 days before the certificate expires
sentinel monitors create --url https://example.com --interval 5 \
--check-types ssl,dns --regions ash,nbg --ssl-threshold 30
# POST with headers and a body
sentinel monitors create --url https://api.example.com/ping --method POST \
--headers '{"Authorization":"Bearer abc"}' --body '{"ping":true}' --accepted-status-codes 2xx
# Keyword check
sentinel monitors create --url https://example.com \
--keyword-settings '{"keywords":[{"phrase":"Welcome","mode":"must_contain"}]}'
# JSON assertion
sentinel monitors create --url https://api.example.com/health \
--json-assertion-settings '{"assertions":[{"path":"status","operator":"equals","value":"ok"}]}'
# Agent payment check: healthy means a 402 with the expected envelope
sentinel monitors update 42 --check-types payment \
--payment-settings '{"expected":{"amount":"0.02","pay_to":"0xYourAddress","network":"eip155:8453"}}'
# Heartbeat, cron, ping, port
sentinel monitors create --type heartbeat --name "Nightly backup" --heartbeat-interval 86400 --heartbeat-grace 600
sentinel monitors create --type cron --name "Reports" --cron-expression "0 6 * * *" --heartbeat-timezone UTC
sentinel monitors create --type ping --url example.com
sentinel monitors create --type port --url db.example.com --port 5432
# Put a monitor in a group (or take it out)
sentinel monitors update 42 --group-id 3
sentinel monitors update 42 --group-id none
Group Commands
Groups nest one level deep. Monitors join a group through --group-id on the monitor commands.
sentinel groups list
sentinel groups get 3
sentinel groups create --name "Production" --description "Customer-facing"
sentinel groups create --name "EU" --parent-id 3
sentinel groups update 3 --name "Prod" --parent-id none
sentinel groups delete 3 --yes # monitors are ungrouped, subgroups move to the top level
Incident Commands
# List and filter
sentinel incidents list
sentinel incidents list --status open
sentinel incidents list --monitor-id 1 --start-date 2026-01-01
# Manage incidents
sentinel incidents get 1
sentinel incidents acknowledge 1 # Acknowledge
sentinel incidents resolve 1 # Resolve
sentinel incidents delete 1 --yes
Team Member Commands
Roles are admin, editor, and viewer. The owner can't be re-roled or removed.
sentinel users list # role, MFA state, last sign-in
sentinel users invite [email protected] --role editor
sentinel users set-role 11 admin
sentinel users remove 11 --yes
sentinel users invitations list
sentinel users invitations set-role 3 viewer
sentinel users invitations cancel 3 --yes
Team Commands
sentinel teams list # shows which team is current
sentinel teams switch 2 # every later command acts on team 2
Webhook Commands
Outbound webhook endpoints receive alert payloads. The URL, auth token, and signing secret are write-only: the API accepts them but never returns them, and leaving them out of an update keeps the stored values.
sentinel webhooks list
sentinel webhooks get 4
sentinel webhooks create --name "PagerDuty" --url https://events.example.com/in \
--auth-type bearer --auth-token TOKEN --severities critical,warning
sentinel webhooks update 4 --no-active
sentinel webhooks update 4 --auth-token ROTATED
sentinel webhooks test 4 # sends a sample payload
sentinel webhooks delete 4 --yes
Status Page Commands
A status page lists one or more monitors as services, passed as id or id:Label pairs.
sentinel status-pages list
sentinel status-pages get 1
sentinel status-pages create --name "Acme Status" --slug acme --monitors 12:API,34:Website
sentinel status-pages update 1 --name "Acme" --monitors 12:API
sentinel status-pages delete 1 --yes
Notification Commands
# List channels
sentinel notifications list
# Configure channels
sentinel notifications create --type slack --webhook-url https://hooks.slack.com/...
sentinel notifications create --type sms --phone +15555550100
# Manage channels
sentinel notifications get slack
sentinel notifications enable slack
sentinel notifications disable sms
sentinel notifications test slack # Send test notification
sentinel notifications delete slack --yes
Billing Commands
Billing is your own account's (the plan owner's), not a team's. Recipients get every paid invoice as a PDF;
billing information is the company, address and tax ID printed on invoices, pushed to Stripe. Needs the
update token ability to change.
sentinel billing get
sentinel billing recipients [email protected] [email protected] # replaces the list, up to five
sentinel billing recipients --clear
sentinel billing information --company "Example Company LLC" --line1 "1 Main St" \
--city Sacramento --state CA --postal-code 95814 --country US \
--tax-id-type us_ein --tax-id 12-3456789
sentinel billing info --company "Example Company LLC" # fields you omit are cleared
CI/CD Integration
Pause a monitor around a deploy, then use sentinel check
as the last step: it fails the job unless every region can reach the site.
name: Deploy with Monitoring
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
env:
SENTINEL_TOKEN: ${{ secrets.SENTINEL_TOKEN }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install -g @rootstuff/sentinel
- name: Pause Monitoring
run: sentinel monitors pause 1
- name: Deploy
run: ./deploy.sh
- name: Resume Monitoring
run: sentinel monitors unpause 1
- name: Verify from every region
run: sentinel check https://example.com
Scripting Examples
# Check for down monitors
DOWN=$(sentinel monitors list --status offline --format json | jq '.data | length')
if [ "$DOWN" -gt 0 ]; then
echo "ALERT: $DOWN monitors are down!"
exit 1
fi
# Pause every monitor in group 3 for maintenance
sentinel monitors list --per-page 100 --format json | \
jq -r '.data[] | select(.group_id == 3) | .id' | \
xargs -I {} sentinel monitors pause {}
# Who on the team hasn't turned on MFA?
sentinel users list --format json | jq -r '.data[] | select(.mfa_enabled == false) | .email'
All Commands Reference
| Category | Commands |
|---|---|
| auth | login, logout, whoami, status |
| check | check <url> (exits non-zero unless every region reaches it) |
| monitors | list, get, create, update, delete, check, pause, unpause |
| groups | list, get, create, update, delete |
| incidents | list, get, acknowledge, resolve, delete |
| users | list, invite, set-role, remove, invitations list, invitations set-role, invitations cancel |
| teams | list, switch |
| webhooks | list, get, create, update, delete, test |
| status-pages | list, get, create, update, delete |
| billing | get, recipients, information (your own account's billing recipients and invoice details) |
| notifications | list, get, create, update, enable, disable, delete, test |
Pro Tip
Use --format json with any command that
prints data for machine-readable output, --yes
to skip confirmation prompts in scripts, and --help
on any command for the full option list.