> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scaling.cloud/llms.txt
> Use this file to discover all available pages before exploring further.

# Incidents

> Understand severity levels, the status lifecycle, and how to track incidents from first alert to resolution.

An incident in scaling.cloud represents a service disruption or degradation that requires your team's attention. Each incident has a title, a severity level, and a status that moves forward through a fixed lifecycle — from the moment it's opened until it's fully resolved.

Incidents can be assigned directly to a user, or handed to the current on-call responder for a schedule — which also attaches the matching escalation policy. Every transition is recorded in a permanent audit trail.

## Severity levels

Severity indicates the impact of an incident. Set it when you create the incident and update it if conditions change.

| Severity   | When to use                                                                          |
| ---------- | ------------------------------------------------------------------------------------ |
| `critical` | Complete outage or data loss affecting all users. Requires immediate action.         |
| `high`     | Major feature broken or significant performance degradation. Urgent response needed. |
| `medium`   | Partial or intermittent impact. A workaround may exist.                              |
| `low`      | Minor issue with minimal user impact. Can be addressed in normal working hours.      |

<Note>
  Severity is the single dial scaling.cloud uses to rank incident impact — there is no
  separate "priority" field. If you ingest [CloudWatch
  alarms](/guides/ingest-cloudwatch-alarms-cdk#set-severity-from-the-alarm-description),
  the `[P1]`–`[P4]` markers in an alarm description are just shorthand for these
  severity levels (`[P1]` → `critical`, through `[P4]` → `low`), not a distinct
  priority scale.
</Note>

## Status lifecycle

Every incident starts at `investigating` and moves forward through four statuses. Transitions are **one-way** — you cannot skip a step or go back to a previous status.

```
investigating → identified → monitoring → resolved
```

| Status          | Meaning                                                           |
| --------------- | ----------------------------------------------------------------- |
| `investigating` | Your team is looking into the cause. Impact is not yet confirmed. |
| `identified`    | The root cause is known. A fix is in progress.                    |
| `monitoring`    | A fix has been applied. You are watching to confirm it holds.     |
| `resolved`      | The incident is over. No further action is required.              |

<Warning>
  Status transitions are enforced. You cannot move an incident from `monitoring` back to `identified`, and you cannot skip directly from `investigating` to `resolved`. Progress through each step in order.

  **`resolved` is terminal.** Once an incident is resolved, no further updates can be posted on it. The only mutation that survives the terminal status is [redaction](#redacting-a-published-mistake) of an existing update. If you need a post-incident write-up, post it as a final `public` update **before** transitioning to `resolved`.
</Warning>

## Incident Updates

An **Incident Update** is the single unit of timeline activity on an incident. Every update carries:

| Field          | Meaning                                                                                             |
| -------------- | --------------------------------------------------------------------------------------------------- |
| `body`         | Free-text message (up to 10,000 characters). Optional for internal updates, required for public.    |
| `statusChange` | Optional lifecycle transition. When set, the incident's `status` advances in the same write.        |
| `visibility`   | Either `internal` (staff-only) or `public` (rendered on your status page). **Default is internal.** |
| `postedBy`     | The user (or API key) who posted the update.                                                        |
| `postedAt`     | Server-set ISO timestamp.                                                                           |

At least one of `body` or `statusChange` must be present. A `public` update **always** requires a non-empty body.

This single concept replaces what used to be two separate things: free-form internal notes, and the implicit "row written every time you transitioned status." Today, both flow through the same shape — the difference is whether `body`, `statusChange`, or both are set.

### Visibility — internal vs public

| Visibility | Where it renders                                                                                                                                |
| ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `internal` | Staff incident timeline only. If `statusChange` is set, the transition still appears as a bare row on the public page, but the body never does. |
| `public`   | Staff timeline **and** the public status page — the body is the message customers read.                                                         |

Every input surface (web, Slack, MCP, public API) defaults to `internal`. Publishing is always an explicit, deliberate action — you cannot publish by accident.

### Publishing requires a covering Status Page

Posting a `public` update is rejected with `NO_PUBLIC_SURFACE` (`400`) unless your org has at least one **published Status Page** whose selected components overlap with the incident's affected components. This is enforced server-side before any write.

This prevents the silent-failure case where you publish into the void — i.e., write a public message that no surface actually renders. Configure your Status Page to include the affected components before publishing. See [Status pages](/concepts/status-pages) for component selection.

### Redacting a published mistake

Updates are **append-only**. To correct or remove a previous statement, redact it and post a new one — the system never silently edits a customer-visible record.

| Caller                | Can redact when                     |
| --------------------- | ----------------------------------- |
| The original author   | Within **5 minutes** of `postedAt`. |
| An organization admin | At any time.                        |

Redaction wipes the `body`, sets `redactedAt` and `redactedBy`, and **preserves** any `statusChange` the update carried — the system does not lie about lifecycle state. On the public status page, the slot remains visible at its original timestamp, rendered as **"This update has been removed."** The original wording is gone, but the fact that something existed and was pulled back is visible.

Redaction is permitted even on resolved incidents — it is the only mutation that survives the terminal status.

## Origin — human vs system

Not every action on an incident is taken by a person. An incident can be auto-opened from an ingested alert, an update can be an auto-resolution posted when the upstream alert clears, and a provisional status page can be promoted automatically. To keep the timeline honest about who did what, both incidents and Incident Updates carry an **origin**:

| Origin   | Meaning                                                                                       |
| -------- | --------------------------------------------------------------------------------------------- |
| `human`  | A person took the action — manual incident creation, or a responder posting an update.        |
| `system` | The platform took the action — alert-driven incident creation, auto-resolution, or promotion. |

`origin` is the truth-bearing field for attribution. A `createdBy` / `postedBy` user is still recorded on every incident and update for audit and plumbing, but a `system` origin means that user is the integration's owner, not someone who personally acted.

System-origin actions render **without** human attribution:

* On the internal timeline, a system-origin update is attributed to **Automated** instead of a member's name.
* On a [public status page](/concepts/status-pages#what-appears-on-the-timeline), a system-origin entry carries an **Automated** badge — so customers see that an auto-resolution was the platform, not a named engineer "resolving" what an alarm resolved.

`origin` (`human` or `system`) is exposed on incident and Incident Update payloads in the API — see [Get Incident](/api/incidents/get) and [List Incident Updates](/api/incidents/updates-list). It also powers the [longest silence and time to mobilize metrics](/concepts/insights#automated-actions-and-origin) in Insights.

## Status history and audit trail

The incident detail view shows the full ordered timeline of updates: internal notes, public messages, and status transitions interleaved at their actual post times. Each entry records who posted it, when, and (for redacted updates) who redacted it and when. System-origin entries show **Automated** in place of a member's name — see [Origin](#origin-human-vs-system).

The legacy `statusHistory` field on the [Get Incident](/api/incidents/get) response remains populated for backwards compatibility — it surfaces just the status transitions. For the full timeline (notes + transitions + public updates), call [List Incident Updates](/api/incidents/updates-list).

## Creating an incident

When you create an incident, the following fields are available:

| Field            | Required | Notes                                                                 |
| ---------------- | -------- | --------------------------------------------------------------------- |
| `title`          | Yes      | 1–100 characters.                                                     |
| `description`    | No       | Additional context. Up to 10,000 characters.                          |
| `severity`       | Yes      | `critical`, `high`, `medium`, or `low`.                               |
| `leadId`         | Either   | User ID to assign directly as the incident lead.                      |
| `leadScheduleId` | Either   | On-call schedule whose current responder becomes the lead. See below. |
| `componentIds`   | No       | UUIDs of affected components, up to 50.                               |

<Note>
  At least one of `leadId` or `leadScheduleId` is required so the paging path
  always has a target.
</Note>

## Assigning an on-call lead

Pass `leadScheduleId` at creation time to hand the incident to the team that is currently on-call. The server resolves the lead and escalation in one step:

* It looks up the **current on-call responder** for the schedule (including active overrides) and sets them as the incident lead.
* It searches your escalation policies for one whose layers target that schedule, and attaches the match.

If you also supply `leadId`, that user wins as the incident lead — the schedule is still used to find a matching escalation policy. If no one is currently on-call and no `leadId` was supplied, the incident is still created without a lead; you can assign one later from the incident detail page.

<Tip>
  For `critical` and `high` severity incidents, pass `leadScheduleId` so the
  right responders are paged automatically through the matching escalation
  policy. See [Escalation Policies](/concepts/escalation-policies) for how
  policies and schedules connect.
</Tip>
