Theme
IoT contract
N2E ingests telemetry through a dedicated iot service. This page is the contract devices and integrators must follow.
Endpoints
| Path | Method | Transport | Auth | Purpose |
|---|---|---|---|---|
/iot/telemetry | — | WebSocket (streamIn) | bearer | Long-lived stream — devices push telemetry frames continuously. |
/iot/trip-end | POST | HTTPS | bearer | One-shot event when a trip completes (includes video metadata). |
/iot/telemetry/emit | POST | HTTPS | bearer | Demo helper — emit synthetic telemetry for a set of vehicleIds. |
/iot/trip-end/emit | POST | HTTPS | bearer | Demo helper — emit a synthetic trip-end event for a vehicle. |
All endpoints require a valid session token (Authorization header Bearer <token> from /auth/signin). The two emit* endpoints are intended for demos and integration testing only.
Once published the events fan out via Encore PubSub topics (telemetryTopic, tripEndTopic) into the telemetry-store service for persistence and into the predictive-maintenance service for AI risk analysis.
Telemetry payload
The shape devices must send on the /iot/telemetry stream:
ts
interface TelemetryEvent {
vehicle_id: string; // matches the vehicle's `vehicleId` from /truck
timestamp: string; // ISO-8601 with timezone, e.g. "2026-05-19T08:32:11.500Z"
powertrain: {
engine_rpm: number; // revolutions per minute
engine_torque_pct: number; // 0–100, percent of max torque
fuel_rate_lph: number; // litres per hour (instantaneous)
coolant_temp_c: number; // °C
oil_pressure_kpa: number; // kPa
boost_pressure_kpa: number;// kPa
nox_ppm: number; // parts per million (after-treatment NOx)
};
speed_kmh: number; // current ground speed, km/h
odometer_km: number; // total distance, km, monotonically increasing
engine_hours: number; // total engine on-time, hours
coordinates: {
lat: number; // WGS-84 decimal degrees
long: number; // WGS-84 decimal degrees (note: field is `long`, not `lng`)
};
}Field naming
The platform uses snake_case on the wire and long (not lng/longitude). Stick to it exactly — the predictive-maintenance rules and storage schema match these names.
Example frame
json
{
"vehicle_id": "KR-SEED-TRK-01",
"timestamp": "2026-05-19T08:32:11.500Z",
"powertrain": {
"engine_rpm": 1850,
"engine_torque_pct": 62,
"fuel_rate_lph": 24.3,
"coolant_temp_c": 88.4,
"oil_pressure_kpa": 410,
"boost_pressure_kpa": 175,
"nox_ppm": 18
},
"speed_kmh": 78.2,
"odometer_km": 142307.1,
"engine_hours": 8423.5,
"coordinates": { "lat": 37.5665, "long": 126.9780 }
}Trip-end payload
Sent once per completed trip via REST:
ts
interface TripEndEvent {
vehicle_id: string;
trip_id: string; // unique id generated by the device or dispatch system
end_timestamp: string; // ISO-8601
video_metadata: {
file_size_gb: number;
duration_minutes: number;
};
}Example
bash
curl -X POST https://<gateway>/iot/trip-end \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"vehicle_id": "KR-SEED-TRK-01",
"trip_id": "trip-2026-05-19-0001",
"end_timestamp": "2026-05-19T14:05:00Z",
"video_metadata": { "file_size_gb": 4.7, "duration_minutes": 312 }
}'Cadence & batching
| Signal | Recommended rate |
|---|---|
| Idle / parked | 1 sample / 30 s |
| Moving (urban) | 1 sample / 1 s |
| Moving (highway) | 1 sample / 2 s |
| Critical event (hard brake, fault) | burst at 10 Hz for 5 s |
The WebSocket endpoint accepts back-pressure; the device may buffer locally during connectivity loss and flush on reconnect. Use monotonically increasing timestamp values.
Authentication
Each device gets a service-account user with role driver (or a dedicated device role you create). The flow:
- Device authenticates once with
/auth/signinusing its email + password. - Stores the returned bearer token (HttpOnly cookie or local secure storage on RN).
- Sends
Authorization: Bearer <token>on the WebSocket upgrade and on every/iot/trip-endPOST. - On
401, re-runs sign-in and retries.
Best practice
Issue per-device credentials (one user per VIN) rather than a shared key. This keeps audit logs meaningful and lets you revoke a single device without taking the whole fleet offline.
Validation & errors
| Code | Meaning | Action |
|---|---|---|
200 / OK frame | Accepted | continue |
400 | Schema mismatch | log + drop frame |
401 | Token expired | refresh and reconnect |
409 | Stale timestamp (older than last) | drop frame |
429 | Rate limited | back off, then retry |
5xx | Upstream issue | buffer locally, retry with jitter |
The server does not ACK every frame — assume success unless the connection drops. On reconnect, replay anything you buffered since the last successful flush.
Downstream effects
When a frame lands in telemetryTopic the following happens:
- telemetry-store writes a row in
telemetry_records. - predictive-maintenance applies its rule set (NOx, coolant, oil, fuel rate, RPM bands) and may emit alerts.
- notification fans critical alerts to the operator UI and (if configured) email/SMS.
- dashboard widgets re-render with the latest summary.
The end-to-end latency from device to operator UI is sub-second on a healthy connection.
See also
- React / React Native client — drop-in client for in-cab apps.
- OEM telematics mapping — bridge Mercedes-Benz, IVECO ON and Caterpillar VisionLink to this contract.