Incidents
Runframe V1 incident API. Create, update, acknowledge, resolve, page responders, and escalate incidents.
Manage the full incident lifecycle through the V1 API.
status is always the canonical machine value for the incident status, and it is the same value accepted by filters and POST /api/v1/incidents/:id/status.
Identifiers
Use the incident number in external integrations.
| Format | Example | Notes |
|---|---|---|
| Incident number | INC-2026-044 | Human-readable incident identifier scoped to the organization |
Use the incident number in any :id path parameter shown on this page.
Create Incident
POST /api/v1/incidentsRequired fields: title, service_ids
{
"title": "Database connection pool exhaustion",
"description": "API returning 500s due to connection limit",
"severity": "SEV1",
"service_ids": ["svc_K7M4Q9TZ2H"]
}| Field | Type | Required | Description |
|---|---|---|---|
title | string | Yes | 1-200 characters |
description | string | No | Detailed description |
severity | string | No | SEV0-SEV4, defaults to your organization's default severity setting (SEV2 by default) |
service_ids | string[] | Yes | Public service keys (e.g. svc_K7M4Q9TZ2H). Use List Services to discover keys. |
Assignment happens automatically based on on-call schedules after creation.
Idempotency: Include Idempotency-Key header for replay-safe creates. See Authentication.
Response: Returns 201 Created with the incident snapshot at creation time in the standard envelope.
Post-create automation such as assignment and notifications runs asynchronously. As a result, assigned_to and team in the initial 201 response may not reflect the final post-create state. If your integration needs the latest assignment state immediately, call GET /api/v1/incidents/:id after create.
SLA Configuration Requirement
Incident creation requires valid SLA settings for the requested severity.
Each organization starts with default SLA settings, so no setup is required before using the API. To change them, go to Settings -> Severities & SLA.
Each severity should have both an acknowledge deadline and a closure deadline.
If SLA settings for the requested severity are invalid, incident creation fails.
Update these settings in Settings -> Severities & SLA.
List Incidents
GET /api/v1/incidents| Parameter | Type | Description |
|---|---|---|
limit | integer | Results per page (max 100, default 20) |
offset | integer | Pagination offset (default 0) |
status | string[] | Filter by canonical status value (repeatable) |
severity | string[] | Filter by severity (repeatable) |
assigned_to | string (email) | Filter by current assignee email |
resolved_by | string (email) | Filter by resolver email |
team_name | string | Filter by team name (case-insensitive) |
created_after | string (ISO 8601) | Only incidents created at or after this timestamp |
created_before | string (ISO 8601) | Only incidents created at or before this timestamp |
resolved_after | string (ISO 8601) | Only incidents resolved at or after this timestamp |
resolved_before | string (ISO 8601) | Only incidents resolved at or before this timestamp |
By default, results include incidents that are still in progress and do not include incidents that are already resolved or closed. To include resolved or closed incidents, pass explicit status filters such as resolved or closed.
Use assignee or resolver email addresses for assigned_to and resolved_by.
Use the team name for team_name. Matching is case-insensitive.
Response:
{
"success": true,
"data": {
"items": [
{
"incident_number": "INC-2026-044",
"title": "...",
"description": "...",
"status": "investigating",
"severity": "SEV1",
"assigned_to": { "name": "Jane", "email": "jane@example.com" },
"team": { "name": "Platform" },
"created_at": "2026-04-18T10:30:00Z",
"acknowledged_at": null,
"resolved_at": null
}
],
"total": 42,
"has_more": true,
"next_offset": 20
}
}Get Incident
GET /api/v1/incidents/:idReturns full incident details with timeline.
Response includes a timeline array and timeline_meta:
{
"timeline": [
{
"event_type": "CREATED",
"title": "Incident created",
"description": null,
"user": "Jane",
"created_at": "2026-04-18T10:30:00Z"
}
],
"timeline_meta": {
"limit": 200,
"has_more": false
}
}Timeline entries are capped at 200 per response. If timeline_meta.has_more is true, older events exist but are not included in the current response.
Update Incident
PATCH /api/v1/incidents/:idField updates only. For status changes, use Change Status.
{
"title": "Updated title",
"description": "Updated description",
"severity": "SEV2",
"assigned_to": "jane@example.com"
}| Field | Type | Description |
|---|---|---|
title | string | New title |
description | string | New description |
severity | string | SEV0-SEV4 |
assigned_to | string (email) | Reassign to an engineer by email address |
All fields are optional. Only included fields are updated.
Change Status
POST /api/v1/incidents/:id/statusCanonical endpoint for all status transitions. Resolving, closing, investigating, and monitoring all flow through here.
{
"status": "resolved",
"comment": "Fixed by rolling back deploy abc123"
}| Field | Type | Required | Description |
|---|---|---|---|
status | string | Yes | Target canonical status name returned by incident read endpoints |
comment | string | No | Reason for change (max 500 chars) |
Valid transitions are enforced server-side. Some transitions require a comment. Use the status value returned by incident read endpoints when sending a status transition.
Acknowledge Incident
POST /api/v1/incidents/:id/acknowledgeA dedicated action endpoint for acknowledging an incident. It records the acknowledgement, assigns the incident to the acknowledging user, and updates acknowledge-SLA state. This is intentionally separate from the generic /status transition path.
No request body required. If the incident is already acknowledged, the request returns an error and does not update the acknowledgement timestamp.
Response:
{
"success": true,
"data": {
"incident_number": "INC-2026-044",
"acknowledged": true,
"acknowledged_at": "2026-04-18T10:35:00Z"
}
}Page Someone
POST /api/v1/incidents/:id/pageSend a real notification to a specific person. Urgency is derived from incident severity automatically.
{
"email": "jane@example.com",
"channels": ["slack", "email"],
"message": "API is down, need your help"
}| Field | Type | Required | Description |
|---|---|---|---|
email | string | Yes | Person to page |
channels | string[] | Yes | One or more delivery channels. Supported values: slack, email |
message | string | No | Custom message (max 500 chars) |
Response includes one entry per requested channel:
{
"success": true,
"data": {
"incident_number": "INC-2026-044",
"sent": true,
"channels": ["slack"],
"deliveries": [
{ "channel": "slack", "sent": true },
{ "channel": "email", "sent": false, "error_code": "EXTERNAL_API_ERROR", "message": "SMTP timeout" }
]
}
}Status codes:
| Code | Meaning |
|---|---|
200 | At least one requested channel sent successfully. Response includes per-channel delivery results. |
409 | Delivery failed for all requested channels because the user does not have the required contact details. |
502 | Delivery failed for all requested channels because the notification provider could not deliver the message. |
Add Timeline Event
POST /api/v1/incidents/:id/eventsAdd a timeline entry to an incident.
{
"comment": "Identified root cause: connection pool leak in auth service"
}Escalate Incident
POST /api/v1/incidents/:id/escalateEscalate to the next level in the escalation policy. Sends real notifications to responders. No request body required.
Response:
{
"success": true,
"data": {
"incident_number": "INC-2026-044",
"escalated": true,
"notified_emails": ["jane@example.com", "casey@example.com"],
"current_level": 2,
"next_level": 3
}
}