Incident and maintenance lifecycle
States, transitions, and the events fired on each.
Incidents and maintenances share one lifecycle. State is derived from timestamp fields, identically whether the transition came from the API, the console, or a scheduled job. Transitions are idempotent.
States
| State | Trigger |
|---|---|
draft | Row exists but published_at IS NULL. Invisible to the public. |
published | published_at set. Renders on the public page. |
resolved | resolved_at set. Final lifecycle for an incident. |
scheduled | Maintenance with scheduled_start_at set, actual_start_at NULL. |
in_progress | Maintenance with actual_start_at set, actual_end_at NULL. |
completed | Maintenance with actual_end_at set. |
canceled | Either type with canceled_at set. |
deleted | Soft-delete via deleted_at. Permanent; not displayed anywhere. |
Transitions
draft
│ POST /publish
▼
published ──── POST /resolve ──▶ resolved
│
│ DELETE
▼
deleted
(maintenance only)
scheduled ── cron @ scheduled_start_at ──▶ in_progress
│ cron @ scheduled_end_at
▼
completed
any state ── POST /cancel ──▶ canceled
Webhook events
Each transition fires a webhook event. See Webhook payload reference for exact body shapes.
| Event | Fires when |
|---|---|
incident.created | Row inserted (regardless of draft / publish). |
incident.published | published_at set. |
incident.updated | Title, severity, or affected services patched. |
incident.message_added | Message appended to timeline. |
incident.resolved | resolved_at set. |
incident.deleted | deleted_at set. |
maintenance.scheduled | Row inserted with scheduled_start_at. |
maintenance.starting_soon | Cron fires within 1h of scheduled_start_at. Once per row. |
maintenance.started | actual_start_at set (manual or cron). |
maintenance.completed | actual_end_at set. |
maintenance.canceled | canceled_at set. |
Auto-message side effects
Some lifecycle transitions append a system message to the timeline:
maintenance.started(cron or API) appends an Information message: "Maintenance started."maintenance.completed(cron or API) appends a Resolved message: "Maintenance completed."maintenance.canceled(API) appends an Information message: "Maintenance canceled."
These are visible on the public page exactly like operator-authored messages. They exist so the timeline reflects every state change without requiring the operator to remember.
Was this page helpful?