Skip to content

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: 164 characters. Allowed characters: letters (A–Z, a–z), digits (0–9), underscore (_), and hyphen (-) only. No spaces or other symbols.
  • Required: requests without job_id are rejected with 400 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.

Terminal window
# Step 1, first POST: no activity running, Island Pulse starts one
curl -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 place
curl -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 job
curl -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.

PatternExample job_id
CI pipelinegithub-deploy, gitlab-staging
Uptime monitorapi-health, db-health
Cron jobdaily-report, invoice-sync
Metric pulsemrr-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.

Terminal window
# Pro: three independent jobs running at the same time
curl -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.