Skip to content

Incident Feed API

The Incident endpoints of the External Feed API let MSSP partners, customer SOC teams, and SOAR platforms pull incidents out of RhythmX — a list of incidents, the full detail of any single incident, and, in one call, everything correlated to an incident: its LogRhythm alarms, its RhythmX Sigma alerts, and its threat cases.

All Incident endpoints share the External Feed API's authentication, rate limiting, and entity scoping. Include your key in the X-API-Key header with every request. Scoped keys only ever see their own entity; master keys (entity_name=*) see all entities and may narrow with ?entity_name=.

Base URL:  https://<your-rhythmx-host>/api/v1/feed

What is an incident?

An incident groups all the alarms raised for a single actor (a user or a computer) within one entity (site/customer). Each incident carries a group_key (the actor), an actor_type (user, host, or ip), and an activity window (first_alarm_timelast_alarm_time). The Incident Feed endpoints let a partner move from "an incident exists" to "here is all the evidence behind it" without stitching together multiple queries.

flowchart LR
    A["GET /incidents"] -->|"pick an incident_id"| B["GET /incidents/{id}"]
    B -->|"pull all evidence"| C["GET /incidents/{id}/related"]
    C --> D["LogRhythm alarms"]
    C --> E["RhythmX Sigma alerts"]
    C --> F["Threat cases"]

    style A fill:#0d47a1,stroke:#42a5f5,color:#fff
    style B fill:#0d47a1,stroke:#42a5f5,color:#fff
    style C fill:#4a148c,stroke:#9c27b0,color:#fff
    style D fill:#1b5e20,stroke:#4c8c4a,color:#fff
    style E fill:#1b5e20,stroke:#4c8c4a,color:#fff
    style F fill:#1b5e20,stroke:#4c8c4a,color:#fff

Endpoints

Endpoint Method Description
/api/v1/feed/incidents GET List incidents (filter by status/entity/time)
/api/v1/feed/incidents/{id} GET Full detail for a single incident
/api/v1/feed/incidents/{id}/related GET Incident plus all related LogRhythm alarms, RhythmX Sigma alerts, and threat cases

List Incidents

GET /api/v1/feed/incidents

Returns security incidents, newest activity first. Each incident represents a group of related alarms for an actor.

Parameters:

Parameter Type Description
entity_name string (Optional) Filter by entity/site. Master keys only — scoped keys ignore this.
status string OPEN, IN_PROGRESS, CLOSED, FALSE_POSITIVE
since string ISO 8601 — incidents with updated_at after this time
limit integer Results per page (default: 50, max: 500)
offset integer Pagination offset (default: 0)

Example:

curl -H "X-API-Key: smk_abc12345..." \
     "https://rhythmx.example.com/api/v1/feed/incidents?status=OPEN&limit=20"

Response:

{
  "success": true,
  "data": [
    {
      "incident_id": "INC-a1b2c3d4",
      "group_key": "jsmith",
      "actor_type": "user",
      "entity_name": "Primary Site",
      "status": "OPEN",
      "assigned_analyst": null,
      "first_alarm_time": "2026-03-02T08:15:00Z",
      "last_alarm_time": "2026-03-02T14:20:00Z",
      "created_at": "2026-03-02T14:22:00Z",
      "updated_at": "2026-03-02T14:22:00Z",
      "closed_at": null,
      "external_ticket_id": null,
      "external_system": null
    }
  ],
  "pagination": { "total": 12, "limit": 20, "offset": 0, "has_more": false },
  "timestamp": "2026-03-20T10:30:00Z"
}


Get Incident Detail

GET /api/v1/feed/incidents/{incident_id}

Returns full details for a single incident (all stored fields). Returns 404 if the incident does not exist or is outside a scoped key's entity.

Example:

curl -H "X-API-Key: smk_abc12345..." \
     https://rhythmx.example.com/api/v1/feed/incidents/INC-a1b2c3d4

Response:

{
  "success": true,
  "data": {
    "incident_id": "INC-a1b2c3d4",
    "group_key": "jsmith",
    "actor_type": "user",
    "entity_name": "Primary Site",
    "status": "OPEN",
    "first_alarm_time": "2026-03-02T08:15:00Z",
    "last_alarm_time": "2026-03-02T14:20:00Z",
    "...": "all remaining incident fields"
  },
  "timestamp": "2026-03-20T10:30:00Z"
}


GET /api/v1/feed/incidents/{incident_id}/related

Returns the incident and everything correlated to its actor in a single call — the fastest way for an external SOC or SOAR platform to build the full picture behind an incident. Three evidence sections are returned together:

Section Source What it contains
logrhythm_alarms LogRhythm The actor's LogRhythm alarms — a per-rule rollup plus a capped list of individual alarms
sigma_alerts RhythmX detection engine The actor's RhythmX Sigma alerts — a per-rule rollup plus a capped list of individual alerts
threat_cases RhythmX analytics engine Threat cases whose activity overlaps the incident

All three sections are scoped to the incident's entity — a partner never sees another tenant's data through this call. The actor is matched by actor_type: users match on their user id (source or target), hosts on their computer name, IPs on their address.

Parameters

Parameter Type Description
window string incident (default) — bound results to the incident's activity window (first_alarm_timelast_alarm_time). all — no time bound; return the actor's full retained history in this entity.
limit integer Max records returned per section (default: 100, max: 500). The per-rule rollups and totals are always complete; only the individual-record lists are capped.

The window parameter

