Incidents & Maintenance
List, report, acknowledge, resolve and comment on incidents, page people about them, and schedule maintenance windows.
Paths are relative to https://api.zharp.io/api/v1, and every request sends a key as Authorization: Bearer zh_live_… — see Authentication. Incident changes need a write key; maintenance changes need admin. Both need the resources:manage permission, which every role but Read-only has.
/incidentsList incidentsGET/incidents/statsCounts by statusGET/incidents/calendarIncidents and downtime per dayGET/incidents/:idOne incident, with its timelineGET/incidents/:id/activitiesThe timeline, pagedPOST/incidentsReport an incidentPOST/incidents/:id/acknowledgeAcknowledgePOST/incidents/:id/resolveResolvePOST/incidents/:id/reopenReopenPOST/incidents/:id/commentsCommentPOST/incidents/:id/attachmentsUpload a file for a commentGET/incidents/:id/logsLog lines around itPOST/incidents/:id/escalatePage people nowPOST/public/incidents/report/:tokenThe public report formGET/maintenanceList maintenance windowsGET/maintenance/:idOne windowPOST/maintenanceSchedule a windowPUT/maintenance/:idChange a windowDELETE/maintenance/:idDelete a windowThe incident lifecycle
An incident is ONGOING when it opens, INVESTIGATING once someone acknowledges it, and RESOLVED when it's over. Monitors open and close their own incidents (mode: AUTOMATIC); the ones people report are MANUAL. A resolved incident can be reopened within 24 hours of being resolved.
| Field | Values |
|---|---|
status | ONGOING, INVESTIGATING, RESOLVED |
mode | AUTOMATIC (raised by a monitor), MANUAL (reported by a person or the public form) |
category | DNS, SSL, HTTP, PING, TCP, TIMEOUT, MAINTENANCE, LOGS, SYNTHETIC, DATABASE, CACHE, INFRASTRUCTURE, SECURITY, EMAIL, COMPLIANCE, UNKNOWN (default) |
activities[].type | COMMENT, ACKNOWLEDGMENT, RESOLUTION, ESCALATION, SYSTEM_LOG, TRACKED_EVENT |
Incidents
/incidents_count.activities counts comments. acknowledgedBy, resolvedBy and reportedBy are { name, email, photoUrl } when set.
pagelimitstatusONGOING,INVESTIGATING. Unknown values are ignored.qsortnewest (default), oldest, or longest — by how long each lasted, open ones counted up to now.curl "https://api.zharp.io/api/v1/incidents?status=ONGOING,INVESTIGATING&limit=20" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "Incidents retrieved successfully",
"data": [
{
"id": 481,
"title": "api.acme.io is down",
"description": null,
"rootCause": "HTTP 503 Service Unavailable",
"status": "ONGOING",
"mode": "AUTOMATIC",
"monitorId": 77,
"startedAt": "2026-10-26T08:14:02.000Z",
"resolvedAt": null,
"monitor": { "name": "API", "type": "HTTP" },
"reportedBy": null,
"reporterEmail": null,
"acknowledgedBy": null,
"resolvedBy": null,
"_count": { "activities": 0 }
}
],
"meta": { "total": 60, "page": 1, "limit": 20, "totalPages": 3 }
}400limitabove 100, orpage/limitbelow 1.
/incidents/statscurl "https://api.zharp.io/api/v1/incidents/stats" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "Incidents retrieved successfully",
"data": { "ongoing": 2, "investigating": 1, "resolved": 57 }
}/incidents/calendaruptimePercentage is null for days still to come; today counts up to now.
monthYYYY-MM. Defaults to the current month.curl "https://api.zharp.io/api/v1/incidents/calendar?month=2026-10" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "…",
"data": {
"month": "2026-10",
"days": [
{
"date": "2026-10-01",
"incidentCount": 2,
"affectedMonitors": 1,
"downtimeSeconds": 840,
"onCall": [{ "id": 12, "name": "Ada", "email": "ada@acme.io", "photoUrl": null }],
"uptimePercentage": 99.03
},
…
]
}
}400monthisn'tYYYY-MM.
/incidents/:idIt also carries what the failing check captured — requestHeaders, requestBody, responseHeaders, responseBody, traceroute — and the AI post-mortem once one is written (aiPostMortem).
idcurl "https://api.zharp.io/api/v1/incidents/481" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "…",
"data": {
"id": 481,
"title": "api.acme.io is down",
"status": "INVESTIGATING",
"rootCause": "HTTP 503 Service Unavailable",
"category": "HTTP",
"startedAt": "2026-10-26T08:14:02.000Z",
"acknowledgedAt": "2026-10-26T08:16:40.000Z",
"resolvedAt": null,
"acknowledgedBy": { "id": 12, "name": "Ada", "email": "ada@acme.io", "photoUrl": null },
"resolvedBy": null,
"monitor": { "id": 77, "name": "API", "type": "HTTP", … },
"activities": [
{
"id": 9001,
"type": "ACKNOWLEDGMENT",
"message": "Status moved to Investigating",
"status": "INVESTIGATING",
"createdAt": "2026-10-26T08:16:40.000Z",
"user": { "name": "Ada", "email": "ada@acme.io", "photoUrl": null },
"attachments": []
},
…
],
…
}
}404No such incident in this workspace.
/incidents/:id/activitiesHere meta is inside data, next to the activities.
idpagelimitcurl "https://api.zharp.io/api/v1/incidents/481/activities?limit=20" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "Activities retrieved successfully",
"data": {
"activities": [
{
"id": 9002,
"incidentId": 481,
"userId": 12,
"type": "COMMENT",
"message": "Rolling back the deploy",
"status": "INVESTIGATING",
"metadata": null,
"createdAt": "2026-10-26T08:20:11.000Z",
"user": { "name": "Ada", "firstName": "Ada", "lastName": "L", "email": "ada@acme.io", "photoUrl": null },
"attachments": []
}
],
"meta": { "total": 7, "page": 1, "limit": 20, "totalPages": 1 }
}
}404No such incident in this workspace.
/incidentsONGOING and MANUAL, reported by the key's owner, and people are told the way you choose with reportTo: by default the monitor's escalation policy, else whoever is on call, else the whole team. The monitor's alert connections that send “down” alerts are notified too.titledescriptionmonitorIdcategoryUNKNOWN.isPublicfalse.reportToauto (default) as above; team for everyone; or one of group:ID, policy:ID, schedule:ID, user:ID, channel:ID — a team group, escalation policy, on-call schedule, member or alert connection in this workspace.notifications{ "email": true, "push": true, "criticalAlert": false }. criticalAlert pages through phones' silent mode and implies push. Without it, the monitor's own setting is used.curl -X POST "https://api.zharp.io/api/v1/incidents" \
-H "Authorization: Bearer $ZHARP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "Checkout failing for EU users",
"description": "Card payments time out since 09:40 UTC.",
"monitorId": 77,
"reportTo": "policy:4"
}'{
"message": "Incident reported successfully",
"data": {
"id": 481,
"workspaceId": 3,
"monitorId": 77,
"title": "api.acme.io is down",
"description": null,
"status": "ONGOING",
"mode": "MANUAL",
"isAcknowledged": true,
"rootCause": "HTTP 503 Service Unavailable",
"category": "HTTP",
"isPublic": false,
"reporterEmail": null,
"startedAt": "2026-10-26T08:14:02.000Z",
"acknowledgedAt": "2026-10-26T08:16:40.000Z",
"resolvedAt": null,
"reportedById": null,
"acknowledgedById": 12,
"resolvedById": null,
"createdAt": "2026-10-26T08:14:02.000Z",
"updatedAt": "2026-10-26T08:16:40.000Z"
}
}400A field fails validation, or thereportTotarget isn't in this workspace.403The key's scope is belowwrite, or its owner is Read-only.
/incidents/:id/acknowledgeINVESTIGATING, the key's owner is recorded as who acknowledged it, and connections that send “acknowledged” alerts are told.idcurl -X POST "https://api.zharp.io/api/v1/incidents/481/acknowledge" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "…",
"data": { "id": 481, "status": "INVESTIGATING", "isAcknowledged": true, "acknowledgedAt": "…", "acknowledgedById": 12, … }
}404No such incident in this workspace.
/incidents/:id/resolveA monitor resolves its own incidents when its checks pass again — call this for incidents people reported, or to close one by hand.
idcurl -X POST "https://api.zharp.io/api/v1/incidents/481/resolve" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "…",
"data": { "id": 481, "status": "RESOLVED", "resolvedAt": "…", "resolvedById": 12, … }
}404No such incident in this workspace.
/incidents/:id/reopenONGOING. Only within 24 hours of it being resolved. Nobody is notified.idcurl -X POST "https://api.zharp.io/api/v1/incidents/481/reopen" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "…",
"data": { "id": 481, "status": "ONGOING", "isAcknowledged": false, "resolvedAt": null, … }
}404No such incident in this workspace.403It was resolved more than 24 hours ago — report a new incident instead.
/incidents/:id/commentsidcontentattachmentscurl -X POST "https://api.zharp.io/api/v1/incidents/481/comments" \
-H "Authorization: Bearer $ZHARP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"content": "Rolled back to v1.4.1 — watching error rates."
}'{
"message": "…",
"data": {
"id": 9003,
"incidentId": 481,
"userId": 12,
"type": "COMMENT",
"message": "Rolled back to v1.4.1 — watching error rates.",
"status": "INVESTIGATING",
"createdAt": "2026-10-26T08:31:05.000Z",
"user": { "name": "Ada", … },
"attachments": []
}
}400contentis missing or empty.404No such incident in this workspace.
/incidents/:id/attachmentsThen post it: { "content": "Error rate during the outage", "attachments": [<that data>] }.
idfilecurl -X POST "https://api.zharp.io/api/v1/incidents/481/attachments" -H "Authorization: Bearer $ZHARP_API_KEY" -F "file=@error-rate.png"
{
"message": "Attachment uploaded successfully",
"data": {
"public_id": "incidents/481/xyz",
"secure_url": "https://res.cloudinary.com/…/incidents/481/xyz.png",
"url": "https://res.cloudinary.com/…/incidents/481/xyz.png",
"format": "png",
"bytes": 48211,
"resource_type": "image",
"original_filename": "error-rate"
}
}400No file, or not one of those types.413Over 10 MB.404No such incident in this workspace.
/incidents/:id/logslogServiceNames, from a few minutes before it started until a few minutes after it ended (or now). Up to 500 lines, newest first.An incident whose monitor names no log services answers with an empty list.
idbeforeaftercurl "https://api.zharp.io/api/v1/incidents/481/logs?before=10" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "Logs retrieved successfully",
"data": [{ "serviceName": "api", "environment": "production", "level": "error", "message": "upstream timed out", "timestamp": "…", "metadata": { … } }],
"meta": { "before": 10, "after": 5 }
}404No such incident in this workspace.
/incidents/:id/escalateidtargetsteam, group:ID, policy:ID, schedule:ID, user:ID, channel:ID — each in this workspace.channelsemail, push, critical (a critical push that sounds through silent mode). E-mail or push at least.curl -X POST "https://api.zharp.io/api/v1/incidents/481/escalate" \
-H "Authorization: Bearer $ZHARP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"targets": [
"schedule:2",
"user:12"
],
"channels": [
"push",
"email"
]
}'{
"message": "Incident escalated successfully",
"data": { "reached": ["whoever is on call on Primary", "Ada"] }
}400No targets, no way to reach them, or a target that isn't in this workspace.404No such incident in this workspace.
/public/incidents/report/:tokentokentitledescriptionemailmonitorIdcurl -X POST "https://api.zharp.io/api/v1/public/incidents/report/YOUR_REPORT_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "title": "Can't log in", "email": "customer@example.com" }'{ "message": "Incident reported successfully", "data": { "id": 483, "status": "ONGOING", "mode": "MANUAL", … } }404The link is wrong or has been replaced.400A field fails validation —titleis missing, say.429More than 5 reports an hour from one address, or 30 an hour into one workspace.
Maintenance windows
While a window is on, its monitors are under maintenance: their alerts and escalations stop, and status pages showing them say so. A window happens once, or repeats daily or weekly.
/maintenanceactive— an occurrence is running right now.nextOccurrence— the current or next occurrence;nullonce a one-off window has passed.repeatConfig.daysare weekdays, Sunday = 0, in the window'stimezone.
curl "https://api.zharp.io/api/v1/maintenance" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "…",
"data": [
{
"id": 14,
"workspaceId": 3,
"name": "Database upgrade",
"description": null,
"startTime": "2026-11-01T02:00:00.000Z",
"endTime": "2026-11-01T04:00:00.000Z",
"timezone": "Europe/Paris",
"scheduleType": "recurring",
"repeatConfig": { "frequency": "weekly", "days": [0], "time": "03:00", "durationMinutes": 120 },
"notificationConfig": null,
"createdAt": "2026-10-20T10:00:00.000Z",
"updatedAt": "2026-10-20T10:00:00.000Z",
"_count": { "monitors": 3 },
"recurring": true,
"active": false,
"nextOccurrence": { "startTime": "2026-11-01T02:00:00.000Z", "endTime": "2026-11-01T04:00:00.000Z" }
}
]
}/maintenance/:ididcurl "https://api.zharp.io/api/v1/maintenance/14" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{
"message": "…",
"data": {
"id": 14,
"name": "Database upgrade",
…,
"monitors": [{ "maintenanceWindowId": 14, "monitorId": 77, "monitor": { "id": 77, "name": "API", "type": "HTTP", … } }],
"recurring": true,
"active": false,
"nextOccurrence": { "startTime": "…", "endTime": "…" }
}
}404No such window in this workspace.
/maintenancenamedescriptionstartTimeendTimetimezoneEurope/Paris; repeats keep this zone's local time. Default UTC.repeatConfignull for a one-off. { "frequency": "daily" } repeats every day at the same time (up to 24 hours long); { "frequency": "weekly" } repeats on the start's weekday (up to 7 days long). An object without a frequency is refused.monitorIdscurl -X POST "https://api.zharp.io/api/v1/maintenance" \
-H "Authorization: Bearer $ZHARP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Database upgrade",
"startTime": "2026-11-01T02:00:00Z",
"endTime": "2026-11-01T04:00:00Z",
"timezone": "Europe/Paris",
"repeatConfig": {
"frequency": "weekly"
},
"monitorIds": [
77,
78,
91
]
}'{
"message": "…",
"data": {
"id": 15,
"name": "Database upgrade",
"scheduleType": "recurring",
"repeatConfig": { "frequency": "weekly", "days": [0], "time": "03:00", "durationMinutes": 120 },
"monitors": [ … ],
"recurring": true,
"active": false,
"nextOccurrence": { "startTime": "2026-11-01T02:00:00.000Z", "endTime": "2026-11-01T04:00:00.000Z" },
…
}
}400A field fails validation, an unknown field, an unknown time zone, an end before the start, or a repeat longer than its period.404A monitor id isn't in this workspace.
/maintenance/:idmonitorIds replaces the whole list; "repeatConfig": null stops it repeating. Subscribers aren't e-mailed again.idcurl -X PUT "https://api.zharp.io/api/v1/maintenance/14" \
-H "Authorization: Bearer $ZHARP_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"endTime": "2026-11-01T05:00:00Z"
}'{ "message": "…", "data": { "id": 14, "endTime": "2026-11-01T05:00:00.000Z", … } }400As for creating one.404No such window, or a monitor id that isn't in this workspace.409The window belongs to one monitor — change it with that monitor'smaintenanceWindowson PUT /monitors/:id.
/maintenance/:ididcurl -X DELETE "https://api.zharp.io/api/v1/maintenance/14" \ -H "Authorization: Bearer $ZHARP_API_KEY"
{ "message": "…", "data": null }404No such window in this workspace.409The window belongs to one monitor — remove it from that monitor instead.