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

POST /api/push Send a push notification

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" }
POST /api/push/:token Token in URL, plain text or JSON body

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"}'
GET /api/push/:token URL-based push (bookmarks, simple webhooks)

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

FieldTypeDescription
token requiredstringYour API token
title requiredstringNotification title (max 512)
messagestringBody text (max 4096)
subtitlestringSubtitle line (max 256)
channelstringGroup name, e.g. "deploys"
prioritystringlow normal high critical
urlstringOpens when notification is tapped
image_urlstringImage attachment URL
soundstringSound name (overrides channel default)
thread_idstringGroup in the same notification thread
interruption_levelstringpassive active time-sensitive
actionsarrayButtons: [{label, url, method?}]
metadataobjectCustom key-value data (max 2KB)

Total payload limit: 64KB.

Priority levels

PriorityBehavior
lowSilent delivery, appears in feed only
normalStandard push with default sound
highProminent alert, highlighted in feed
criticalBypasses 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

EndpointLimit
POST /api/push60 requests/min per token
GET /api/push/:token30 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" }
StatusMeaning
200Notification sent
400Invalid request (missing fields, payload too large)
401Invalid or expired token
403Pro subscription required
429Rate limit exceeded
500Server 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

~/.claude/CLAUDE.md (global) or project 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

AGENTS.md (project root)
## 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")