← Back to Scalar (REST API)

SignalR hub contract — DSP Fleet

This document describes WebSocket/SignalR behavior. It is served as static HTML at /docs/signalr.html and linked from the Scalar API reference header.

Connecting & authentication

Build the hub URL with the same host you use for HTTPS (or HTTP in dev). The JWT access token (user or device) is passed on the query string so the WebSocket handshake can authenticate:

wss://YOUR_HOST/hubs/fleet?access_token=YOUR_JWT
wss://YOUR_HOST/hubs/pairing?access_token=OPTIONAL

PairingHub is [AllowAnonymous]; access_token is optional there. FleetHub requires a valid JWT (user or device) unless noted below.

Groups

After connect, the server adds connections to groups automatically:

GroupMembers
account:{accountId}All FleetHub connections whose JWT has that AccountId (web dashboards and devices).
device:{deviceId}FleetHub connections whose JWT includes DeviceId matching that device.

FleetHub — /hubs/fleet

Method names below are C# hub names. JSON clients often use camelCase (reportLocation); negotiate with your SignalR client defaults.

Client → server (invoke)

MethodAuthParametersReturns / behavior
RequestTokenRefresh AllowAnonymous string refreshToken AuthResponse? — same shape as HTTP refresh; lets web UI refresh without reconnecting if connection still alive.
ReportLocation Device JWT double lat, double lon, double? batteryPercent, string? appVersion, string? appLanguage Updates in-memory location store; persists last lat/lon to DB; may notify account: group via DeviceUpdated.
ReportDeviceInfo Device JWT double? batteryPercent, string? appVersion, string? appLanguage Phone battery + app metadata before GPS fix; notifies dashboard.
MessageReceived Device JWT string messageId Stops server resend loop for that message; notifies web DeviceMessageReceived + DeviceMessageAcknowledged.
MessageSeen Device JWT string messageId Marks seen; broadcasts DeviceMessageSeen to account group.
MessageResponse Device JWT string messageId, string responseText Persists reply to DeviceMessages; broadcasts DeviceMessageResponse and DeviceMessageSeen.

Server → client (callbacks on your connection)

Subscribe with your client’s On handler using these exact event names:

EventTypical targetArguments (order)
DeviceUpdated account:* deviceId (uint), isConnected, lastLat, lastLon, lastLocationAt, batteryLevelPercent, appVersion, appLanguage, appInfoAt, syncState
ReceiveMessage device:{id} messageId (string), body (string), displaySeconds (int)
DeviceMessageReceived account:* deviceId, messageId
DeviceMessageAcknowledged account:* deviceId, messageId — legacy alias for receipt
DeviceMessageSeen account:* deviceId, messageId
DeviceMessageResponse account:* deviceId, messageId, responseText, respondedAt (DateTime)
ZoneSync Single connection or devices List of zone DTOs (full list) — sent to a device on connect
ZoneAdded Account + devices Zone DTO
ZoneDeleted Account + devices zoneId (int)
StartFastLocation device:{id} intervalSeconds (int), durationSeconds (int)
StopFastLocation device:{id} (no args)
RequestHistorySync device:{id} hours (int) — device should POST /api/devices/history-sync with cached samples
RescueSessionStarted account:{id} + each device:{id} in the pair Object: sessionId, rescueeDeviceId, rescuerDeviceId, startedUtc; device-targeted sends also include yourRole (rescuee|rescuer), peerDeviceId, peerDisplayName
RescuePeerLocation device:{peerId} only Object: peerDeviceId, lat, lon, atUtc
RescueSessionEnded account:{id} + both devices Object: sessionId, endReason (completed | cancelled_by_dispatcher)

PairingHub — /hubs/pairing

Anonymous. Used while the app shows a pairing code (or before POST /api/devices/by-code completes).

Client → server

MethodParametersReturns
RegisterConnectionForPairing string deviceGuid (32 hex, hyphens optional) bool — links this SignalR connection to the pending row created by POST /api/device/init
RequestPairingCode (optional cancellation) string — new 6-character code; creates PendingDevice tied to this connection

Server → client

EventWhenPayload
DeviceBound After web binds device via POST /api/devices/by-code (or debug trigger) Object: deviceId, accountId, signalREndpoint, name, identifier, accessToken, speedUnit, country, accountTimezone, periodicAirplaneModeOff

Related REST endpoints

Generated for DSP Fleet API. Keep in sync with Hubs/FleetHub.cs, Hubs/PairingHub.cs, ZonePushService, and DeviceMessageService.