Use the default window=incident to see only the activity that defines this incident. Use window=all to pull the actor's entire history in this entity — useful for retro-hunting, because it surfaces older alarms, alerts, and threat cases that predate the incident window. Each section reports a total so you can tell when the per-section limit has truncated the returned list.

Example

# Everything tied to the incident, within its activity window
curl -H "X-API-Key: smk_abc12345..." \
     "https://rhythmx.example.com/api/v1/feed/incidents/INC-a1b2c3d4/related"

# The actor's full history in this entity, 250 records per section
curl -H "X-API-Key: smk_abc12345..." \
     "https://rhythmx.example.com/api/v1/feed/incidents/INC-a1b2c3d4/related?window=all&limit=250"

Response

{
  "success": true,
  "incident": {
    "incident_id": "INC-a1b2c3d4",
    "group_key": "jsmith",
    "actor_type": "user",
    "entity_name": "Primary Site",
    "status": "OPEN",
    "first_alarm_time": "2026-03-02T08:15:00Z",
    "last_alarm_time": "2026-03-02T14:20:00Z"
  },
  "window": {
    "mode": "incident",
    "start": "2026-03-02T08:15:00Z",
    "end": "2026-03-02T14:20:00Z"
  },
  "logrhythm_alarms": {
    "total": 3,
    "rule_groups": [
      {
        "alarm_rule": "Windows User Added to Privileged/Security/Admin Groups",
        "alarm_count": 1,
        "first_seen": "2026-03-02T09:41:50Z",
        "last_seen": "2026-03-02T09:41:50Z",
        "max_rbp": 65
      }
    ],
    "alarms": [
      {
        "alarm_id": 8338492,
        "alarm_rule": "Windows User Added to Privileged/Security/Admin Groups",
        "alarm_date": "2026-03-02T09:41:50Z",
        "rbp_max": 65
      }
    ],
    "returned": 3
  },
  "sigma_alerts": {
    "total": 49,
    "unique_rules": 8,
    "max_risk": 34,
    "rule_groups": [
      {
        "title": "External Remote SMB Logon from Public IP",
        "rule_level": "high",
        "tactics": "initial-access,credential-access",
        "techniques": "t1133,t1078,t1110",
        "event_count": 49,
        "last_seen": "2026-03-02T14:08:59Z",
        "max_risk": 34
      }
    ],
    "alerts": [
      {
        "id": 3188483435,
        "system_time": "2026-03-02T13:59:53Z",
        "title": "Failed Logon From Public IP",
        "rule_level": "medium",
        "tactics": "initial-access,persistence",
        "techniques": "t1078,t1190,t1133",
        "risk": 31,
        "computer_name": "DC01",
        "ip_address": "203.0.113.42",
        "user_id": "(unknown)",
        "target_user_name": "jsmith"
      }
    ],
    "returned": 100
  },
  "threat_cases": {
    "total": 2,
    "cases": [
      {
        "case_id": "CASE-20260302-30E8278B",
        "case_type": "SYSTEM_BINARY_ANOMALY",
        "status": "OPEN",
        "severity": "HIGH",
        "max_risk_score": 15,
        "auto_created": 1,
        "first_alert_time": "2026-03-02T12:06:10Z",
        "last_alert_time": "2026-03-02T12:06:19Z",
        "created_at": "2026-03-02T12:44:58Z",
        "lr_case_id": null,
        "affected_computers": "[\"WS-PC42\"]"
      }
    ],
    "returned": 2
  },
  "limit_per_section": 100,
  "timestamp": "2026-03-20T10:30:00Z"
}

Response fields

Top level

Field Description
incident The incident record (same shape as Get Incident Detail).
window The time bound applied. mode is incident or all; start/end are the bounds (both null when mode is all).
logrhythm_alarms / sigma_alerts / threat_cases The three evidence sections (below).
limit_per_section The effective per-section record cap for this response.
timestamp Server time the response was generated (UTC).

logrhythm_alarms

Field Description
total Total distinct LogRhythm alarms for the actor in scope.
rule_groups[] Per-rule rollup: alarm_rule, alarm_count, first_seen, last_seen, max_rbp (peak Risk-Based Priority).
alarms[] Individual alarms (capped at limit): alarm_id, alarm_rule, alarm_date, rbp_max.
returned Number of individual alarms in alarms[].

sigma_alerts

Field Description
total Total RhythmX Sigma alerts for the actor in scope.
unique_rules Distinct rule titles.
max_risk Highest risk score across the matched alerts.
rule_groups[] Per-rule rollup: title, rule_level, tactics, techniques, event_count, last_seen, max_risk.
alerts[] Individual alerts (capped at limit): id, system_time, title, rule_level, tactics, techniques, risk, computer_name, ip_address, user_id, target_user_name.
returned Number of individual alerts in alerts[].

threat_cases

Field Description
total Total threat cases for the actor in scope.
cases[] Case records (capped at limit): case_id, case_type, status, severity, max_risk_score, auto_created, first_alert_time, last_alert_time, created_at, lr_case_id, affected_computers.
returned Number of cases in cases[].

Reading the totals

Each section's total counts everything matched in scope, while returned counts only what fits inside the per-section limit. If returned < total, raise limit (up to 500) or narrow the window to pull the rest.


Error codes

Code Meaning
200 Success
401 Missing, invalid, expired, or disabled API key
404 Incident not found (or outside a scoped key's entity)
429 Rate limit exceeded
500 Internal server error

Error response:

{ "error": "Incident not found" }


See the full External Feed API reference for cases, alerts, metrics, MITRE, entities, and risk endpoints.