Push notifications from the CLI and cURL
The honk command sends from shell scripts, cron jobs and CI, with the same retries and idempotency as the libraries. Or skip the install and use one cURL request.
- Package
-
github.com/honk-hq/goPublished - Source
- github.com/honk-hq/go · MIT License
- Requirements
- Linux, macOS or Windows (amd64 or arm64). Go 1.22+ to build it yourself.
Install
The CLI is part of the Go module.
go install github.com/honk-hq/go/cmd/honk@latest
# or download a prebuilt binary (Linux, macOS, Windows; amd64 and arm64):
# https://github.com/honk-hq/go/releases Anyone with an ingestion key (honk_…) can post to its project. Keep it on servers, in jobs and in CI secrets, never in a browser, mobile or desktop app.
Send an event
It reads HONK_URL and HONK_KEY from the environment; the key is never a flag, so it never lands in your shell history or process list.
export HONK_URL=https://honk-honk.app HONK_KEY=honk_… # better: your secret store
honk beep "Backup finished" "nightly pg_dump took 42 s"
honk loud "Disk 91%" --group-key "disk/$(hostname)/var" Commands
The shortcuts light, beep, loud, long and blast set the level and take the text as arguments. uhoh and phew take the group key first, then the text. send takes flags, which work with every command. honk send -h lists them all.
honk loud "Disk 91%" # shortcut: light, beep, loud, long, blast
honk beep "Backup finished" "nightly pg_dump took 42 s" # [TITLE] MESSAGE, flags anywhere
honk send --title "Disk almost full" --message "/var at 91%" --severity loud \
--group-key "disk/$(hostname)/var" --source "$(hostname)" --meta host="$(hostname)" --meta used:=91
honk uhoh db/backup "Backup failed" "pg_dump exited with 1" # GROUP_KEY [TITLE] MESSAGE, or the flags
honk phew db/backup "Backup is back" "pg_dump finished. Nobody needs to know."
tail -c 8000 /var/log/backup.log | honk send --title "Backup log" --message - # message from stdin
honk send --message "Someone's at the front door" --image-url https://cam.example.com/snap.jpg --priority high
honk light "New request from Emily" "Wants a quote for an online shop" \
--action "Reply by email=mailto:[email protected]" --action "Call=tel:+12025550147" # buttons, up to 3 In cron: alert only on failure
Send a recovery only when something was actually broken. A recovery with no open problem still opens a “recovered” episode and notifies, so a recovery after every good run would buzz every night.
0 3 * * * pg_dump app > /backup/app.sql || honk uhoh --group-key db/backup --source "$(hostname)" --title "Backup failed" --message "pg_dump exited with $?" In CI
One idempotency key per run attempt, so the CLI’s own retries never duplicate, and || true so a notification can never fail the build.
- name: Notify
if: failure()
env:
HONK_URL: ${{ secrets.HONK_URL }}
HONK_KEY: ${{ secrets.HONK_KEY }}
run: |
honk uhoh --group-key "ci/${{ github.repository }}/${{ github.ref_name }}" \
--title "CI failed: ${{ github.workflow }}" --message "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" \
--source github-actions --category deployments \
--idempotency-key "gh-${{ github.run_id }}-${{ github.run_attempt }}" || true Exit codes
Add || true where a failed notification must not fail the script.
| 0 | Accepted, or a duplicate of an accepted event |
|---|---|
| 1 | Unexpected answer: a wrong HONK_URL, a redirect, a malformed reply |
| 2 | Usage error, or HONK_URL or HONK_KEY missing |
| 3 | Invalid message: fix the flags |
| 4 | Authentication: invalid or revoked key, urgent not allowed, suspended project |
| 5 | Quota or rate limit (429); stderr shows Retry-After |
| 6 | Idempotency conflict (409): same key, different payload |
| 7 | Temporary failure after retries: rerun with the same --idempotency-key |
With cURL
Nothing to install. Add an Idempotency-Key so cURL’s own retries can’t create duplicates.
curl -sS https://honk-honk.app/v1/messages \
-H "Authorization: Bearer $HONK_KEY" \
-H "Idempotency-Key: backup-$(date +%Y%m%d)" \
-H "Content-Type: application/json" \
-d '{
"title": "Backup failed",
"message": "pg_dump exited with 1",
"severity": "long",
"group_key": "db/backup",
"event_type": "problem"
}'
# → 202 {"id":"msg_…","status":"accepted","duplicate":false,"received_at":"…"} curl --fail-with-body -sS --max-time 10 --retry 3 --retry-all-errors \
-X POST "$HONK_URL/v1/messages" \
-H "Authorization: Bearer $HONK_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: request-42" \
-d '{"title":"New request from Ana Pop","message":"Wants a quote for an online shop, budget €4,000.","severity":"light","priority":"high","category":"customers","group_key":"requests/42"}' Retries that never send twice
- Every send carries an
Idempotency-Key: yours, or a fresh UUIDv7. The same key is reused on every retry, and within 24 hours Honk answers a replay with the original id andduplicate: true, so a lost response never turns into a second message. - Only network errors, timeouts,
429and5xxare retried, with exponential backoff and full jitter, never sooner than the server’sRetry-After. Other4xxresponses are never retried; fix the request instead. - Each attempt times out after 5 seconds and everything stops after 30. A wait that would cross that deadline, like a daily quota that resets at midnight, fails right away and tells you when to retry.
- Fields are validated before sending, and all invalid fields are reported together.