Live Data API
The Live Data API can be used to receive live streamed boat data and is different from the GraphQL API.
Protocol
The Live Data API uses the WebSocket protocol exclusively. All messages (requests and responses) are send as JSON encoded objects.
Authentication
The Live Data API uses the same API tokens as the GraphQL API. For instructions on how to retrieve an API key, see Authentication. A valid API key must be used when subscribing to data (see below), and will only allow subscribing to data of boats that the user owning the API key has permissions for.
Endpoints
Njord operates multiple live data endpoints around the globe to ensure low latency between the boat and the live data endpoint. At the time of writing this, there are 3 endpoints, in Frankfurt (Germany), Northern Virginia (USA) and Sydney (Australia).
When set up correctly, boats will send live data to the nearest endpoint automatically. In order to receive live data via the API, you need to connect to the appropriate endpoint. There are two strategies that you can use.
Retrieve a Boat's Endpoint
To retrieve the live data endpoint WebSocket URL for a specific boat, access the liveDataStatus.WebSocketUrl2
field of that boat in any GraphQL query. For example, the following GraphQL query will return all boats that you have access to that have sent live data at some point, and their WebSocket URLs.
query {
listBoats(filter: { hasLiveDataAfter: "2020-01-01T00:00Z" }) {
boat {
key
name
liveDataStatus {
webSocketUrl2
}
}
}
}
The response will look like:
{
"data": {
"listBoats": [
{
"boat": {
"key": "Boat_abc",
"name": "Live Boat",
"liveDataStatus": {
"websocketUrl2": "wss://live-eu-central-1.prod.sailnjord.com:5002/"
}
}
}
]
}
}
Connect to All Endpoints
You can also create separate connections to all live data endpoints at the same time. The advantage of this approach is that you will still receive data when a boat suddenly starts sending data to a different live data endpoint than the one you originally connected to. This can happen if the boat moves physically, or if there are changes in the boat's internet connection. You will need to subscribe to the desired boats on each connection / endpoint separately.
To retrieve all live data endpoints and their WebSocket URLs, use the following GraphQL query:
query {
streamingGateways(onlyOnline: true) {
webSocketUrl2
}
}
The response will look like:
{
"data": {
"streamingGateways": [
{
"websocketUrl2": "wss://live-ap-southeast-2.prod.sailnjord.com:5002/"
},
{
"websocketUrl2": "wss://live-eu-central-1.prod.sailnjord.com:5002/"
},
{
"websocketUrl2": "wss://live-us-east-1.prod.sailnjord.com:5002/"
}
]
}
}
WebSocket URLs for each endpoint are designed to be stable, and we add or remove endpoints very infrequently.
Heartbeat - Ping/Pong
After connecting to the WebSocket URL, it is the client's responsibility to send a ping
message once at least every 15 minutes. A shorter interval like 1 minute is recommended. If the server doesn't receive a ping
message within that time interval, it may terminate the WebSocket connection.
A ping
message is a JSON-formatted object like the following, where ping
and requestId
values are arbitrarily chosen by the client.
{ "requestId": "uuid-xxx-yyy-zzz", "ping": 1 }
The server will always respond with a pong
message immediately, repeating both values. If you don't receive a pong
message, consider reconnecting.
{ "requestId": "uuid-xxx-yyy-zzz", "pong": 1 }
Receiving Live Data
Send a subscription request, a JSON-formatted object like the following. The requestId
value is optional and is arbitrarily chosen by the client, for authorization
, insert a valid API token.
You can subscribe to:
- one or more boats using the
boatKeys
field (array of boat keys), and/or - one or more wind stations using the
windStationKeys
field (array of wind station keys), and/or - one or more data sources using the
dataSourceKeys
field (array of data source keys)
{
"requestId": "uuid-xxx-yyy-zzz",
"subscriptionRequest": {
"authorization": "...",
"boatKeys": ["Boat_123", "Boat_456"]
}
}
If the subscription was successful, the server will respond with:
{
"requestId": "uuid-xxx-yyy-zzz",
"subscriptionResponse": {
"boatKeys": ["Boat_123", "Boat_456"],
"subscribed": true
}
}
Else, the response will look like this:
{
"requestId": "uuid-xxx-yyy-zzz",
"subscriptionResponse": {
"boatKeys": ["Boat_123", "Boat_456"],
"subscribed": false,
"error": "Permission denied"
}
}
Whenever live data is received from the boat, and until unsubscribed, the server will respond with a data message like this (sourceTimestamp
is the time in UNIX epoch/milliseconds at which the the data originated at the source, and gatewayTimestamp
is the timestamp when it was received by the Njord live data endpoint):
{
"boatKey": "Boat_123",
"sourceTimestamp": 1738866164000,
"gatewayTimestamp": 1738866164100,
"records": {
"BoatSpeed": 8.2,
"Heading": 270.0
}
}
To unsubscribe, send a request like:
{
"requestId": "uuid-xxx-yyy-zzz",
"unsubscribeRequest": {
"boatKeys": ["Boat_123", "Boat_456"]
}
}
Sending Live Data
Sending live data to a live data endpoint does not use the Live Data API, as application-specific protocols are being used (NMEA 0183 and Expedition format via UDP, Igtimi data via their own protocol).
If you are interested in sending live data using a WebSocket connection in addition to receiving it via a WebSocket connection as described above, contact us.