Skip to content

Uptime & Incidents

Island Pulse is a natural fit for on-call visibility. When something goes down, you want to know the moment it happens, not the next time you check a dashboard. This guide covers the integration patterns for uptime monitors and incident tools.

The incident pattern

Uptime tools typically fire a webhook on state changes, when a monitor transitions from healthy to degraded, and again when it recovers. Map those two states to Island Pulse’s failed and success statuses:

Monitor stateIsland Pulse statusNotes
Degraded / downfailedActivity appears in red, gets your attention
Recovered / upsuccessActivity turns green, confirms resolution
Terminal window
# Incident fires, your monitor calls this
curl -X POST "YOUR_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"job_id": "api-health",
"layout": "default",
"message": "API endpoint returning 503",
"status": "failed",
"icon": "exclamationmark.triangle.fill",
"accentColor": "#FF3B30"
}'
# Recovery fires, same job_id, new status
curl -X POST "YOUR_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{
"job_id": "api-health",
"layout": "default",
"message": "API recovered. Downtime: 4m 12s",
"status": "success",
"icon": "checkmark.circle.fill",
"accentColor": "#34C759"
}'

Both pushes use the same job_id. The recovery updates the same Live Activity in place rather than opening a new one.

Using the Score layout for status metrics

For monitors that track a quantitative value (response time, error rate), use the Score layout to surface the number prominently:

{
"job_id": "p99-latency",
"layout": "score",
"metric": "2,840ms",
"message": "p99 response time, degraded",
"secondaryMetric": "SLOW",
"status": "failed",
"accentColor": "#FF9500"
}

When it recovers:

{
"job_id": "p99-latency",
"layout": "score",
"metric": "120ms",
"message": "p99 response time, healthy",
"secondaryMetric": "OK",
"status": "success"
}

Integrating with common tools

Better Uptime / UptimeRobot

These tools support custom webhook URLs with configurable JSON bodies. Point the webhook URL at your Island Pulse /notify endpoint and configure the payload like this:

{
"job_id": "site-health",
"layout": "default",
"message": "Monitor {{monitorFriendlyName}} is {{alertTypeFriendlyName}}",
"status": "{{#is alertType 'down'}}failed{{else}}success{{/is}}"
}

Replace the template variables with whatever your specific tool uses.

PagerDuty / OpsGenie webhooks

Route PagerDuty outbound webhooks through a small middleware script that reformats the payload:

import requests, json
def forward_to_island_pulse(pd_event: dict, webhook_url: str):
event_type = pd_event.get("event", {}).get("event_type", "")
summary = pd_event.get("event", {}).get("data", {}).get("title", "Incident")
status = "failed" if "triggered" in event_type else "success"
message = summary[:80] # keep within field limits
requests.post(webhook_url, json={
"job_id": "pagerduty",
"layout": "default",
"message": message,
"status": status,
"icon": "bell.fill" if status == "failed" else "bell.slash.fill"
})

Heartbeat / dead man’s switch

Some teams send a periodic heartbeat from a cron job and treat a missing pulse as an incident signal. For this, combine Island Pulse with a cron job that posts a success update on each scheduled run. If the update stops arriving, you know the job died. See the Cron guide for the full pattern.

Multiple services

Run one job key per monitored service. They each get their own Live Activity slot:

Terminal window
# Check each service independently
curl -X POST "YOUR_WEBHOOK_URL" -d '{"job_id": "api-health", "message": "503 errors", "status": "failed"}'
curl -X POST "YOUR_WEBHOOK_URL" -d '{"job_id": "db-health", "message": "Connection timeout", "status": "failed"}'
curl -X POST "YOUR_WEBHOOK_URL" -d '{"job_id": "cdn-health", "message": "All edges healthy", "status": "running"}'