Skip to content

Command Line Interface ​

Send push notifications from your terminal, scripts and CI, and manage Pocket Alert applications, devices, webhooks and API keys. Source code and releases: github.com/PocketAlert/cli.

Installation ​

bash
curl -fsSL https://raw.githubusercontent.com/PocketAlert/cli/main/install.sh | sh
bash
brew install pocketalert/tap/pocketalert
bash
go install github.com/PocketAlert/cli/cmd/pocketalert@latest

The script verifies the SHA-256 checksum and installs to /usr/local/bin (or ~/.local/bin). Set POCKETALERT_VERSION=v2.0.0 to pin a version.

Manual download ​

These links always point to the latest release:

PlatformArchitectureDownload
LinuxAMD64pocketalert_linux_amd64.tar.gz
LinuxARM64pocketalert_linux_arm64.tar.gz
macOSIntelpocketalert_darwin_amd64.tar.gz
macOSApple Siliconpocketalert_darwin_arm64.tar.gz
WindowsAMD64pocketalert_windows_amd64.zip
bash
tar -xzf pocketalert_*.tar.gz
sudo mv pocketalert /usr/local/bin/
# macOS, if Gatekeeper blocks a browser download:
xattr -d com.apple.quarantine /usr/local/bin/pocketalert
powershell
# Unzip, then add the folder with pocketalert.exe to PATH
.\pocketalert.exe --help

Authentication ​

Create an API key in Settings → API Keys, then:

bash
pocketalert auth

Paste the key at the hidden prompt — it stays out of your shell history. The CLI checks the key before saving it to ~/.pocketalert/config.json. You can also pipe it: echo "$KEY" | pocketalert auth.

In CI and containers, skip auth and set an environment variable instead:

