RAAD platform

API reference

A private, token-authenticated API for pulling your estate into your own systems. It reads the same data the RAAD console reads, so a device that has just reported in is available here immediately. Send Authorization: Bearer <token> with every request. Every response is { data }, plus { page } on paginated lists, and errors are { error: { code, message } }.

Base URL openapi.json Get a token

The contract itself is private. openapi.json and the interactive console both require a partner or platform session, so open them in a tab where you are already signed in to the portal.

Authentication

One header, on every request.

Tokens are issued in Settings → API inside the portal. A token belongs to one tenant and carries a fixed set of scopes, so the safest pattern is one token per integration with only the scopes that integration needs. The token is shown once at creation. Store it as a secret and rotate it by issuing a new one, then revoking the old.

Send the token in the Authorization header. Query-string tokens are not accepted, and a request with no header, an expired token or a revoked token returns 401. Call /health to confirm which tenant and scopes a token is acting as before you wire anything else up.

Scopes

Three read scopes cover the whole of v1.

A token that lacks the scope an endpoint requires gets 403, not an empty list, so a permissions problem never looks like missing data. Scopes are additive and set when the token is issued.

devices:read
The device registry. Required by /devices and /devices/{id}.
tracking:read
Movement and telemetry. Required by /positions, /positions/history, /sensors and /geofences.
alerts:read
Rule fires and device events. Required by /events.

/health requires no scope beyond a valid token, which makes it the right endpoint for an uptime check or a credential test.

Errors and limits

One error shape, whatever went wrong.

200OK. The body is { data }, plus { page } on paginated lists.
400Bad request. A parameter is missing or malformed. Returned by /positions/history when deviceId, from or to is absent or unparseable.
401Unauthorized. Missing, invalid, expired or revoked token.
403Forbidden. The token is valid but lacks the scope this endpoint requires.
404Not found. The resource does not exist, or is not visible to this token. The two cases are deliberately indistinguishable, so a token cannot be used to probe for devices in another tenant.

Rate limiting

Requests are limited per token. Poll /positions rather than looping over /devices/{id}, and page through /events with a cursor rather than re-reading the head of the list. If you need a higher ceiling for a bulk export, ask before you build against it.

Pagination

Cursor-based, on /events.

List endpoints return everything the token may see. /events is the exception, because the log grows without bound. It returns newest first, up to limit rows, with page.nextCursor set when more remain. Pass that value back as cursor to continue. When nextCursor is null you have reached the end.

Store the newest id you have processed rather than a timestamp. Events are written as they are evaluated, and a device that reconnects after a gap can backfill events with older occurredAt values than ones you have already seen.

Endpoints

Eight endpoints, all read-only in v1. Select one to see its parameters, a request in three languages and a real response.

System

Confirm a token works and see what it can reach.

Returns the tenant and scopes this token acts as. Accepts any valid token, so it doubles as a health check and as the first call to make when an integration starts returning 403.

any valid token

Request

Response

Devices

The registry: what is onboarded, what state it is in, and which SIM it is on.

Every device this token may see, with its current state and the time it last reported. Returns the whole set rather than a page, so cache it and refresh on a schedule rather than per request.

devices:read

Request

Response

Notes

state is one of moving, idle, stopped, offline or nodata. nodata means the device is registered but has never reported; offline means it has reported before and has now gone quiet. protocol names the decoder handling the device, one of 267 supported.

One device with its latest status and telemetry.

devices:read404 if not visible

Path parameters

idintegerRequired
The deviceId from /devices. Not the uniqueId printed on the hardware.

Request

Response

Positions

Where everything is now, and where one thing has been.

The latest position of every device this token may see. This is the endpoint to poll for a live map: one call returns the whole estate, so you never need to fan out per device.

tracking:read

Request

Response

Notes

lastFix is when the GPS fix was taken; lastUpdate is when the platform received it. A device inside a tunnel or a container reports a fresh lastUpdate against a stale lastFix. Treat a widening gap between the two as loss of GPS rather than loss of the device. lat and lon are null until the first fix.

