API documentation
Send push notifications to your iPhone from any server, script, or CI pipeline with a single HTTP request.
Quickstart
1. Open Pling on your iPhone. Go to Config > Tokens and generate an API token.
2. Send your first notification:
$ curl -X POST https://api.plingpush.com/api/push \ -H "Content-Type: application/json" \ -d '{"token":"YOUR_TOKEN","title":"Hello from Pling!"}'
3. The notification arrives on your phone instantly via push or WebSocket.
Base URL
https://api.plingpush.com
All endpoints accept and return JSON. Authenticate with your API token in the request body or URL path.
Endpoints
Send a JSON push notification. Include your token in the body.
Request
{
"token": "YOUR_TOKEN",
"title": "Deploy complete",
"message": "Production v2.4.1 is live",
"channel": "deploys",
"priority": "normal"
}
Response 200
{ "ok": true, "id": "notif_a7x9k2" }
Token passed in the URL path. Send plain text (body becomes the message) or JSON without the token field.
# Plain text — body becomes the message curl -d "Server rebooted" https://api.plingpush.com/api/push/YOUR_TOKEN # JSON — token from URL, not body curl -X POST https://api.plingpush.com/api/push/YOUR_TOKEN \ -H "Content-Type: application/json" \ -d '{"title":"Alert","priority":"high"}'
Paste in a browser, bookmark, or use in webhooks that only support GET requests.
https://api.plingpush.com/api/push/YOUR_TOKEN?title=Hello&message=World&priority=high
Query parameters: title (or t), message (or m), priority (or p), subtitle, sound.
Request fields
| Field | Type | Description |
|---|---|---|
| token required | string | Your API token |
| title required | string | Notification title (max 512) |
| message | string | Body text (max 4096) |
| subtitle | string | Subtitle line (max 256) |
| channel | string | Group name, e.g. "deploys" |
| priority | string | low normal high critical |
| url | string | Opens when notification is tapped |
| image_url | string | Image attachment URL |
| sound | string | Sound name (overrides channel default) |
| thread_id | string | Group in the same notification thread |
| interruption_level | string | passive active time-sensitive |
| actions | array | Buttons: [{label, url, method?}] |
| metadata | object | Custom key-value data (max 2KB) |
Total payload limit: 64KB.
Priority levels
| Priority | Behavior |
|---|---|
low | Silent delivery, appears in feed only |
normal | Standard push with default sound |
high | Prominent alert, highlighted in feed |
critical | Bypasses Do Not Disturb and silent mode |
Channels
Channels group notifications by topic. Create them in the app to set custom sounds and mute schedules per channel.
Include "channel": "name" in your request. The notification delivers even if the channel doesn't exist yet in the app — settings just won't apply until you create it.
Rate limits
| Endpoint | Limit |
|---|---|
POST /api/push | 60 requests/min per token |
GET /api/push/:token | 30 requests/min per token |
Returns 429 Too Many Requests when exceeded.
Errors
All responses return JSON:
// Success { "ok": true, "id": "notif_a7x9k2" } // Error { "ok": false, "error": "token and title are required" }
| Status | Meaning |
|---|---|
| 200 | Notification sent |
| 400 | Invalid request (missing fields, payload too large) |
| 401 | Invalid or expired token |
| 403 | Pro subscription required |
| 429 | Rate limit exceeded |
| 500 | Server error |
Code examples
# Basic notification curl -X POST https://api.plingpush.com/api/push \ -H "Content-Type: application/json" \ -d '{"token":"YOUR_TOKEN","title":"Hello"}' # Full example with all common fields curl -X POST https://api.plingpush.com/api/push \ -H "Content-Type: application/json" \ -d '{ "token": "YOUR_TOKEN", "title": "Disk full", "subtitle": "db-01", "message": "/dev/sda1 at 95%", "channel": "alerts", "priority": "critical", "url": "https://grafana.example.com/d/disk" }' # Plain text via token-in-URL echo "Backup complete" | curl -d @- \ https://api.plingpush.com/api/push/YOUR_TOKEN
// Node.js / Bun / Deno const response = await fetch("https://api.plingpush.com/api/push", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ token: process.env.PLING_TOKEN, title: "Build failed", message: error.message, channel: "ci", priority: "high" }) }); const data = await response.json(); // { ok: true, id: "notif_..." }
import requests requests.post("https://api.plingpush.com/api/push", json={ "token": os.environ["PLING_TOKEN"], "title": "Training complete", "message": f"Loss: {final_loss:.4f}", "channel": "ml", "priority": "normal" })
var request = URLRequest( url: URL(string: "https://api.plingpush.com/api/push")!) request.httpMethod = "POST" request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpBody = try JSONEncoder().encode([ "token": "YOUR_TOKEN", "title": "Backup complete", "message": "2.4 GB archived", "channel": "backups" ]) let (data, _) = try await URLSession.shared.data(for: request)
payload, _ := json.Marshal(map[string]string{ "token": os.Getenv("PLING_TOKEN"), "title": "Deploy complete", "channel": "deploys", "priority": "normal", }) http.Post("https://api.plingpush.com/api/push", "application/json", bytes.NewReader(payload))
# .github/workflows/deploy.yml - name: Notify Pling if: always() run: | curl -X POST https://api.plingpush.com/api/push \ -H "Content-Type: application/json" \ -d '{ "token": "${{ secrets.PLING_TOKEN }}", "title": "Deploy ${{ job.status }}", "message": "${{ github.repository }}@${{ github.sha }}", "channel": "deploys", "priority": "${{ job.status == 'failure' && 'high' || 'normal' }}" }'
#!/bin/bash # pling-notify.sh — save and chmod +x TOKEN="${PLING_TOKEN}" TITLE="${1:-Notification}" MSG="${2:-}" PRIORITY="${3:-normal}" CHANNEL="${4:-}" curl -s -X POST https://api.plingpush.com/api/push \ -H "Content-Type: application/json" \ -d "$(jq -n \ --arg t "$TOKEN" --arg title "$TITLE" \ --arg msg "$MSG" --arg p "$PRIORITY" \ --arg ch "$CHANNEL" \ '{token:$t,title:$title,message:$msg,priority:$p,channel:$ch}')" # Usage: ./pling-notify.sh "Deploy OK" "v2.4.1" "normal" "deploys"
# Crontab heartbeat every 6 hours 0 */6 * * * curl -s -o /dev/null \ "https://api.plingpush.com/api/push/YOUR_TOKEN?title=Heartbeat&m=Server+is+alive" # Docker healthcheck HEALTHCHECK --interval=5m CMD curl -sf \ "https://api.plingpush.com/api/push/YOUR_TOKEN?t=Health+OK" || exit 1
AI agent setup
Add Pling notifications to any project by pasting these into your AI coding agent. They'll wire up a notify helper and call it from your deploy/error paths.
Claude Code Add to CLAUDE.md
When you complete a task, send me a push notification:
curl -X POST https://api.plingpush.com/api/push \
-H "Content-Type: application/json" \
-d '{"token": "YOUR_TOKEN", "title": "Done", "message": "Brief summary"}'
For deploy scripts and error handlers in this project, use the
PLING_TOKEN environment variable and send push notifications on
success (priority: normal, channel: deploys) and failure
(priority: high, channel: alerts). Add a notify() helper if one
doesn't exist.
Claude Code reads CLAUDE.md at the start of every conversation. Adding this globally means every project gets Pling notifications automatically.
Codex Add to AGENTS.md
## Notifications
After completing tasks, send a push notification via Pling:
POST https://api.plingpush.com/api/push
Content-Type: application/json
{"token": "$PLING_TOKEN", "title": "Task complete", "message": "summary"}
For deploy and CI scripts, call this endpoint on success
(channel: deploys, priority: normal) and on failure
(channel: alerts, priority: high). Use the PLING_TOKEN env var.
Codex reads AGENTS.md for project instructions. This ensures every Codex agent run notifies you via Pling on completion.
One-shot prompt (any AI agent)
Integrate Pling push notifications into this project.
API endpoint: POST https://api.plingpush.com/api/push
JSON body: {token, title, message?, channel?, priority?}
Token comes from PLING_TOKEN env variable.
Add a notify() helper function. Call it from:
- Deploy success path (channel: "deploys", priority: "normal")
- Error handlers (channel: "alerts", priority: "high")
- Long-running task completion (channel: "tasks")