Uptimeify Docs
Incident management

Get Incident

Returns the full detail of a single Incident Management incident: the incident row plus its alerts, timeline events, and role assignments.

GET /api/im/incidents/:id

Returns the full detail of a single incident: the incident row plus its alerts (a safe, redacted view, see below), timeline events in chronological order, and role assignments.

Authentication

Any IM-eligible role (admin, editor, responder) or an organization-wide API token, see Authentication. Incident Management must be enabled for the organization.

Example (cURL)

curl -X GET "$BASE_URL/api/im/incidents/42" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Accept: application/json"

Response

{
  "id": 42,
  "organizationId": 1,
  "teamId": 3,
  "title": "Database connection pool exhausted",
  "customerId": null,
  "primarySourceId": 7,
  "severity": "sev1",
  "severityManual": false,
  "status": "triggered",
  "mergedIntoId": null,
  "escalationPolicyId": null,
  "currentTier": 1,
  "escalationEpoch": 0,
  "escalationCycle": 0,
  "acknowledgedBy": null,
  "acknowledgedAt": null,
  "snoozedUntil": null,
  "autoResolve": true,
  "resolvedBy": null,
  "resolveNote": null,
  "statuspageUpdate": null,
  "createdBy": null,
  "sourceKind": "alert",
  "isTest": false,
  "category": null,
  "isNearMiss": false,
  "triggeredAt": "2026-07-17T09:12:00.000Z",
  "resolvedAt": null,
  "serviceId": null,
  "statuspageRuleApplies": false,
  "customerName": null,
  "customerPublicId": null,
  "monitoringIncidentPublicId": null,
  "hasReportCase": false,
  "reportCasePublicId": null,
  "postmortemStatus": "none",
  "needsPostmortem": false,
  "canManagePostmortem": false,
  "mergeSuggestions": [
    {
      "incidentId": 41,
      "title": "db-primary-01 unreachable",
      "reason": "host",
      "suggestedAt": "2026-07-17T09:12:01.000Z"
    }
  ],
  "alerts": [
    {
      "id": 101,
      "organizationId": 1,
      "sourceId": 7,
      "dedupKey": "db-primary-01:pool-exhausted",
      "status": "open",
      "suppressedReason": null,
      "title": "Database connection pool exhausted",
      "severity": "sev1",
      "host": "db-primary-01",
      "mappedFields": {},
      "duplicateCount": 0,
      "firstSeenAt": "2026-07-17T09:12:00.000Z",
      "resolvedAt": null,
      "incidentId": 42
    }
  ],
  "events": [
    {
      "id": 501,
      "incidentId": 42,
      "at": "2026-07-17T09:12:00.000Z",
      "kind": "alert_received",
      "actorUserId": null,
      "actorName": null,
      "payload": {}
    },
    {
      "id": 502,
      "incidentId": 42,
      "at": "2026-07-17T09:15:00.000Z",
      "kind": "acknowledged",
      "actorUserId": "u_abc123",
      "actorName": "Jane Doe",
      "payload": {}
    }
  ],
  "assignments": [
    {
      "id": 12,
      "userId": "u_abc123",
      "userName": "Jane Doe",
      "role": "commander",
      "createdAt": "2026-07-17T09:15:00.000Z"
    }
  ],
  "publicUpdates": [
    {
      "id": 17,
      "publicId": "6f1d2c3b-4a5e-4f60-8a7b-9c0d1e2f3a4b",
      "status": "investigating",
      "body": "We are investigating slow logins.",
      "createdAt": "2026-07-17T09:20:00.000Z",
      "createdByUserId": "u_abc123"
    }
  ]
}

publicUpdates is the incident's public timeline, oldest first and append-only: one entry per text set through Update Status Page Text, each with status (investigating, identified, monitoring, resolved), body, createdAt and createdByUserId (null once the user is deleted). Public status pages show it without the user.

statuspageRuleApplies is true when one of the team's status page rules would flip a status page for this incident (a rule for its team whose minimum severity it meets). statuspageUpdate is the curated text shown on that page (set it with Update Status Page Text).

customerName and customerPublicId name the customer in customerId; both are null when the incident has no customer.

