Incidents
List incidents and drive their lifecycle — acknowledge and resolve — from your own tooling.
The incident object:
{
"id": 19351,
"object": "incident",
"status": "firing",
"severity": "critical",
"message": "http.status_code >= 500",
"monitor": { "id": "0b0f6a41-…", "name": "Marketing site" },
"started_at": "2026-08-24T10:14:59.000Z",
"acknowledged_at": null,
"resolved_at": null
}status follows the lifecycle firing → acknowledged → resolved. Incidents
only open after multi-location confirmation — see
how incidents work.
List incidents
GET /v1/incidents — newest first.
Query parameters: status (firing | acknowledged | resolved),
severity (warning | critical), monitor_id (only that monitor's
incidents), since / until (ISO 8601 range on started_at), limit
(1–100, default 50), cursor — pass the previous page's next_cursor
to fetch the next page (same pattern as
monitors). The response carries total,
has_more and next_cursor.
Each incident includes rule — the alert rule as it was when the
incident fired (name, metric, operator, value; frozen to the
fire-time version) — and duration_seconds (null while still firing).
curl "https://watchfor.io/api/v1/incidents?status=firing" \
-H "Authorization: Bearer wf_live_YOUR_KEY"{
"object": "list",
"data": [ { "id": 19351, "object": "incident", "…": "…" } ],
"total": 128,
"has_more": true
}Get an incident
GET /v1/incidents/{id}
curl https://watchfor.io/api/v1/incidents/19351 \
-H "Authorization: Bearer wf_live_YOUR_KEY"Acknowledge an incident
POST /v1/incidents/{id}/acknowledge — requires write scope. Marks the
incident as being handled; escalation chains stop at acknowledgement.
curl -X POST https://watchfor.io/api/v1/incidents/19351/acknowledge \
-H "Authorization: Bearer wf_live_YOUR_KEY"Returns the full incident object with status: "acknowledged" and
acknowledged_at set. Idempotent: acknowledging an already-acknowledged
incident returns 200 with the current object; acknowledging a resolved
incident is an invalid transition and returns 409 conflict.
{
"id": 19351,
"object": "incident",
"status": "acknowledged",
"acknowledged_at": "2026-08-24T16:02:11.000Z",
"…": "…"
}Resolve an incident
POST /v1/incidents/{id}/resolve — requires write scope. Manually closes
the incident and resets the alerting engine's state for that rule, so the
next genuine failure opens a fresh incident.
Resolution is processed asynchronously by the alerting pipeline, so a
successful request returns 202 Accepted with the incident's current
state — poll GET /v1/incidents/{id} until status is resolved (usually
within a few seconds). Resolving an already-resolved incident is an
idempotent no-op that returns 200 with the resolved object.
curl -X POST https://watchfor.io/api/v1/incidents/19351/resolve \
-H "Authorization: Bearer wf_live_YOUR_KEY"{
"id": 19351,
"object": "incident",
"status": "acknowledged",
"resolved_at": null,
"…": "…"
}Mark an incident as maintenance
POST /v1/incidents/{id}/mark-maintenance — requires write scope.
Retroactively reclassifies a resolved incident's time range as
maintenance: the range is excluded from uptime/SLA numbers and the
incident gets the "Maintenance" badge in the dashboard. Useful when a
deploy caused an outage that shouldn't count against your SLA.
Idempotent — marking the same incident again returns the existing
marking. To undo, DELETE the returned maintenance window. Marking a
firing or acknowledged incident returns 409 — resolve it first.
curl -X POST https://watchfor.io/api/v1/incidents/19351/mark-maintenance \
-H "Authorization: Bearer wf_live_YOUR_KEY"{
"id": 19351,
"object": "maintenance_marking",
"incident_id": 19351,
"maintenance_window": { "id": "19a612d1-…", "object": "maintenance_window", "…": "…" }
}Incident statistics
GET /v1/incidents/stats?period=24h|7d|30d|90d (default 7d) — aggregate
numbers for reporting and wallboards: totals by severity, MTTR (mean time
to resolve, only incidents that resolved), MTBF (period ÷ incident count),
per-bucket counts (hourly for 24h, daily otherwise) and the five most
unstable monitors. For an instant "what's on fire right now" snapshot use
GET /v1/summary instead.
curl "https://watchfor.io/api/v1/incidents/stats?period=30d" \
-H "Authorization: Bearer wf_live_YOUR_KEY"{
"object": "incident_stats",
"period": "30d",
"total": 12,
"critical": 9,
"warning": 3,
"mttr_seconds": 840,
"mtbf_seconds": 216000,
"counts": [{ "bucket": "2026-08-01", "count": 2 }, { "…": "…" }],
"top_unstable_monitors": [
{ "id": "de5c56f7-…", "name": "www.example.com", "incident_count": 5 }
]
}