---
title: Incidents
description: The real request/response field shape for POST /v1/incidents and its /updates route.
order: 5
---

`/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](/reference.html) 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
```

```json
{
  "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. To schedule planned maintenance instead,
see the [Maintenance Windows](/guides/maintenance-windows) guide - it's a separate endpoint,
`/v1/maintenance-windows`, not a variant of this one.

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

```json
{
  "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
```

```json
{ "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).

```json
{ "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.
