Auth: session cookie.
Alert deliveries for a monitor. Unparameterized requests remain capped at 50 rows; the monitor detail page requests selectable 25-, 50-, or 100-row cursor-paginated pages. Free users see only a count.
Request fields
limit (integer, optional)
Optional page size for cursor pagination. Defaults to 25 and is capped at 100.
before_started_at (ISO-8601 timestamp, optional)
Use with `before_id` to fetch the page strictly older than the last row returned.
before_id (integer, optional)
Use with `before_started_at` as the stable delivery-id half of the cursor.
status (string, optional)
Filter by an existing delivery status: `sending`, `delivered`, `skipped`, `failed`, `suppressed`, `retrying`, or `recorded`.
event_type (string, optional)
Filter by `down`, `recovery`, `sustained_outage`, `repeated_down`, `escalation`, or `configuration`.
start_date (date or ISO-8601 timestamp, optional)
Inclusive lower boundary for `started_at`; a date-only value starts at 00:00:00 UTC.
end_date (date or ISO-8601 timestamp, optional)
Exclusive upper boundary for `started_at`; a date-only value ends after that entire UTC day.
Response
{
"incidents": [
{
"id": 9931,
"monitor_id": 201,
"check_result_id": 10042,
"incident_id": 477,
"linked_incident_id": 477,
"incident_started_at": "2026-08-08T14:30:00.000Z",
"incident_resolved_at": "2026-08-08T14:38:55.000Z",
"channel_id": 14,
"channel_type": "email",
"channel_name": "Owner",
"status": "delivered",
"error_message": null,
"started_at": "2026-08-08T14:30:01.000Z",
"alert_kind": "incident",
"downtime_ms": null,
"maintenance_window_id": null
}
],
"has_more": true,
"next_cursor": {
"before_started_at": "2026-08-08T14:30:01.000Z",
"before_id": 9931
},
"has_history": true,
"has_matching_history": true
}
curl
# Grab your session cookie from browser devtools
# (Application → Cookies → https://watchdog.app → connect.sid) and save it:
export WD_COOKIE='connect.sid=s%3A…'
curl -X GET https://watchdog.app/api/monitors/201/incidents?limit=25 -b "$WD_COOKIE"
The response `started_at` is the delivery-event time; `linked_incident_id`, `incident_started_at`, and `incident_resolved_at` identify the linked outage and its start and recovery times. The monitor detail page uses `limit=25`, `limit=50`, or `limit=100`, then passes `before_started_at` and `before_id` from `next_cursor` to load older rows. Filter parameters are carried unchanged on each subsequent request, so cursor pagination stays within the same filtered result set. `has_more` is false and `next_cursor` is null when the feed is exhausted. When filters are supplied, `has_history` distinguishes a monitor with any history from `has_matching_history: false` (no records match); an unparameterized Pro request remains `{ incidents: [...] }` with the existing 50-row cap. On free accounts the response is always `{ count: <integer> }` with no row list.