Install
openclaw skills install incidentioManage incidents via the incident.io REST API. Create, view, update, escalate, and resolve incidents. Check severities, statuses, and post incident updates. Requires INCIDENTIO_API_KEY environment variable.
openclaw skills install incidentioManage incidents, severities, statuses, and post updates via the incident.io REST API.
export INCIDENTIO_API_KEY="your-api-key"
Base URL: https://api.incident.io
Important: The API has a v1/v2 split:
All requests use this auth pattern:
curl -s "https://api.incident.io/v2/..." \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" \
-H "Content-Type: application/json"
Rate limit: 1200 requests/minute per API key.
Pagination: Use page_size (max 250) and the after cursor from pagination_meta.after in responses.
Severities are organization-specific. Always fetch them before creating an incident to get valid IDs.
curl -s "https://api.incident.io/v1/severities" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" | jq '.severities[] | {id, name, rank}'
curl -s "https://api.incident.io/v1/incident_statuses" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" | jq '.incident_statuses[] | {id, name, category}'
Status categories: triage, live, learning, closed, declined, merged, canceled.
curl -s "https://api.incident.io/v1/incident_types" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" | jq '.incident_types[] | {id, name, is_default}'
Required fields: idempotency_key, visibility. A severity_id is needed to open an active incident.
curl -s -X POST "https://api.incident.io/v2/incidents" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"idempotency_key": "unique-key-123",
"name": "Database connection pool exhaustion",
"summary": "Primary DB connection pool at 100% causing request failures",
"severity_id": "SEVERITY_ID",
"visibility": "public",
"mode": "standard"
}' | jq '.incident | {id, reference, name, permalink}'
Optional fields:
incident_type_id — set a specific incident typeincident_status_id — override the default starting statusmode — standard (default), retrospective (no Slack announcement), or test (no alerts)visibility — public or privatecustom_field_entries — array of {custom_field_id, values: [{value_link}]}incident_role_assignments — array of {incident_role_id, user: {id}}incident_timestamp_values — array of {incident_timestamp_id, value}Always generate a unique idempotency_key per incident (e.g. a UUID or descriptive slug).
curl -s "https://api.incident.io/v2/incidents/INCIDENT_ID" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" \
| jq '.incident | {id, reference, name, summary, status: .incident_status.name, severity: .severity.name, created_at, permalink}'
curl -s "https://api.incident.io/v2/incidents?page_size=25" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" \
| jq '.incidents[] | {id, reference, name, status: .incident_status.name, severity: .severity.name}'
Filter parameters (query string):
status_category[one_of]=live — filter by category (triage, live, learning, closed, declined, merged, canceled)status[one_of]=STATUS_ID — filter by exact status ID (repeatable)severity[one_of]=SEVERITY_ID — filter by severity (repeatable)severity[gte]=SEVERITY_ID / severity[lte]=SEVERITY_ID — filter by severity rankcreated_at[gte]=2024-01-01 / created_at[lte]=2024-12-31 — date rangemode[one_of]=standard — filter by modepage_size=N (max 250) and after=CURSOR for paginationOnly provided fields are updated; omitted fields remain unchanged.
curl -s -X POST "https://api.incident.io/v2/incidents/INCIDENT_ID/actions/edit" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"incident": {
"summary": "Root cause identified: memory leak in connection pooler",
"severity_id": "NEW_SEVERITY_ID"
},
"notify_incident_channel": true
}' | jq '.incident | {id, reference, name, severity: .severity.name}'
Editable fields inside incident:
name, summary, severity_id, incident_status_idcall_url, slack_channel_name_overridecustom_field_entries, incident_role_assignments, incident_timestamp_valuesSet notify_incident_channel: true to alert responders of the change.
Closing is done by setting incident_status_id to a status with category closed. First, find the closed status ID:
curl -s "https://api.incident.io/v1/incident_statuses" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" \
| jq '.incident_statuses[] | select(.category == "closed") | {id, name}'
Then update the incident:
curl -s -X POST "https://api.incident.io/v2/incidents/INCIDENT_ID/actions/edit" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"incident": {
"incident_status_id": "CLOSED_STATUS_ID"
},
"notify_incident_channel": true
}' | jq '.incident | {id, reference, name, status: .incident_status.name}'
curl -s -X POST "https://api.incident.io/v2/incident_updates" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"incident_id": "INCIDENT_ID",
"message": "Rolling restart in progress. Monitoring connection pool metrics."
}' | jq '.incident_update | {id, message, created_at}'
curl -s "https://api.incident.io/v2/incident_updates?incident_id=INCIDENT_ID&page_size=25" \
-H "Authorization: Bearer $INCIDENTIO_API_KEY" \
| jq '.incident_updates[] | {id, message, created_at}'
GET /v1/severities to get valid severity IDsPOST /v2/incidents with name, severity, visibilityPOST /v2/incident_updates as investigation progressesPOST /v2/incidents/{id}/actions/editclosed-category statusGET /v2/incidents?status_category[one_of]=liveGET /v2/incidents/{id} for each incidentGET /v2/incident_updates?incident_id={id} for latest status01FCNDV6P870EA6S7TK1DSYDG0)idempotency_key on create prevents duplicate incidents; use a unique value per requestmode: "test" creates test incidents that do not alert respondersincident object, unlike the create endpointafter cursor from pagination_meta.after in responses