HeimPulse API

Incidents

The real request/response field shape for POST /v1/incidents and its /updates route.

View as Markdown

/v1/incidents is a thin proxy in front of the same engine that powers the dashboard’s incidents tab - so its request/response bodies are plain JSON objects, not one of the reference’s typed schemas (see the API reference for why those two endpoints show up there as a bare object). This page is the field-by-field shape.

Create an incident

POST /v1/incidents
{
  "title": "Elevated error rates",
  "service_ids": ["5b1e...", "8a2f..."],
  "message": "We're seeing elevated error rates on checkout and are investigating.",
  "severity": "partial_outage"
}
Field Type Required Notes
title string yes Non-empty.
service_ids array of uuid yes Non-empty; every id must belong to your org.
message string yes The incident’s first update.
severity string yes One of degraded_performance, partial_outage, major_outage.

kind is not a field you send - every incident created through /v1/incidents is forced to kind incident server-side, even if you send something else. Maintenance windows aren’t part of this API surface.

A 201 response is the full incident, including its initial update:

{
  "id": "c4e1...",
  "kind": "incident",
  "title": "Elevated error rates",
  "status": "investigating",
  "severity": "partial_outage",
  "created_by": null,
  "created_at": "2026-09-05T12:00:00Z",
  "resolved_at": null,
  "service_ids": ["5b1e...", "8a2f..."],
  "display_id": "INC-42",
  "updated_at": "2026-09-05T12:00:00Z",
  "auto_managed": false,
  "updates": [
    { "id": "...", "body": "We're seeing elevated error rates...", "status_at_update": "investigating", "created_at": "..." }
  ]
}

created_by is always null for an incident created through the API - there’s no human session behind an API key, so it’s attributed to the system, the same way an auto-detected incident is.

Post an update (including resolving)

POST /v1/incidents/{id}/updates
{ "body": "Root cause found, deploying a fix.", "status": "identified" }
Field Type Required Notes
body string yes Non-empty.
status string yes One of investigating, identified, monitoring, resolved.
severity string no Change the severity alongside this update; same allowed values as create.

There’s no separate “resolve” endpoint. Resolving an incident is posting an update with "status": "resolved" - that’s the one status this API treats as terminal (it sets resolved_at and stops counting the incident as active).

{ "body": "Fixed and confirmed stable.", "status": "resolved" }

Listing and reading

GET /v1/incidents?section=active
GET /v1/incidents/{id}

section is required on the list endpoint: active or resolved. Optional filters: q (searches title and display id, e.g. INC-42), severity, one or more service_id params, and page/limit for pagination.