Movement history for one device over a time range, already segmented into trips and stops with a summary. You do not have to reconstruct journeys from raw points.

tracking:read400 on bad range404 if not visible

Query parameters

deviceIdintegerRequired
The device to report on.
fromdate-timeRequired
Start of the range, ISO 8601. Send it in UTC with a Z suffix.
todate-timeRequired
End of the range, ISO 8601. Keep ranges to a day or so per call for a busy device.

Request

Response

Sensors

Configured sensors and their latest values, per device.

Every configured sensor on every device this token may see, with the most recent reading. Values are already calibrated, so a fuel probe reads in litres rather than in raw counts.

tracking:read

Request

Response

Events

Rule fires and device events, newest first.

Everything the platform has raised against a device: rule fires and events reported by the hardware itself. Newest first, cursor-paginated. This is the feed to mirror into a ticketing system or a warehouse.

alerts:readcursor-paginated

Query parameters

limitintegerOptional
Rows per page. Defaults to 100, capped at 500.
cursorstringOptional
The page.nextCursor from the previous response. Omit it for the first page.

Request

Response

Notes

severity is one of critical, warning, info or muted. muted events are suppressed in the console but still returned here, so filter on it if you are mirroring the operator's worklist rather than the full log. page.nextCursor is null on the last page.

Geofences

The tenant's zones, with geometry you can draw.

Every zone on the tenant, with geometry already parsed. Pair it with /positions to render the same map the console shows.

tracking:read

Request

Response

Notes

Coordinates are [longitude, latitude], matching GeoJSON. That is the reverse of the lat/lon fields on a position, so check the order before you plot. radius is in metres. A polygon is not closed for you; repeat the first point if your renderer needs it.

Schemas

The four objects v1 returns, plus the error envelope.

Device

Returned by /devices and /devices/{id}.

deviceIdinteger
Stable identifier. Use this everywhere the API asks for an id.
namestring
The operator-facing name, usually the plate or asset number.
uniqueIdstring
The identifier the hardware reports, typically the IMEI.
stateenum
moving, idle, stopped, offline or nodata.
customerstring | null
The customer the device is assigned to, if any.
iccidstring | null
The SIM fitted to the device, for support and reconciliation.
protocolstring | null
The decoder handling this device.
lastUpdatedate-time | null
When the platform last heard from the device.

Position

Returned by /positions.

deviceIdinteger
The device this position belongs to.
namestring
Device name, repeated so a map does not need a second lookup.
uniqueIdstring
Hardware identifier.
lat lonnumber | null
Decimal degrees. Null until the device has had a fix.
speedKmhnumber
Ground speed at the last fix.
coursenumber
Heading in degrees, 0 to 359.
statestring
Same values as on Device.
ignitionboolean | null
Null where the device does not report ignition.
addressstring | null
Reverse-geocoded, and populated lazily. Do not depend on it being present.
lastFixdate-time | null
When the GPS fix was taken.
lastUpdatedate-time | null
When the platform received it.

Event

Returned by /events.

idstring
Sortable identifier. Store the newest you have processed to resume.
deviceId deviceNameinteger, string
The device the event fired against.
typestring
Machine-readable kind, for example fuelDrop or geofenceExit. Branch on this, not on label.
labelstring
The human-readable version shown in the console.
detailstring | null
Extra context where the rule produced any.
severityenum
critical, warning, info or muted.
latitude longitudenumber | null
Where the event fired, when the position was known.
occurredAtdate-time
When the event happened, which can be earlier than when it was written.
acknowledgedboolean
Whether an operator has cleared it in the console.

Geofence

Returned by /geofences.

idstring
Zone identifier.
namestring
The name operators see.
kindenum
circle or polygon. It determines the shape of geometry.
geometryobject
A circle is { center: [lon, lat], radius } with the radius in metres. A polygon is { points: [[lon, lat]] }.
colorstring
Hex colour used to draw the zone in the console.

Error

Returned with every 4xx status.

error.codestring
Stable, machine-readable, for example unauthorized or forbidden. Branch on this.
error.messagestring
Written for a person reading a log. The wording can change; the code will not.