VariablePurpose
POCKETALERT_API_KEYAPI key; takes precedence over the saved one
POCKETALERT_API_URLAPI base URL (default https://api.pocketalert.app)
POCKETALERT_CONFIGPath of the config file
bash
pocketalert profile   # who am I?
pocketalert logout    # remove the saved key

Sending notifications ​

bash
pocketalert send "Deploy finished" "v1.4.2 is live"

Title and message can be arguments or flags (-t, -m). Pipe text in, or pass -m -, to read the message from stdin:

bash
df -h | pocketalert send "Disk report"
FlagDescription
-a, --app <tid>Application
-d, --device <tid>Device, or all (default: every device)
-l, --level <level>silent, low, default, high, critical (or -2…2)
--action <type:label:value>Action button, repeat up to 3 times
--image <path|url>Image attachment
--at <time>Deliver at 2026-10-20 09:00 (account timezone), RFC 3339 or Unix seconds
--in <delay>Deliver after 30m, 2h, 1d, 1d12h
-q, --quietPrint only the message TID

Levels ​

bash
pocketalert send "Disk 95%" "/var is almost full" --level high
pocketalert send "Prod is down" "502 from api" --level critical

critical bypasses Do Not Disturb. Paid On the free plan it is delivered as high and the CLI prints a note. See Priority levels.

Action buttons Paid ​

bash
pocketalert send "Deploy failed" "main@4f2c" -l critical \
  --action "view:Open logs:https://ci.example.com/run/1" \
  --action "http:Retry:https://ci.example.com/run/1/retry" \
  --action "copy:Copy SHA:4f2c9e1"
TypeValue
viewURL to open
httpURL (sends POST), GET https://…, or a JSON object {"url":"…","method":"PUT","headers":{…},"body":"…"}
copyText to copy

See Action buttons.

Scheduled delivery Paid ​

bash
pocketalert send "Standup" "In 10 minutes" --at "2026-10-20 09:50"
pocketalert send "Reminder" "Rotate the keys" --in 1d

pocketalert scheduled list                  # pending, soonest first
pocketalert scheduled list --status all
pocketalert scheduled cancel <tid>

Messages can be scheduled up to 30 days ahead. See Scheduled delivery.

Images Paid ​

bash
pocketalert send "Grafana" "CPU spike" --image ./panel.png
pocketalert send "Grafana" "CPU spike" --image https://example.com/panel.png

Interactive mode ​

bash
pocketalert ui

pocketalert ui opens a full-screen app. Browse and search the inbox, read messages (opening one marks it as read), and compose new ones with an application, device, level, delivery time, image and action buttons. Scheduled messages, applications, devices and webhooks — with their recent requests — are one keypress away. New messages appear automatically.

Inbox with the preview pane

The preview pane shows the whole message, including its action buttons and where each one points:

A message with action buttons

n opens the composer. Action buttons use the same type:label:value format as --action:

Composing a new message

KeyAction
tab, 1…5Inbox, Scheduled, Applications, Devices, Webhooks
enter / escOpen / back. On an application or device: show its messages
nNew message, ctrl+s sends
fResend or duplicate the selected message
r / a / uToggle read / mark all read / show only unread
dDelete a message, cancel a scheduled one, remove a resource (asks first)
sSend to the selected application or device
e / v / tRename / app default level / pause or resume a webhook
/Search
yCopy the message text, TID or webhook URL
?All shortcuts

Notify when a command finishes ​

exec runs a command, streams its output as usual, then sends a push with the exit status, duration and the last lines of output. The command's exit code is passed through.

bash
pocketalert exec -- make release
pocketalert exec --on failure -l critical -- ./backup.sh
pocketalert exec -t "Nightly import" --tail 20 -- python import.py
FlagDescription
--on <when>always (default), success, failure
--tail <n>Lines of output to include (default 10, 0 to omit)
-t, --title <name>Name in the title instead of the command

Failed runs default to level high. All delivery flags of send (-a, -d, -l, --action) work here too.

Watch a log ​

watch turns piped lines into notifications. Lines that arrive within --batch (default 5s) are grouped into one push, up to --max-lines (default 20), so a burst of errors costs one message from your daily quota.

bash
tail -f app.log | grep --line-buffered ERROR | pocketalert watch -t "app errors"
journalctl -fu nginx | pocketalert watch --batch 1m -l high

Messages ​

bash
pocketalert messages list                 # 20 newest
pocketalert messages list -n 50 --offset 50
pocketalert messages list --sort asc --device <device-tid>
pocketalert messages get <tid>            # also marks it as read
pocketalert messages read <tid> [<tid>…]
pocketalert messages read --all
pocketalert messages delete <tid> [<tid>…]
pocketalert messages delete --all         # asks for confirmation; --yes in scripts
pocketalert messages stats                # messages per day
pocketalert usage                         # today's usage against the daily limit

Applications ​

bash
pocketalert apps list
pocketalert apps get <tid>
pocketalert apps create -n "Production" -c "#EF4444" -l high
pocketalert apps update <tid> --name "Prod" --level critical
pocketalert apps delete <tid>

--level sets the default level for messages that don't specify one.

Devices ​

bash
pocketalert devices list
pocketalert devices get <tid>
pocketalert devices rename <tid> "Work iPhone"
pocketalert devices delete <tid>

Webhooks ​

bash
pocketalert webhooks list
pocketalert webhooks get <tid>
pocketalert webhooks history <tid> [--status error] [--page 2]
pocketalert webhooks delete <tid>
bash
pocketalert webhooks create -n "GitHub" -m "*"
bash
pocketalert webhooks create -n "Deploy" -m "Deployed %repository.name% by %sender.login%"
bash
pocketalert webhooks create -n "Alertmanager" -m "%alerts.0.annotations.summary%" -l critical \
  --action "view:Open:%externalURL%"
bash
pocketalert webhooks create -n "Uptime" -m "%monitor.name% is %status%" --slug uptime-alerts

The output shows the inbound URL (https://p4a.me/wh/…) and a curl command to test it. webhooks update <tid> changes only the flags you pass; use --active=false to pause a webhook.

Forms ​

bash
pocketalert forms list
pocketalert forms delete <tid>

Forms are created in the web console.

API keys ​

bash
pocketalert apikeys list
pocketalert apikeys create -n "CI"
pocketalert apikeys delete <tid>

WARNING

The token is printed once on creation — store it right away.


Scripting ​

Every command accepts --json and prints the raw API response:

bash
pocketalert messages list --json | jq -r '.data[].title'
TID=$(pocketalert send "Build" "started" -q)

Errors go to stderr and exit with a non-zero code. A 429 response explains the daily limit and when it resets.

Configuration ​

bash
pocketalert config                                    # show settings and where the key comes from
pocketalert config set base_url https://api.example.com
pocketalert config reset base_url

~/.pocketalert/config.json (permissions 600, directory 700):

json
{
  "api_key": "your-api-key",
  "base_url": "https://api.pocketalert.app"
}

Upgrading from 1.x ​

Install 2.x with any method above; it reads the same ~/.pocketalert/config.json, so the saved key keeps working. Scripts may need three changes:

  • A message is required. pocketalert send -t "Cron OK" without -m is an error now. Add a message, pipe one in, or use exec.
  • Don't mix the forms. Use send "Title" "Message" or send -t "Title" -m "Message". send -t "Title" "Message" fails with title given both as argument and --title.
  • Use -m for generated text. A positional message that starts with - (a Markdown list from an AI agent, for example) is parsed as a flag; -m "$text" is always safe.

Release archives are now pocketalert_<os>_<arch>.tar.gz (.zip on Windows) instead of the old cdn.pocketalert.app/cli/*.zip files.

Shell completion ​

bash
pocketalert completion zsh > "${fpath[1]}/_pocketalert"
bash
pocketalert completion bash > /etc/bash_completion.d/pocketalert
bash
pocketalert completion fish > ~/.config/fish/completions/pocketalert.fish

Homebrew installs completions automatically.


Examples ​

GitHub Actions ​

yaml
- name: Deploy
  run: pocketalert exec -t "Deploy ${{ github.ref_name }}" -- make deploy
  env:
    POCKETALERT_API_KEY: ${{ secrets.POCKETALERT_API_KEY }}

Prefer a ready-made step? See the GitHub Action.

Cron ​

bash
# Alert only when the backup fails
0 3 * * * /usr/local/bin/pocketalert exec --on failure -l critical -- /opt/backup.sh

Service check ​

bash
#!/bin/sh
systemctl is-active --quiet nginx || \
  pocketalert send "NGINX down" "on $(hostname)" -l critical \
    --action "view:Status page:https://status.example.com"

Pocket Alert Documentation