Skip to content

API User Guide: Reference

This page is the endpoint-by-endpoint reference for the Logster REST API. Every shape here is derived from services/api/src/logster_api/app.py. If anything here drifts from that file, the file wins.

For base URL, authentication posture, and interactive docs, see the Overview. For task-oriented workflows, see API Usage.


Endpoints at a glance

Method Path Purpose
GET /health Service health check
GET /alerts List alerts, filtered and paginated
GET /alerts/{alert_id} Fetch one alert
PATCH /alerts/{alert_id} Update status / notes
POST /feedback Submit analyst verdict
GET /endpoints Per-endpoint summary

GET /health

Returns a lightweight liveness response plus a cheap summary of how many alerts the in-process store currently holds.

Response — HealthResponse

Field Type Notes
status string "ok" when the alert store is attached.
service string Always "logster-api".
uptime_seconds float Seconds since the FastAPI app started.
alerts_count int Current count of alerts in the store.

Example

curl http://localhost:8080/health
{
  "status": "ok",
  "service": "logster-api",
  "uptime_seconds": 1234.56,
  "alerts_count": 42
}

GET /alerts

List alerts with optional filtering and pagination.

Query parameters

Name Type Default Notes
tenant_id string Restrict to a single tenant.
status string One of open, acknowledged, investigating, resolved, false_positive (lowercase — enum values in libs/logster-common/logster_common/schemas/alerts.py). Invalid values return 400.
limit int 100 Must be 1..1000.
offset int 0 Zero-based page offset.

Response — AlertListResponse

Field Type Notes
alerts array of AlertResponse Current page.
total int Total matching alerts in the store (pre-pagination), for this tenant if tenant_id is supplied.
limit int Echo of the request limit.
offset int Echo of the request offset.

Example

curl 'http://localhost:8080/alerts?tenant_id=default&status=open&limit=50'

GET /alerts/{alert_id}

Fetch a single alert by id.

Path parameters

Name Type Notes
alert_id string The alert_id returned by a previous /alerts query.

Responses

  • 200AlertResponse
  • 404{"detail": "Alert <id> not found"}

Example

curl http://localhost:8080/alerts/6f0a8d3e-2b1c-4f6e-9a70-123456789abc

PATCH /alerts/{alert_id}

Update an alert's status and optionally attach analyst notes. This is how analysts move an alert through its lifecycle.

Request body — UpdateAlertRequest

Field Type Default Notes
status string Required. One of the AlertStatus values. Invalid → 400.
notes string "" Free-form analyst notes.
resolved_by string "" Identifier of the analyst or service account performing the transition.

Valid AlertStatus values

Source of truth: libs/logster-common/logster_common/schemas/alerts.py.

open → acknowledged → investigating → resolved / false_positive

The AlertStatus enum values are lowercase strings. The API expects them lowercase on input and returns them lowercase in responses.

[!NOTE] The API does not enforce a specific transition graph — any valid enum value is accepted from any starting state. Enforce your own workflow at the client or the reverse proxy if you need it.

Responses

  • 200AlertResponse reflecting the new state.
  • 400{"detail": "Invalid status: <value>"}
  • 404 — Alert not found.

Example

curl -X PATCH http://localhost:8080/alerts/6f0a8d3e-2b1c-4f6e-9a70-123456789abc \
  -H 'Content-Type: application/json' \
  -d '{"status":"investigating","notes":"Reviewing process tree","resolved_by":"alice"}'

POST /feedback

Record an analyst's true-positive / false-positive verdict on an alert. Under the hood this is a thin wrapper that calls store.update_status(...) with resolved or false_positive depending on is_true_positive.

This is the canonical "ground truth" hook — in future Logster Support model releases, it will feed a retraining pipeline.

Request body — FeedbackRequest

Field Type Default Notes
alert_id string Required.
is_true_positive bool Required. true → status becomes resolved; falsefalse_positive.
notes string "" Analyst notes, stored on the alert.
analyst string "" Analyst identifier, stored as resolved_by.

Response

{
  "status": "ok",
  "alert_id": "<id>",
  "new_status": "resolved",
  "is_true_positive": true
}
  • 200 — Success.
  • 404 — Alert not found.

Example

curl -X POST http://localhost:8080/feedback \
  -H 'Content-Type: application/json' \
  -d '{"alert_id":"6f0a8d3e-...","is_true_positive":false,"notes":"Dev workstation","analyst":"alice"}'

GET /endpoints

Aggregates all alerts by endpoint and returns one row per endpoint, regardless of status.

Query parameters

Name Type Default Notes
tenant_id string Restrict to a single tenant.

Response — array of EndpointStatusResponse

Field Type Notes
endpoint_id string Hostname (lowercased).
tenant_id string Tenant the endpoint belongs to.
platform string windows or linux.
total_alerts int All alerts ever seen for this endpoint.
open_alerts int Count where status == "open".
last_alert_time float Unix epoch of most recent alert, or null.

[!CAUTION] This endpoint internally calls store.list_alerts(..., limit=10000). Tenants with more than ~10,000 alerts in the store will have truncated summaries. Back the API with the Postgres store before relying on this at scale. See Admin Guide: Important Considerations.

Example

curl 'http://localhost:8080/endpoints?tenant_id=default'

AlertResponse schema

Every single-alert response uses this shape. Source definition: services/api/src/logster_api/app.py.

Field Type Notes
alert_id string UUID, primary key.
tenant_id string Tenant isolation key.
endpoint_id string Hostname (lowercased).
severity string low / medium / high / critical. Derived from attack_prob. Serialized as the enum's lowercase value.
status string Current AlertStatus (open, acknowledged, investigating, resolved, false_positive). Serialized as the enum's lowercase value.
platform string windows or linux.
attack_prob float Model probability of attack (0.01.0).
confidence float Model confidence.
prediction string Raw model label: attack / benign / error.
ttp_techniques array of string MITRE ATT&CK technique IDs (e.g. T1059.001). Empty if the TTP analyzer is not deployed.
ttp_explanation string, nullable Human-readable TTP description.
inference_ids array of string All inference results merged into this alert by dedup.
related_endpoints array of string Other endpoints that alerted within alerts.correlation_window_seconds.
first_seen float Unix epoch of first contributing inference.
last_seen float Unix epoch of most recent contributing inference.
created_at float Unix epoch when the alert was first opened.
updated_at float Unix epoch of last state change.
analyst_notes string Free-form notes attached via PATCH/feedback.
resolved_by string, nullable Identifier of the analyst or automation that most recently transitioned the alert.
model_name string Name of the model that produced the underlying inference.
num_nodes int Nodes in the GNN graph that produced the most recent inference.
num_edges int Edges in that graph.

Severity derivation

attack_prob >= 0.95  →  CRITICAL
attack_prob >= 0.85  →  HIGH
attack_prob >= 0.70  →  MEDIUM
attack_prob <  0.70  →  LOW

This is enforced by the alerts service. alerts.min_threshold in Admin Guide: Installation Parameters controls whether LOW alerts ever reach the store at all.


Error shape

All error responses use FastAPI's standard shape:

{"detail": "Alert 6f0a8d3e-... not found"}

Status codes

Code When
200 Success.
400 Invalid status on PATCH /alerts/{id}.
404 Unknown alert_id.
422 FastAPI automatic validation error.
503 Alert store is not attached (misconfiguration).

Where to go next

  • API Usage — workflows with curl examples.
  • Overview — base URL, auth, interactive docs.