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/frameslimit accepts 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.

POST
/api/auth/sign-in/email
Public
Start a session by email + password. On success the server returns the operator profile and sets the same-origin session cookie used by every gated endpoint below.

Request 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.

POST
/api/auth/sign-out
Public
End the current session. Clears the session cookie on the response so subsequent gated endpoints return `401` until the operator signs in again.

Request 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.

GET
/api/radar/frames
Public
Poll the live drift feed the on-platform radar agent produces. Each item is a single phased-array capture with a 32-value magnitude sample, the drift metric, and the CAN-sync timestamp.

Query 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.

POST
/api/radar/recalibrate
Public
Trigger the boresight-rerun recalibration stub for a specific frame. Writes back a `RecalibrationEvent` and returns it in the same wire format the dashboard renders.

Request 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.

GET
/api/radar/events/[id]
Public
Single recalibration-event lookup. Returns the persisted `RecalibrationEvent` plus the drift-sample timeseries the recalibration ran against — the wire endpoint the `latestEventId` deep-links in `/api/radar/frames` and `/api/alerts` resolve to.

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.

GET
/api/fleet/sensors
Public
List the monitored sensor roster — every sensor the platform is currently watching, with its operational status and the id of the most recent recalibration event for the same device.

Response

{
  "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.

GET
/api/alerts
Public
List every drift alert in the queue, newest first. The server resolves `latestEventId` per row so the cell can deep-link to the drift-event detail page without a second round trip.

Response

{
  "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"
    }
  ]
}
PATCH
/api/alerts/[id]
Auth required
Mutate an alert's triage state. State machine: `dismiss` sets handledAt + reason; `escalate` flags for review; `assign` hands off to a teammate; `unassign` returns the row to the active queue.

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.

GET
/api/reports/sample
Public
Regulator-ready sample compliance report populated from 30 days of synthetic telemetry. Deterministic per UTC day so consecutive refreshes return the same payload (reproducible for the auditor).

Response

{
  "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`.

GET
/api/reports
Auth required
Archived compliance reports in reverse-chronological order. Each row carries the full `SampleReportResponse` payload so the PDF render path is typed end-to-end.

Query 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.

GET
/api/forecast
Public
30-day calibration forecast per monitored sensor: OLS linear fit, trajectory classification, and projected breach date within the horizon. Pre-sorted by `projectedBreachIso` ascending with `null`s last.

Response

{
  "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
}