API reference · Kaltreon
Integrate with the Kaltreon fleet surface.
Every public HTTP endpoint for pulling sensor telemetry and pushing telemetry back. Plain JSON, no SDK, no auth required for the public read surface — see Authentication for the write surface.
Rate limits
Current soft ceilings and the forward-looking quota model.
Today the public read surface runs without an explicit per-key quota — the soft ceilings below are the only rate-shaped knobs. The forward-looking model moves per-operator quotas into the same auth surface documented above so a tier can move with the fleet.
- GET /api/radar/frames
limitaccepts 1–600 frames per poll (default 120). No per-key rate ceiling — the limit is the size cap, not a frequency cap. - POST /api/radar/recalibrate60-second cool-down per device. A duplicate POST inside the window is a no-op and returns the in-flight event — not a rate limit, a debounce.
- Everything elseNo explicit per-key limit today. Polling at a steady cadence from a single integrator host is the expected pattern.
Forward-looking: per-operator quotas (requests/minute, frames/minute, concurrent recalibrations) will move into the Authentication section above as the auth model grows a tier claim. Documented ceilings land here before they take effect.
Authentication
Authentication
better-auth (v1.6.x) is the session model — the read surface is public, but any write surface (alert triage, archived compliance reports) requires a same-origin session cookie. Sign in once, then call the gated endpoints with the cookie attached.
/api/auth/sign-in/emailRequest body
{
"email": "operator@kaltreon.example",
"password": "••••••••"
}Response
HTTP/1.1 200 OK
Set-Cookie: better-auth.session_token=<token>; Path=/; HttpOnly; SameSite=Lax
{
"user": {
"id": "usr_01HZX8K3M9N5P7R2T4V6X8Z0AB",
"email": "operator@kaltreon.example",
"name": "Demo Operator",
"role": "user"
}
}Mounted by the catch-all at `/api/auth/[...all]/route.ts` from the installed `better-auth` module (v1.6.x). The client calls this same path with no baseURL — same-origin only, so the cookie scope matches the host the integrator is running against. Subsequent gated endpoints read the cookie automatically.
/api/auth/sign-outRequest body
{}Response
HTTP/1.1 200 OK
Set-Cookie: better-auth.session_token=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0
{
"success": true
}Same-origin only — the client ships the cookie it received from `POST /api/auth/sign-in/email`. There is no separate admin sign-out; the same endpoint ends both roles' sessions.
Ingest
Ingest
Live phased-array frames the on-platform radar agent produces, plus the recalibration write surface that fires when drift crosses the threshold.
/api/radar/framesQuery params
{
"limit": 120,
"sinceMs": 1754054400000
}Response
{
"items": [
{
"id": "frm_01HZX9T7M3Q5R8V2Y4N6C8B0KD",
"deviceId": "cr-77ghz-fwd-01",
"capturedAtIso": "2026-08-03T14:22:18.114Z",
"canBusMs": "1754054538114",
"channelCount": 32,
"magnitudeSample": [
0.41, 0.42, 0.44, 0.45, 0.47, 0.48, 0.49, 0.5,
0.51, 0.52, 0.53, 0.54, 0.55, 0.56, 0.57, 0.58,
0.59, 0.6, 0.61, 0.62, 0.63, 0.62, 0.6, 0.58,
0.56, 0.54, 0.52, 0.5, 0.48, 0.46, 0.44, 0.42
],
"driftMetric": 0.341,
"status": "watch"
}
],
"serverTimeMs": 1754054538114,
"canBusEpochMs": 1754054400000,
"threshold": 0.45,
"latestRecalEventId": "evt_cr-77ghz-corner-r_20260730"
}`limit` accepts 1–600 (default 120). `sinceMs` is an epoch-ms lower bound — items whose `canBusMs` is `>= sinceMs` are returned. This is the downstream consumer mirror of the live feed; the closest public read of ingest today.
/api/radar/recalibrateRequest body
{
"frameId": "frm_01HZX9T7M3Q5R8V2Y4N6C8B0KD"
}Response
{
"id": "evt_cr-77ghz-fwd-01_20260803",
"frameId": "frm_01HZX9T7M3Q5R8V2Y4N6C8B0KD",
"deviceId": "cr-77ghz-fwd-01",
"startedAtIso": "2026-08-03T14:22:18.512Z",
"completedAtIso": "2026-08-03T14:22:24.918Z",
"outcome": "recovered",
"routine": "boresight_rerun_v3",
"notes": null,
"triggerDrift": 0.482,
"triggerThreshold": 0.45,
"lifecycle": "completed",
"sensorType": "radar"
}60-second cool-down per device (a duplicate POST within the window is a no-op and returns the in-flight event). Returns `404 frame_not_in_ring` if the frame has rolled out of the 256-frame ring buffer — re-poll `/api/radar/frames` and retry.
/api/radar/events/[id]Path params
{
"id": "evt_cr-77ghz-fwd-01_20260803"
}Response
{
"event": {
"id": "evt_cr-77ghz-fwd-01_20260803",
"frameId": "frm_01HZX9T7M3Q5R8V2Y4N6C8B0KD",
"deviceId": "cr-77ghz-fwd-01",
"startedAtIso": "2026-08-03T14:22:18.512Z",
"completedAtIso": "2026-08-03T14:22:24.918Z",
"outcome": "recovered",
"routine": "boresight_rerun_v3",
"notes": null,
"triggerDrift": 0.482,
"triggerThreshold": 0.45,
"lifecycle": "completed",
"sensorType": "radar"
},
"samples": [
{ "capturedAtIso": "2026-08-03T14:20:00.114Z", "driftMetric": 0.21 },
{ "capturedAtIso": "2026-08-03T14:20:30.114Z", "driftMetric": 0.27 },
{ "capturedAtIso": "2026-08-03T14:21:00.114Z", "driftMetric": 0.34 },
{ "capturedAtIso": "2026-08-03T14:21:30.114Z", "driftMetric": 0.41 },
{ "capturedAtIso": "2026-08-03T14:22:00.114Z", "driftMetric": 0.482 }
]
}Returns `404` when the id has aged out of the recalibration-event buffer — re-poll `/api/radar/frames` or `/api/alerts` and retry. This is the wire endpoint the `latestEventId` deep-links in `/api/radar/frames` and `/api/alerts` resolve to.
Sensors
Sensors
The monitored sensor roster — id, model, channel count, firmware, install date, location, status, last calibration, latest event id.
/api/fleet/sensorsResponse
{
"items": [
{
"id": "cr-77ghz-fwd-01",
"model": "Aptiv APR-77F forward radar",
"channelCount": 32,
"firmware": "4.12.3",
"installDateIso": "2025-09-04",
"location": "Front bumper, centerline",
"status": "nominal",
"lastCalibrationIso": "2026-07-28T14:22:00.000Z",
"latestEventId": null
},
{
"id": "cr-77ghz-corner-l",
"model": "Aptiv APR-77C corner radar",
"channelCount": 32,
"firmware": "4.12.3",
"installDateIso": "2025-09-12",
"location": "Front-left fender",
"status": "watch",
"lastCalibrationIso": "2026-07-19T09:05:00.000Z",
"latestEventId": "evt_cr-77ghz-corner-l_20260725"
}
]
}Field names match the deterministic stub returned by `listMonitoredSensors()` today; the same contract will be served by the real Prisma query once the `MonitoredSensor` model lands.
Events
Events
Drift alerts the monitor surface tracks, plus the triage mutations that dismiss, escalate, or assign an alert to a teammate. Drift events are delivered via polling today; webhook push delivery is on the roadmap.
/api/alertsResponse
{
"items": [
{
"id": "alt_01HZX8K3M9N5P7R2T4V6X8Z0AB",
"frameId": "frm_01HZX8K3M9N5P7R2T4V6X8Z0AA",
"deviceId": "cr-77ghz-rear-01",
"detectedAtIso": "2026-08-03T14:18:02.477Z",
"magnitude": 0.512,
"status": "active",
"assignedTo": null,
"handledAtIso": null,
"notes": null,
"latestEventId": "evt_cr-77ghz-rear-01_20260731"
}
]
}/api/alerts/[id]Request body
{
"action": "assign",
"assignee": "Priya Subramanian"
}Response
{
"items": [
{
"id": "alt_01HZX8K3M9N5P7R2T4V6X8Z0AB",
"frameId": "frm_01HZX8K3M9N5P7R2T4V6X8Z0AA",
"deviceId": "cr-77ghz-rear-01",
"detectedAtIso": "2026-08-03T14:18:02.477Z",
"magnitude": 0.512,
"status": "assigned",
"assignedTo": "Priya Subramanian",
"handledAtIso": "2026-08-03T14:19:11.203Z",
"notes": null,
"latestEventId": "evt_cr-77ghz-rear-01_20260731"
}
]
}See Authentication → session cookie. `assignee` must name a teammate on the platform's static roster (unknown names → `400 invalid_assignee`). `dismiss` requires a `notes` reason of at least 3 characters. Returns `401` without a session — this is the demo dashboard's write surface; wire a session to use it.
Reports
Reports
Regulator-ready compliance reports — a synthesized 30-day sample for evaluation, plus the archived history for a signed-in operator.
/api/reports/sampleResponse
{
"reportId": "rep_sample_20260803",
"generatedAtIso": "2026-08-03T14:20:00.000Z",
"periodStartIso": "2026-07-04T00:00:00.000Z",
"periodEndIso": "2026-08-02T23:59:59.999Z",
"threshold": 0.45,
"sensorsCount": 4,
"driftEventsCount": 12,
"driftEventsResolvedCount": 10,
"attestation": "All monitored sensors operated below the configured drift threshold for 28 of 30 days. Two sensors tripped the recalibration routine and were recovered without operator intervention. No manual override was applied during the reporting period.",
"signOff": {
"operator": "Kaltreon Compliance Engine",
"role": "automated",
"signaturePlaceholder": "kce-signoff://rep_sample_20260803",
"generatedAtIso": "2026-08-03T14:20:00.000Z",
"reportId": "rep_sample_20260803"
}
}Best fit for an integrator evaluating the schema before wiring the archived endpoint. The full payload (sensor list, daily rollups, incidents, magnitudes) is the same shape the archived rows expose — see `/api/reports`.
/api/reportsQuery params (both optional)
{
"from": "2026-07-01",
"to": "2026-08-03"
}Response
{
"items": [
{
"id": "rep_01HZX7N2P4Q6R8T0V2W4Y6A8CE",
"generatedAtIso": "2026-08-02T17:00:00.000Z",
"periodStartIso": "2026-07-03T00:00:00.000Z",
"periodEndIso": "2026-08-01T23:59:59.999Z",
"sensorsCount": 4,
"driftEventsCount": 11,
"driftEventsResolvedCount": 10,
"fleetSlice": "forward + rear + corner L/R (4 sensors)",
"status": "Sealed"
}
]
}See Authentication → session cookie. Returns `401` without a session. Reports are fleet-wide (not user-scoped), so the gate is session presence only — no `userId` filter.
Forecast
Forecast
30-day calibration forecast per monitored sensor: linear fit, trajectory classification, and projected breach date within the horizon.
/api/forecastResponse
{
"items": [
{
"sensorId": "cr-77ghz-rear-01",
"currentDrift": 0.318,
"slopePerDay": 0.0075,
"daysUntilBreach": 18,
"projectedBreachIso": "2026-08-21",
"trajectory": "degrading",
"sampleCount": 30
},
{
"sensorId": "cr-77ghz-fwd-01",
"currentDrift": 0.198,
"slopePerDay": -0.0008,
"daysUntilBreach": null,
"projectedBreachIso": null,
"trajectory": "stable",
"sampleCount": 30
}
],
"generatedAtIso": "2026-08-03T14:20:00.000Z",
"threshold": 0.45
}