Skip to content

API User Guide: API Usage

This page is a task-oriented guide to working with the Logster REST API. It covers the common analyst and integration workflows: listing alerts, drilling into one, transitioning its state, recording verdicts, and handling errors. Every workflow has a complete curl example.

For endpoint-by-endpoint specification, see the Reference. For base URL, auth, and Swagger UI, see the Overview.


Prerequisites

  • The Logster API is running at http://localhost:8080 (or wherever your deployment publishes it). Verify with:
curl http://localhost:8080/health
  • curl or any HTTP client. Examples on this page use curl with inline JSON bodies.

  • If you're putting the API behind an auth-enforcing reverse proxy (recommended for production), all examples on this page must be prefixed with your proxy's auth header — usually -H "Authorization: Bearer <token>". See Admin Guide: Authentication.


Workflow 1 — List current open alerts

The most common first action: "what's in my queue right now?"

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

Note on casing. The AlertStatus enum values in libs/logster-common/logster_common/schemas/alerts.py are lowercase strings ("open", "acknowledged", "investigating", "resolved", "false_positive"). The API expects them lowercase and returns them lowercase.

The response shape is documented in Reference: AlertListResponse. For the field-by-field schema, see Reference: AlertResponse schema.

Filter by tenant

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

Paginate

# First 50
curl 'http://localhost:8080/alerts?limit=50&offset=0'

# Next 50
curl 'http://localhost:8080/alerts?limit=50&offset=50'

[!TIP] The total field in the response is the full count before pagination. Use it to decide whether to fetch more pages.


Workflow 2 — Drill into one alert

Given an alert_id from the previous list response:

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

The response is a single AlertResponse object.

If the alert doesn't exist you get a 404:

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

Workflow 3 — Acknowledge an alert (start triage)

An analyst picks up an alert from the queue. Transition it from open to acknowledged so other analysts know it's being worked:

curl -X PATCH http://<host>:8080/alerts/<alert_id> \
  -H 'Content-Type: application/json' \
  -d '{
    "status": "acknowledged",
    "notes": "<TBD — real analyst note>",
    "resolved_by": "<TBD — analyst identifier>"
  }'

The response is the updated alert with status: "acknowledged", updated_at bumped, and resolved_by set.

Move to investigating

curl -X PATCH http://<host>:8080/alerts/<alert_id> \
  -H 'Content-Type: application/json' \
  -d '{
    "status": "investigating",
    "notes": "<TBD>",
    "resolved_by": "<TBD>"
  }'

Workflow 4 — Record an analyst verdict

When the investigation concludes, submit a true / false-positive verdict. This is the preferred way to close an alert because it:

  1. Transitions the alert to the right terminal state automatically (resolved for true positive, false_positive for false).
  2. Records the analyst and notes in one atomic call.
  3. Provides a ground-truth signal for analyst feedback tracking.

True positive

curl -X POST http://<host>:8080/feedback \
  -H 'Content-Type: application/json' \
  -d '{
    "alert_id": "<alert_id>",
    "is_true_positive": true,
    "notes": "<TBD — sanitized analyst summary>",
    "analyst": "<TBD>"
  }'

Response:

{
  "status": "ok",
  "alert_id": "<alert_id>",
  "new_status": "resolved",
  "is_true_positive": true
}

False positive

curl -X POST http://<host>:8080/feedback \
  -H 'Content-Type: application/json' \
  -d '{
    "alert_id": "<alert_id>",
    "is_true_positive": false,
    "notes": "<TBD>",
    "analyst": "<TBD>"
  }'

Response:

{
  "status": "ok",
  "alert_id": "<alert_id>",
  "new_status": "false_positive",
  "is_true_positive": false
}

Workflow 5 — Summarize all endpoints

Get a per-endpoint rollup (useful for an operations dashboard):

curl http://localhost:8080/endpoints

Response:

[
  {
    "endpoint_id": "desktop-alice-01",
    "tenant_id": "default",
    "platform": "windows",
    "total_alerts": 3,
    "open_alerts": 1,
    "last_alert_time": 1773956580.0
  },
  {
    "endpoint_id": "srv-app-02",
    "tenant_id": "default",
    "platform": "linux",
    "total_alerts": 1,
    "open_alerts": 0,
    "last_alert_time": 1773956200.0
  }
]

[!CAUTION] The /endpoints route internally fetches up to 10,000 alerts per tenant to build the summary. For tenants with more alerts than that, the summary will be truncated. Back the API with the Postgres store before relying on this at scale.


Error handling

The API returns standard HTTP status codes and a FastAPI-style error body:

Code Meaning Example cause
200 Success Any successful call
400 Bad request PATCH /alerts/{id} with an invalid status value
404 Not found Unknown alert_id
422 Validation error Missing required body field, wrong type
503 Service unavailable Alert store not attached (misconfiguration)

All error bodies use this shape:

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

Example — invalid status

curl -X PATCH http://<host>:8080/alerts/<alert_id> \
  -H 'Content-Type: application/json' \
  -d '{"status": "done"}'
{"detail": "Invalid status: done"}

Fix: use one of the valid lowercase AlertStatus values — open, acknowledged, investigating, resolved, false_positive. See libs/logster-common/logster_common/schemas/alerts.py for the authoritative enum.


Scripting integration

TBD — working client example.

Add a minimal client script (Python / Go / Node / etc.) that demonstrates listing alerts and posting feedback. Keep the sample restricted to two calls so it is easy to review. Use the lowercase status values from libs/logster-common/logster_common/schemas/alerts.py.

For a typed client, generate one from http://localhost:8080/openapi.json using any OpenAPI SDK generator.


Where to go next