> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kaireonai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# System Health

> Per-tenant operational alert feed — errors, warnings, and tripped thresholds — with per-user read state.

The System Health API serves the operational alert feed: errors, warnings, and critical
thresholds tripped across the platform (flow runs, decisioning, approvals, licensing, data,
models, and the Decision Sentinel). It is distinct from the notification bell, which carries
passive product-feed content.

All endpoints are tenant-scoped and require role `viewer`, `editor`, or `admin`.

## GET /api/v1/system-health

Returns the alert feed for the current tenant, newest first, with the requesting user's read
state resolved per alert.

### Query parameters

| Parameter    | Type              | Default | Description                                                  |
| ------------ | ----------------- | ------- | ------------------------------------------------------------ |
| `cursor`     | string            | —       | Pagination cursor (an alert id; returns rows older than it). |
| `limit`      | integer           | `50`    | Page size. Max `200`.                                        |
| `unreadOnly` | boolean           | `false` | When `true`, only alerts the requesting user has not read.   |
| `since`      | string (ISO-8601) | —       | Only alerts created after this timestamp.                    |
| `severity`   | string (CSV)      | —       | Comma-separated severity filter (see values below).          |
| `source`     | string (CSV)      | —       | Comma-separated source filter (see values below).            |

**Severities:** `info`, `success`, `warning`, `error`, `critical`.

**Sources:** `flow`, `decisioning`, `approvals`, `license`, `system`, `data`, `model`, `sentinel`.
(The `source` column accepts arbitrary strings; these are the canonical values emitted across the codebase.)

### Response `200`

```json theme={null}
{
  "data": [
    {
      "id": "cha_...",
      "tenantId": "my-tenant",
      "userId": null,
      "severity": "critical",
      "source": "sentinel",
      "title": "Empty-candidate rate spiked",
      "message": "18% of decisions returned zero offers in the last 30m.",
      "link": "/dashboards/decision-health",
      "metadata": { "observed": 0.18, "threshold": 0.1 },
      "pinned": false,
      "createdAt": "2026-07-03T12:00:00.000Z",
      "read": false
    }
  ],
  "pagination": { "limit": 50, "cursor": "cha_...", "hasMore": true },
  "sources": ["flow", "decisioning", "approvals", "license", "system", "data", "model", "sentinel"],
  "severities": ["info", "success", "warning", "error", "critical"]
}
```

The response echoes the full `sources` and `severities` value lists so a client can build filter
controls without hard-coding them.

<Note>
  A user sees alerts addressed directly to them (`userId` matches) **plus** fan-out alerts
  (`userId: null`). API-key callers with no resolved user id see only fan-out alerts, and their
  `read` is always `false` (they have no per-user read state).
</Note>

## PATCH /api/v1/system-health/:id/read

Mark a single alert as read for the requesting user.

## POST /api/v1/system-health/read-all

Mark every alert visible to the requesting user as read.

## DELETE /api/v1/system-health/:id

Dismiss (delete) an alert for the tenant.

<Note>
  Read state is per-user, stored in `SystemHealthAlertRead`. Marking read does not delete or
  modify the alert — it only clears the unread indicator for that user. All three endpoints
  accept role `viewer`, `editor`, or `admin`.
</Note>
