List tracked users, cursor-paginated
VIEWER+. Scoped to the caller's active org. Filters: `?search=` (matches `externalId` OR `customName`, case-insensitive), `?projectIds=`, `?statuses=ONLINE,ACTIVE_24H,...`, `?sort=last-seen|sessions|active-time|newest`, `?sortDir=`. Status is derived (not indexable) — when status filter is active the route over-fetches up to 500 rows and applies it in JS.
/api/tracked-usersVIEWER+. Scoped to the caller's active org. Filters: ?search= (matches externalId OR customName, case-insensitive), ?projectIds=, ?statuses=ONLINE,ACTIVE_24H,..., ?sort=last-seen|sessions|active-time|newest, ?sortDir=. Status is derived (not indexable) — when status filter is active the route over-fetches up to 500 rows and applies it in JS.
Query Parameters
"last-seen" | "sessions" | "active-time" | "newest""desc" | "asc"1 <= value <= 100Response Body
application/json
curl -X GET "https://loading/api/tracked-users"{
"data": [
{
"id": "tu_t5u6v7w8",
"externalId": "usr_abc123",
"displayName": "alex@your-app.com",
"projectId": "prj_x9y8z7w6",
"projectName": "Production",
"traits": {
"plan": "pro",
"email": "alex@your-app.com"
},
"sessionCount": 14,
"lastEventAt": "2026-04-26T10:33:04.320Z",
"status": "ONLINE",
"activeTime7d": 184320,
"createdAt": "2026-04-15T11:24:00.000Z"
}
],
"nextCursor": null
}Cancel a session — SDK `stop()` teardown path POST
Public-key authenticated. Hard-deletes the session row matching `(projectId, externalId)`. Quiet no-op when no row exists — cancellation can race with the first ingest batch arriving. The `(projectId, externalId)` scoping prevents one project's key from cancelling another project's session.
Full tracked-user detail GET
VIEWER+. Same shape `loadTrackedUserDetail` produces for the user-detail page Server Component prefetch — `HydrationBoundary` skips the on-mount refetch because the wire format is byte-identical.