Sending
All examples use npx pidge-cli (npm: pidge-cli,
binary pidge, Node ≥ 18, zero dependencies). The CLI reads PIDGE_URL/PIDGE_TOKEN from the
environment or ~/.config/pidge/env — see Quickstart for the key-free setup.
The five types
Section titled “The five types”# Just inform — fire-and-forget, clears when the human opens it (unless they turned "Done when read" off):pidge message --title "Build green" --body "2m12s"
# A pendency they should resolve — the DEFAULT type ("waiting for you" card):pidge important --title "Review PR #42" --url "https://github.com/…/pull/42"
# Urgent — breaks through silent/Focus; --escalate forces an alarm if unanswered:pidge urgent --title "Balance dropped below $5k" --escalate
# A thing with a known time — push at T−lead + a lock-screen countdown:pidge event --title "Team meeting" --event-at "2026-07-14T15:00:00" --lead-minutes 30
# Track something live — Live Activity progress card, no banner:pidge live --title "Deploying api" --status "Building…"# then: pidge live <cid> --step 3/5 · pidge live <cid> --end --outcome "Deployed ✓"Old names still work as aliases: fyi → message, report → important, alert → urgent.
Ask and wait — the one an agent wants
Section titled “Ask and wait — the one an agent wants”pidge ask --title "Approve deploy?" --actions yes,no --timeout 600ask = important --wait: send and block until the human answers, then print the chosen
action as JSON on stdout (exit 0). A timeout exits 3 — that means no answer yet, not
failure. ask requires a way to answer (--actions, --custom-action or a template).
Need a typed answer? Use --actions reply alone — a decision + reply in one send is
refused (one tap on reply would dodge the decision).
ask prints correlation_id=<cid> as its first stderr line, so even a killed ask leaves
a handle behind: pidge wait <cid> resumes the wait instead of re-sending.
Two things can end an ask besides the buttons you offered — handle both (details in Waiting & receiving):
action_id: "done"— the server appends a neutral Done to every ask; the human cleared the pendency without deciding. Terminal; not an approval.- A typed composer message — while
askblocks, a message the human types in the channel wakes it too (CLI ≥ 0.32) and is printed askind: "human_message"; handle it, ack, and re-waiton the cid.
Approval recipes
Section titled “Approval recipes”# Go/no-go with Face ID — important + Approve/Reject + --wait:pidge approval --title "Deploy to production?"# → chosen_action.action_id is "grant" (approved) or "deny" (rejected)
# Gate YOUR OWN risky action behind a human Face-ID tap — deny-default EXIT CODES:pidge approve "Run the schema migration?" --body "Drops legacy_orders" --timeout 300# exit 0 ONLY on explicit allow; deny/timeout/error → non-zeroapprove is built for permission hooks (fail closed) — full treatment in
Approval gates.
Buttons
Section titled “Buttons”# From the built-in catalog:pidge important --title "Ship it?" --actions yes,no,later
# Your own labels (repeatable):pidge important --title "DB migration ready" \ --custom-action "run:Run now:destructive:biometric:terminal" \ --custom-action "defer:Tonight"- Catalog ids:
yes,no,approve,reject,accept,decline,later,done,snooze,reschedule,reply,mute.snooze/done/reschedule/mute/replyare handled by Pidge; the rest come back to you as the chosenaction_id— you interpret the meaning. - Custom-action spec:
id:label[:destructive][:confirm][:biometric][:terminal]. - Gated actions never appear as lock-screen buttons. Anything
destructive/confirm/biometric(and every custom action) shows only on the tap-through detail screen, behind a confirm or Face ID gate — a banner tap can never fire a risky action. - Free-text reply is always available to the human, on any notification.
Rich content and media
Section titled “Rich content and media”pidge important --title "Nightly report" --body-markdown-file report.md # tables; "-" reads stdinpidge message --title "Chart ready" --image ./chart.png # local path → uploaded for youpidge important --title "Report" --file ./report.xlsx # real artifact → Quick Look → Files (≤25 MB)pidge important --title "Prod token rotated" --copy "tok_9f3…" # tap-to-copy valuepidge important --title "Review PR" --url "https://github.com/…" # deep link on tap--body is the banner text; --body-markdown is the rich detail screen the human taps through
to. An --image that’s already an https URL is passed through as-is.
Scheduling, updating, canceling
Section titled “Scheduling, updating, canceling”pidge important --title "Stand-up in 10" --deliver-at "2026-07-14T09:50:00" # server-side schedulepidge message --title "Queue: 12 jobs" --collapse-key queue-status # replaces the prior onepidge cancel <correlation_id> # withdraw a still-scheduled send (409 once it reached the phone)--correlation-id makes sends idempotent (same id → same notification, never a duplicate)
and is the handle you poll, wait on, and get echoed back on every reply. Set it so you can
match answers to tasks; it’s auto-generated if omitted. While a scheduled send hasn’t fired,
re-POSTing the same correlation id edits it in place (full upsert — send the whole desired
shape) and pidge cancel withdraws it; the human also sees scheduled sends in the app and can
delete them before they fire.
Threads and decision queues
Section titled “Threads and decision queues”pidge important --title "Step 2 ready" --thread build-42 # same id ⇒ one strand on the phonepidge ask --title "Decision 2/3" --actions yes,no --after <cid-of-decision-1>--thread groups related sends as one conversation strand; --after <cid> holds a
notification until that one is answered, so the human sees one decision at a time (a snooze
doesn’t advance the queue).
What comes back
Section titled “What comes back”- Fire-and-forget sends print the raw
201JSON on stdout — trust the echo: it shows exactly what was accepted, includingdegraded: true+degrade_reasonwhen the human’s channel policy lowered the loudness (see How Pidge works). --waitsends print thechosen_actionJSON.- Everything human-facing (warnings, the correlation id, snooze notices) goes to stderr — stdout is always machine-readable.
The full flag list is in the command reference.