monitoringIncidentPublicId is the public id of the Uptimeify monitoring incident this incident was bridged from (source type uptimeify_monitoring), for a link to /dashboard/system/incidents/<publicId>. It is null for every other source.

mergeSuggestions lists open incidents from OTHER alert sources of your organization that are probably the same incident: triggered within 15 minutes of this one and either assigned the same service (reason: "service", preferred) or with an open alert on the same host (reason: "host"; hosts are compared without scheme, port, path, trailing dot or case, so db-01:9100 and https://DB-01/ match). The suggestion is made once, when this incident is created, at most three of them, and nothing is ever merged automatically: merge with Merge Incidents (this incident into incidentId) or drop it with Dismiss Merge Suggestion. The list is empty once this incident is resolved or merged, and a suggestion whose target is closed is left out. In the timeline the suggestion is the event merge_suggested ({ targetIncidentId, targetTitle, reason, host? }), a dismissal merge_suggestion_dismissed ({ targetIncidentId }). No notification is sent for a suggestion.

hasReportCase is true when the incident is linked to a NIS-2 report case. Its content is only visible to admins and reporting officers.

reportCasePublicId is the publicId of that report case, for a link to it. Only organization admins and reporting officers signed in with a session get it; for everyone else, and without a linked case, it is null.

category is the NIS-2 incident category (availability, security, other, or null while not classified) and isNearMiss marks a near miss; set both with Classify Incident. postmortemStatus is none, draft or completed (see Postmortems). needsPostmortem is true when NIS-2 is on, the incident needs a postmortem and none is completed yet. canManagePostmortem is true for organization admins and reporting officers signed in with a session.

events[].actorName is the display name of the user in events[].actorUserId, resolved server-side so you do not have to look it up. It is null for a system event, meaning there was no actor at all (an alert arriving, an escalation tier firing). It is also null when the actor cannot be named within the incident's own organization, for example a platform-level operator or a user account that no longer exists. Render an anonymous actor in that case: the user id in actorUserId is an internal identifier, not a label. A person without a display name is labelled with their e-mail address for an organization admin only; any other role gets null there as well.

The two escalation events carry payload.toTargetName, the name of what the tier pages at the moment of escalation: the tier's first schedule, or the team's name for a tier without schedules (null when neither exists). escalated (a manual Escalate Now) has { fromTier, toTier, toTargetName }, escalated_tier (a tier firing on its own) has { tier, repeat, userIds, toTargetName }. Events recorded before the field existed lack it.

alerts[].rawPayload is never returned by this endpoint: the raw webhook/API payload can carry API keys or other secrets its source's operator put in it. It is also nulled server-side 90 days after ingest by a retention job. alerts[].mappedFields is the already-normalized, safe view of the same alert and survives retention. It carries the alert's url (a link back to its origin: the monitor in the dashboard, the Zabbix event, the Grafana panel), when the source supplied one, and every mapped custom field as a flat string key next to it (for the monitoring bridge e.g. monitor_type, region, failed_locations, last_success_at). The reserved key _mapping holds display metadata, not a field.

Retention, in full: alert payloads (rawPayload) are nulled 90 days after ingest; resolved alerts are deleted 90 days after ingest; outbound-delivery (integration forwarding) records are deleted 90 days after they were sent. The incident itself and its timeline events (events) are kept in full for 12 months after the incident triggered; after that only a daily aggregate survives (incident counts plus acknowledge and resolve times, per team and severity), for 24 months total. Per-source daily aggregates (alert/dedup/incident counts, as shown on a source's Analytics tab) are retained indefinitely. Deleting the underlying alert rows does not erase that history.

Common errors

  • 401 Unauthorized when not authenticated
  • 403 Forbidden (customerScopedTokenForbidden) when using a customer-scoped token
  • 403 Forbidden (imAccessDenied) when the session user has no IM-eligible role
  • 403 Forbidden (imNotEnabled) when Incident Management is not enabled for the organization
  • 400 Bad Request (invalidRequestBody) when :id is not a positive integer
  • 404 Not Found (imIncidentNotFound) when the incident does not exist, or belongs to another organization

On this page