Skip to content
Try the API

Manage incidents

An incident is an episode built around one finding (a Hunt finding, a violation or a data-classification result) on one asset. This guide shows how to pull the open queue into your own tooling, read an incident’s audit history, and assign, comment on or close it from a script.

Each incident row has two statuses that change independently:

  • status is the episode lifecycle: open or closed.
  • finding.status is the disposition of the underlying finding: open, acknowledged, suppressed or resolved. You change it with the finding endpoints in Findings and violations.

finding is null when the finding is no longer available. Your code should handle that.

GET
/gateway/api/v2/incidentsList retained incident episodes
Try it

With no parameters the list returns open incidents sorted by SEVERITY_ASC. That puts critical first, Hunt findings before violations, and oldest first. The filters below are all optional. Severity, finding status and type take comma-separated lists.

Parameter Values
status open, closed, all
finding_status open, acknowledged, suppressed, resolved
severity critical, high, medium, low, info
type threat, violation, data_classification
assignee me, unassigned, or a tenant member UUID
search Substring match over handle, finding key, asset name or ID, title and method
sort_by SEVERITY_ASC, SEVERITY_DESC, OPENED_AT_ASC, OPENED_AT_DESC, HANDLE_ASC, HANDLE_DESC, ASSET_NAME_ASC, ASSET_NAME_DESC, ASSIGNEE_ASC, ASSIGNEE_DESC
limit, offset Offset pagination. limit defaults to 20, which is also the maximum.

This example fetches every unassigned critical or high incident built on a Hunt finding (type=threat), one page at a time:

Terminal window
curl -G "https://acme.app.elastio.com/gateway/api/v2/incidents" \
-H "Authorization: Bearer $ELASTIO_TOKEN" \
--data-urlencode "severity=critical,high" \
--data-urlencode "type=threat" \
--data-urlencode "assignee=unassigned" \
--data-urlencode "sort_by=OPENED_AT_ASC" \
--data-urlencode "limit=20" \
--data-urlencode "offset=0"

Example response (trimmed):

{
"total": 3,
"data": [
{
"id": "6f1c2a3e-8b4d-4e2a-9c1f-0a1b2c3d4e5f",
"handle": "INC-000042",
"finding_type": "threat",
"asset_id": "2b7e9c1d-3f4a-4b5c-8d6e-7f8091a2b3c4",
"status": "open",
"assignee_id": null,
"opened_at": "2026-10-08T14:02:11Z",
"last_observed_at": "2026-10-11T09:30:00Z",
"closed_at": null,
"closure_reason": null,
"version": 1,
"finding": {
"id": "threat:2b7e9c1d-3f4a-4b5c-8d6e-7f8091a2b3c4:ransomware",
"class": "threat",
"severity": "critical",
"status": "open",
"asset_name": "prod-db-01",
"asset_kind": "ec2",
"platform": "aws",
"platform_details": { "account_id": "123456789012", "region": "us-east-1" },
"files_affected": 118,
…
},
…
}
]
}
GET
/gateway/api/v2/incidents/filtersGet contextual filter options for incidents
Try it

The filters endpoint takes the same filters as the list, without pagination or sort, and returns a count for each value of each facet. Each facet ignores its own filter. So if you filter by severity=critical, the severity facet still shows counts for every severity, while the other facets count only critical incidents.

Terminal window
curl "https://acme.app.elastio.com/gateway/api/v2/incidents/filters?status=open&type=threat" \
-H "Authorization: Bearer $ELASTIO_TOKEN"

Example response (trimmed):

{
"total": 12,
"severity": [
{ "value": "critical", "count": 3 },
{ "value": "high", "count": 9 }
],
"finding_status": [
{ "value": "open", "count": 10 },
{ "value": "acknowledged", "count": 2 }
],
"type": [ { "value": "threat", "count": 12 }, … ],
"assignee": [ … ],
"status": [ … ]
}
GET
/gateway/api/v2/incidents/{id}Get an incident and its retained audit history
Try it

