Wiring
Island Pulse uses a single JSON field, job_id, to decide whether an incoming webhook should start a new Live Activity or update an existing one. Getting this right is the key to a clean integration.
For the complete request schema (all fields, defaults, and tier notes), see Payload Reference.
The job key
Every POST to /notify should include job_id as the stable routing key for that run.
- Format:
1–64characters. Allowed characters: letters (A–Z,a–z), digits (0–9), underscore (_), and hyphen (-) only. No spaces or other symbols. - Required: requests without
job_idare rejected with400 MISSING_JOB_ID.
Two POSTs with the same job_id target the same Live Activity. Two POSTs with different job_id values produce independent activities. Invalid job_id values return 400 INVALID_JOB_ID with an error message (no silent fallback to alternate field names).
Start → update → end lifecycle
You don’t need to manage state yourself. Island Pulse tracks whether a Live Activity is already running for a given job key:
- No activity running → Island Pulse starts a new Live Activity on your phone.
- Activity already running → Island Pulse updates it in place.
action: "end"→ Island Pulse dismisses the activity.
In practice this means you can send the exact same payload structure throughout a job’s lifetime, Island Pulse handles the routing automatically.
# Step 1, first POST: no activity running, Island Pulse starts onecurl -X POST "https://api.islandpulse.dev/notify" \ -H "Authorization: Bearer YOUR_SECRET_ID" \ -H "Content-Type: application/json" \ -d '{"job_id": "nightly-build", "message": "Build started", "status": "running"}'
# Step 2, subsequent POSTs: activity is running, Island Pulse updates it in placecurl -X POST "https://api.islandpulse.dev/notify" \ -H "Authorization: Bearer YOUR_SECRET_ID" \ -H "Content-Type: application/json" \ -d '{"job_id": "nightly-build", "message": "Running tests…", "status": "running", "progress": 0.4}'
# Step 3, finish the jobcurl -X POST "https://api.islandpulse.dev/notify" \ -H "Authorization: Bearer YOUR_SECRET_ID" \ -H "Content-Type: application/json" \ -d '{"job_id": "nightly-build", "message": "All 142 tests passed", "status": "success"}'Naming conventions
Use short, stable IDs such as github-deploy, api-health, or daily-report. job_id is for routing and matching updates, not display text.
| Pattern | Example job_id |
|---|---|
| CI pipeline | github-deploy, gitlab-staging |
| Uptime monitor | api-health, db-health |
| Cron job | daily-report, invoice-sync |
| Metric pulse | mrr-today, signups-today |
Multiple concurrent jobs (Pro)
Free tier is limited to one active job_id per webhook URL. If you send a different job_id while one is active, the request is rejected with 403 FREE_TIER_JOB_LOCKED (support code TIER_LIMIT_EXCEEDED).
Pro tier removes this limit (up to the iOS system cap of 5 simultaneous Live Activities per app). Run as many independent job_id values as you need, each one is tracked and updated separately.
# Pro: three independent jobs running at the same timecurl -X POST "https://api.islandpulse.dev/notify" -H "Authorization: Bearer YOUR_SECRET_ID" -d '{"job_id": "deploy-prod", ...}'curl -X POST "https://api.islandpulse.dev/notify" -H "Authorization: Bearer YOUR_SECRET_ID" -d '{"job_id": "db-backup", ...}'curl -X POST "https://api.islandpulse.dev/notify" -H "Authorization: Bearer YOUR_SECRET_ID" -d '{"job_id": "report-gen", ...}'Activity session length
Live Activities are capped by iOS at 8 hours. Pro users get automatic session renewal, if a session expires, the next update seamlessly starts a fresh one. Free users’ activities expire after 8 hours without renewal.
On the Free tier, if a different job_id is sent while the active lock is still valid, you’ll get a lock error until that job ends (or lock expiry is reached).
Title fields
Use title for the Live Activity card title. The start notification banner uses the same resolved title automatically.
{ "job_id": "deploy-prod", "title": "Vercel Deploy", "message": "Build queued", "status": "running"}If title is omitted, Island Pulse derives the title from message. Update pushes are silent by design.