Command-line client for Simplepush.
Binaries: simplepush and sp (alias).
bun add -g @simplepush/cli
# or
npm install -g @simplepush/cli
# or run without installing
bunx @simplepush/cli events --since 24hsp task Send a task, optionally wait for the first completion.
sp subtask Append a follow-up to an existing task via its append token.
sp notify Send a fire-and-forget notification.
sp collect Collect replies, inputs, or submissions as bounded NDJSON.
sp download Download one file a collect line referenced, by its ids.
sp events Stream or replay the raw event feed.
sp auth Log in to an organization (login / logout / status).
sp org Administer an organization: members, invites, topics, API key, encryption.
Two credentials, picked automatically: your personal API token (from the app settings, via --api-token or $SP_API_TOKEN) for personal sends and sp events, and an organization session (sp auth login) for org sends, org-wide collects and downloads, and sp org.
sp task -t ops --title "Deploy v2.1.0 to prod?" \
-a "approve=Approve:primary,abort=Abort:destructive" \
--wait--wait blocks until the recipient taps a button on their phone and prints the result. This turns any shell script into something that can stop and ask a human.
Tasks carry typed inputs: text, single or multi choice, action buttons, sliders, photo, voice recording, file upload, and GPS location.
sp task -t field-crew --title "Morning site check" \
--photo-input "Photo of the meter" \
--slider-input "Water temperature;min=0;max=40;step=0.5;unit=C" \
--choice-input "Which pumps are running?;P1,P2,P3;multi=true" \
--text-input "Anything unusual?;required=false"--format json prints a machine-readable sent line that sp collect consumes. Every answer then arrives as one JSON line, and a final end line tells you why the stream stopped. Built for scripts and agents.
sp task -b --format json --title "Standup" \
--text-input "What did you ship today?" \
| sp collect --inputs > answers.ndjsonNotifications work the same way when they carry an input:
sp notify -t ops --content "Restart the staging cluster?" -c "Approve,Deny" \
--format json | sp collect--save-files downloads every collected file (photos, voice recordings, file uploads, reply and submission files) into a directory as it streams in, decrypted and checksum-verified. Each file object on the NDJSON line gains a path with the saved location.
sp task -b --format json --title "Site check" --photo-input "Photo of the meter" \
| sp collect --inputs --save-files ./meter-photossp download fetches a single file after the fact, using the ids a collect line carried (taskId + the upload's id, or a submission's id + its file's id):
sp download tsk_0198… inp_0198… # task input upload or rfl_… reply file
sp download sbm_0198… sbf_0198… --out . # submission fileIt searches the last 7 days of your event stream for the file's metadata; pass --since 90d for older files.
A submission is content you push from the app with no task attached: a note, a photo, a file, a voice memo, a location. sp collect --submissions streams your inbox as NDJSON, one line per submission, and watches until Ctrl-C:
sp collect --submissions --save-files ./inbox -p "account-password"Attachments land in ./inbox; the bare -p password is your account default and decrypts encrypted submissions. --since 7d backfills earlier submissions first.
Omit the target entirely and the send goes to all of your own devices.
sp task --title "Pick up the package" --content "Locker 14, code 8841"password@topic encrypts everything sent to that topic on your machine; the same flag decrypts on receive. The server never sees plaintext.
sp task -t alerts -p "hunter2@alerts" --title "Rotate the door code" \
--text-input "New code?"
sp events -t alerts --since 24h -p "hunter2@alerts"sp task -t design --markdown -f mock.png \
--title "Design review" \
--content "Check the **hero section**, then vote:" \
-c "Ship it,Iterate"Files are uploaded (and encrypted when the send is), --link attaches URLs instead.
Every send prints an append token. sp subtask uses it to push another step onto the task the recipient already has, with the full input palette available.
sp subtask --append-token "$TOKEN" \
--content "One more approval needed" \
-a "accept=Accept:primary,deny=Deny:destructive"sp events # live firehose
sp events --since 7d --type submission --format pretty
sp collect --submissions --until count:1 # block until the next inbox submissionsp auth login # browser or device-code flow
sp org members invite "Alice" # prints a one-time login code for her app
sp notify -b --title "All hands at 3pm" --content "Room 2"
sp task -m "Alice" --title "Badge photo" --photo-input "A selfie please"
sp org encryption enable # end-to-end encryption for the whole orgRun sp <command> --help for every flag, or see the full CLI guide.
Bun can compile the CLI into a single-file native binary:
bun run build:binary
./bin/simplepush --help