TL;DR: You can bring data from your Emma Smart Trackers into your own systems in three ways: the REST API (you pull data when you need it), Webhooks (Surfact pushes each new reading to you) and MQTT (you subscribe to live values).
Email [email protected] to get an API token for your organization.
📓 Full guides and API reference: docs.surfact.com
🧭 Which option should I use?
Option | How it works | Best for |
🔄 REST API | Your system requests data when it needs it | Historical data, reports and statistics, and managing devices, device groups and alerts |
📬 Webhooks | Surfact sends each new reading to your endpoint as it arrives | Feeding fleet or transport management systems without polling |
⚡ MQTT | Your system subscribes to live values over an open connection | Live dashboards and embedded or low-bandwidth systems |
🔐 Getting access
API access is granted per organization. Email [email protected] to request a token.
Send the token in the
X-Auth-Tokenheader on every request. The same token works for the REST API and for MQTT (as the username, with an empty password).Keep the token secret, for example in a secrets manager rather than in code. If it is ever exposed, contact us and we will replace it.
Building a web or mobile app? Ask us about OAuth2.
🔄 REST API
Surfact has two REST APIs that use the same token:
Data API –
https://api.surfact.com/api/v1.6– sensor readings, statistics and raw time series.Platform API –
https://api.surfact.com/api/v2.0– devices, variables, device groups, organizations and events (alerts).
Here are the endpoints you will use most:
Action | Endpoint |
📦 List all your devices |
|
📍 Get one device |
|
🗂️ List a device's variables (and their IDs) |
|
🧭 Latest value of a variable |
|
🕒 Historical values |
|
📄 Export history as CSV | Add |
📊 One statistic (mean, min, max…) |
|
📈 Several variables at once |
|
Example: latest temperature from a tracker
Send a GET request to https://api.surfact.com/api/v2.0/devices/~{DEVICE_LABEL}/variables/~temperature with your token in the X-Auth-Token header. The response includes the variable's details and its lastValue (shortened):
{
"label": "temperature",
"lastValue": {
"value": -18.4,
"timestamp": 1788377538000,
"context": {}
}
}
Good to know
Labels vs. IDs: on the Platform API (v2.0), put
~in front of a label, e.g.~reefer-trailer-21. The Data API (v1.6) uses variable IDs, which you get from the device's variable list.Timestamps are POSIX time in milliseconds. Timestamps in seconds point to 1970 and are rejected.
Without
startorend, you get the last 100 values.Data is kept for 24 months. Requests reaching further back are rejected with HTTP 403.
Serial number: each tracker's serial number is in the device's
propertiesasdevice-serial.Location: use the
positionvariable. The coordinates are incontext.latandcontext.lng, and the value is the estimated accuracy in metres. See Device Position.
📬 Webhooks
With webhooks, Surfact sends readings to your endpoint as an HTTP request, so you don't need to poll the API. There are two kinds:
Streaming webhook – sends every reading from the devices in scope. The Surfact team sets it up for you.
Event webhook – sends a reading only when a condition is met, such as a temperature threshold being crossed. You configure it yourself as an event action (type
web-hook). See Working with Events.
Setting up a streaming webhook
Email [email protected] with:
An HTTPS endpoint reachable from the public internet
The HTTP method (usually
POST)Any headers to include, typically an
Authorizationheader or API keyWhich devices to include: all devices, an organization, or a device group
We configure the webhook, send a test reading with you on a call, and switch it live once you confirm you received it.
What you receive
You get one request per variable. A tracker that reports temperature, humidity and battery in one transmission produces three requests. Reply with any 2xx status to confirm receipt.
{
"device": {
"name": "Reefer Trailer 21",
"id": "6a7c777c1da2efbc51f62ba9",
"label": "reefer-trailer-21",
"properties": {
"device-serial": "18e-9e1-242",
"destination": "Bergen Cold Hub",
"max-temp-threshold": "-15",
"min-temp-threshold": "-22"
},
"data": {
"temperature": {
"value": "-18.4",
"context": {},
"timestamp": "1788377538000"
}
}
}
}dataalways contains exactly one key: the variable that just reported.valueandtimestampare strings. Convert them to numbers before storing.Sort readings by
timestamp, not by arrival time. Trackers that were out of coverage send their stored readings later.For
position, the coordinates are incontextaslatandlng.The payload format is fixed. If your system needs a different structure, transform it when you receive it.
⚠️ Limits to plan for
Each webhook delivers up to 4 requests per second. Requests above that are dropped, not queued.
Every variable on an in-scope device is sent, and an Emma tracker typically reports 10+ variables per transmission. Filter on your side, and talk to us about scoping, for example one webhook per device group.
Don't rely on the webhook as your only copy of the data. Run regular catch-up requests against the REST API to fill any gaps from dropped requests or downtime on your side.
⚡ MQTT
Connect to the broker at api.surfact.com using your API token as the username and an empty password. Use TLS in production.
Connection | Port |
MQTT with TLS | 8883 |
MQTT over WebSockets with TLS | 8084 |
TLS requires the Surfact certificate. Topics, wildcards and the certificate link are in the MQTT guides.
✅ Ready to connect?
Email [email protected] to get your API token or to set up a webhook. For every endpoint, parameter and example, see docs.surfact.com.
