Online-status heartbeat
VIEWER+. Lightweight — `MAX(Session.endedAt)` keyed on the indexed `trackedUserId`, no `Event` table scan. Online flag flips when the most recent session ended within `ONLINE_THRESHOLD_MS`. `Cache-Control: no-store` so polling sees fresh values.
/api/tracked-users/{userId}/statusVIEWER+. Lightweight — MAX(Session.endedAt) keyed on the indexed trackedUserId, no Event table scan. Online flag flips when the most recent session ended within ONLINE_THRESHOLD_MS. Cache-Control: no-store so polling sees fresh values.
Path Parameters
TrackedUser id (cuid)
Response Body
application/json
curl -X GET "https://loading/api/tracked-users/string/status"{
"online": true,
"lastEventAt": "2026-04-26T10:33:04.320Z"
}Sessions for one tracked user, cursor-paginated GET
VIEWER+. Slim shape — no event payload, no trait JSON. Detail fields hydrate per-row via the session detail endpoint on demand. `userDisplayName` is `null` here on purpose (the user-detail page already surfaces the identity above the table).
Sessions timeline in a rolling window GET
VIEWER+. `?range=` matches the activity histogram (`6h` / `24h` / `7d`). Server computes `from = now - windowMs` itself — sending raw ISO from the client would shift the TanStack Query key on every render. Sessions overlap the window if they `startedAt ≤ to AND (endedAt ≥ from OR endedAt IS NULL)`.