Runframe
API Reference

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.

FormatExampleNotes
Incident numberINC-2026-044Human-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/incidents

Required fields: title, service_ids

{
  "title": "Database connection pool exhaustion",
  "description": "API returning 500s due to connection limit",
  "severity": "SEV1",
  "service_ids": ["svc_K7M4Q9TZ2H"]
}
FieldTypeRequiredDescription
titlestringYes1-200 characters
descriptionstringNoDetailed description
severitystringNoSEV0-SEV4, defaults to your organization's default severity setting (SEV2 by default)
service_idsstring[]YesPublic 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
ParameterTypeDescription
limitintegerResults per page (max 100, default 20)
offsetintegerPagination offset (default 0)
statusstring[]Filter by canonical status value (repeatable)
severitystring[]Filter by severity (repeatable)
assigned_tostring (email)Filter by current assignee email
resolved_bystring (email)Filter by resolver email
team_namestringFilter by team name (case-insensitive)
created_afterstring (ISO 8601)Only incidents created at or after this timestamp
created_beforestring (ISO 8601)Only incidents created at or before this timestamp
resolved_afterstring (ISO 8601)Only incidents resolved at or after this timestamp
resolved_beforestring (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/:id

Returns 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/:id

Field updates only. For status changes, use Change Status.

{
  "title": "Updated title",
  "description": "Updated description",
  "severity": "SEV2",
  "assigned_to": "jane@example.com"
}
FieldTypeDescription
titlestringNew title
descriptionstringNew description
severitystringSEV0-SEV4
assigned_tostring (email)Reassign to an engineer by email address

All fields are optional. Only included fields are updated.


Change Status

POST /api/v1/incidents/:id/status

Canonical endpoint for all status transitions. Resolving, closing, investigating, and monitoring all flow through here.

{
  "status": "resolved",
  "comment": "Fixed by rolling back deploy abc123"
}
FieldTypeRequiredDescription
statusstringYesTarget canonical status name returned by incident read endpoints
commentstringNoReason 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/acknowledge

A 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/page

Send 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"
}
FieldTypeRequiredDescription
emailstringYesPerson to page
channelsstring[]YesOne or more delivery channels. Supported values: slack, email
messagestringNoCustom 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:

CodeMeaning
200At least one requested channel sent successfully. Response includes per-channel delivery results.
409Delivery failed for all requested channels because the user does not have the required contact details.
502Delivery failed for all requested channels because the notification provider could not deliver the message.

Add Timeline Event

POST /api/v1/incidents/:id/events

Add a timeline entry to an incident.

{
  "comment": "Identified root cause: connection pool leak in auth service"
}

Escalate Incident

POST /api/v1/incidents/:id/escalate

Escalate 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
  }
}