CLI and cURL
The honk-me 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-me/honk-goPublished - Source
- github.com/honk-me/honk-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-me/honk-go/cmd/honk-me@latest
# or download a prebuilt binary (Linux, macOS, Windows; amd64 and arm64):
# https://github.com/honk-me/honk-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-me.app HONK_KEY=honk_… # better: your secret store
honk-me beep "Backup finished" "nightly pg_dump took 42 s"
honk-me 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. send, problem and recovery take flags. honk-me send -h lists them all.
honk-me loud "Disk 91%" # shortcut: light, beep, loud, long, blast
honk-me beep "Backup finished" "nightly pg_dump took 42 s" # [TITLE] MESSAGE, flags anywhere
honk-me 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-me problem --group-key db/backup --title "Backup failed" --message "pg_dump exited with 1"
honk-me recovery --group-key db/backup --title "Backup OK" --message "pg_dump finished"
tail -c 8000 /var/log/backup.log | honk-me send --title "Backup log" --message - # message from stdin
honk-me send --message "Front door" --image-url https://cam.example.com/snap.jpg --priority high
honk-me 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-me problem --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-me problem --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-me.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.