Send your first push notification
Three steps and about a minute: sign in, grab your keys, send one POST request. It's Pushover's API, so existing Pushover code only needs a new host and keys.
1. Sign in and allow notifications
Open pushpiper.com/app on each device you want pings on, sign in with Google and allow notifications when asked.
- Android, Windows, macOS and Linux: Chrome, Edge, Firefox and Safari deliver notifications straight from the browser. Install PushPiper from the address bar for its own icon and window.
- iPhone and iPad: open pushpiper.com/app in Safari, tap Share, then Add to Home Screen. Open PushPiper from the home screen and allow notifications. This needs iOS or iPadOS 16.4 or later.
Give each device a short name like pixel or work-laptop, so you can target it with the device parameter later.
2. Get your user key and an app token
Your user key is shown in the app after you sign in. Then create an app for each script, server or service that sends notifications. Its name becomes the default title, and its API token authenticates your requests.
Both are 30 characters long. User keys start with u and app tokens with a.
3. Send your first message
Replace APP_TOKEN and USER_KEY, then run one of these. The notification lands on every device you signed in on.
curl -s \
--form-string "token=APP_TOKEN" \
--form-string "user=USER_KEY" \
--form-string "message=Backup finished in 42 seconds." \
https://api.pushpiper.com/1/messages.jsonimport requests
response = requests.post(
"https://api.pushpiper.com/1/messages.json",
data={
"token": "APP_TOKEN",
"user": "USER_KEY",
"message": "Backup finished in 42 seconds.",
},
timeout=10,
)
print(response.status_code, response.json())const response = await fetch("https://api.pushpiper.com/1/messages.json", {
method: "POST",
body: new URLSearchParams({
token: "APP_TOKEN",
user: "USER_KEY",
message: "Backup finished in 42 seconds.",
}),
});
console.log(response.status, await response.json());package main
import (
"fmt"
"io"
"net/http"
"net/url"
)
func main() {
resp, err := http.PostForm("https://api.pushpiper.com/1/messages.json", url.Values{
"token": {"APP_TOKEN"},
"user": {"USER_KEY"},
"message": {"Backup finished in 42 seconds."},
})
if err != nil {
panic(err)
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
fmt.Println(resp.Status, string(body))
}<?php
$ch = curl_init("https://api.pushpiper.com/1/messages.json");
curl_setopt_array($ch, [
CURLOPT_POSTFIELDS => [
"token" => "APP_TOKEN",
"user" => "USER_KEY",
"message" => "Backup finished in 42 seconds.",
],
CURLOPT_RETURNTRANSFER => true,
]);
$response = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), " ", $response, PHP_EOL;# Add to ~/.profile, then run: push "Backup finished"
push() {
curl -fsS --max-time 10 \
--form-string "token=${PUSHPIPER_TOKEN:?}" \
--form-string "user=${PUSHPIPER_USER:?}" \
--form-string "message=$*" \
https://api.pushpiper.com/1/messages.json > /dev/null
}
./backup.sh && push "Backup finished" || push "Backup failed"A 200 response with "status": 1 means the message was accepted. Anything else comes with an errors array that says what to fix.
Coming from Pushover?
Your code already speaks our API. Change api.pushover.net to api.pushpiper.com and use your PushPiper token and user key. The migration guide covers groups, subscribers and tools that hardcode the Pushover host.
Next steps
- API reference: every endpoint and parameter, from priorities to receipts.
- End-to-end encryption: keep message contents unreadable to us.
- Integrations: Home Assistant, Uptime Kuma, Grafana, n8n, Apprise, GitHub Actions and cron.
- Pricing: 10,000 messages a month free, Pro for €4 a month.