The detail call returns the same fields as a list row, plus history, the append-only audit trail for the episode. Note the version field. Every write in the next section must send the current version, so read the incident right before you change it.

Terminal window
curl "https://acme.app.elastio.com/gateway/api/v2/incidents/6f1c2a3e-8b4d-4e2a-9c1f-0a1b2c3d4e5f" \
-H "Authorization: Bearer $ELASTIO_TOKEN"

Example response (trimmed):

{
"id": "6f1c2a3e-8b4d-4e2a-9c1f-0a1b2c3d4e5f",
"handle": "INC-000042",
"status": "open",
"assignee_id": null,
"opened_at": "2026-10-08T14:02:11Z",
"version": 1,
"finding": { "id": "threat:2b7e9c1d-3f4a-4b5c-8d6e-7f8091a2b3c4:ransomware", "class": "threat", "severity": "critical", … },
"history": [
{ "id": "…", "at": "2026-10-08T14:02:11Z", "actor": "…", "event": "…", "details": { … } }
],
…
}

Assign, comment, close and reopen are all POST calls on the incident. Each one records an audit entry and takes the incident’s current version for optimistic concurrency. If someone else has changed the incident since you read it, the version no longer matches and the call fails. Re-read the incident and try again.

GET
/gateway/api/v2/incident-assigneesList active tenant members eligible for assignment
Try it

This returns the active tenant members who can be assigned. The spec doesn’t document the response body, so check the API reference or inspect a live response before you parse it.

POST
/gateway/api/v2/incidents/{id}/assignAssign an incident
Try it

The body takes version and assignee_id, both required, plus an optional comment. Send "assignee_id": null to unassign.

Terminal window
curl -X POST "https://acme.app.elastio.com/gateway/api/v2/incidents/6f1c2a3e-8b4d-4e2a-9c1f-0a1b2c3d4e5f/assign" \
-H "Authorization: Bearer $ELASTIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"version": 1,
"assignee_id": "9d8c7b6a-5f4e-4d3c-8b2a-1f0e9d8c7b6a",
"comment": "Taking this one during the on-call shift."
}'
POST
/gateway/api/v2/incidents/{id}/commentComment on an incident
Try it

The comment body takes version and comment, both required. Re-read the incident first, because the assignment above changed its version.

Terminal window
curl -X POST "https://acme.app.elastio.com/gateway/api/v2/incidents/6f1c2a3e-8b4d-4e2a-9c1f-0a1b2c3d4e5f/comment" \
-H "Authorization: Bearer $ELASTIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "version": 2, "comment": "Isolated the instance; restoring from the last clean recovery point." }'
POST
/gateway/api/v2/incidents/{id}/closeClose an incident
Try it

Closing requires version, comment and a reason. The reason must be one of remediated, false_positive, accepted_risk or duplicate. Closing the episode doesn’t change the finding’s disposition. If the problem is fixed, also resolve the finding (see Findings and violations).

Terminal window
curl -X POST "https://acme.app.elastio.com/gateway/api/v2/incidents/6f1c2a3e-8b4d-4e2a-9c1f-0a1b2c3d4e5f/close" \
-H "Authorization: Bearer $ELASTIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "version": 3, "reason": "remediated", "comment": "Restored from clean recovery point; follow-up hunt found nothing." }'

To undo a close, call POST /gateway/api/v2/incidents/{id}/reopen with version and comment. The spec doesn’t document a success response body for any of these four calls. Check the HTTP status, then re-read the incident to see its new state.

PUT
/gateway/api/v2/incident-settingsSet tenant incident history retention, at most 730 days
Try it

Incident history retention is a tenant-wide setting. The body takes retention_days, an integer of at most 730. Read the current value with GET /gateway/api/v2/incident-settings.

Terminal window
curl -X PUT "https://acme.app.elastio.com/gateway/api/v2/incident-settings" \
-H "Authorization: Bearer $ELASTIO_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "retention_days": 365 }'