📘

API Base URLs

REST Endpoints: https://ws.tryterra.co
Websocket connection endpoint: wss://ws.tryterra.co/connect

Overview

See Integrations for a full list of SDK-based integrations which support websockets.

The Terra websocket API provides a method of sending to and receiving from real-time data streams to allow almost instant access to wearable data as it is being recorded. Many of the various Terra SDKs have out-of-the-box support for the streaming of data to the websocket service.

See for details on how to write your own consumer connection in order to receive data from the websocket service.


Connecting

Upon opening a websocket connection to the server, you will immediately be sent an Op 2 HELLO payload containing the heartbeat interval (in milliseconds) that the client should use when sending heartbeat messages to the server.

{
  "op": 2,
  "d": {
    "heartbeat_interval": 40000
  }
}

Once this payload has been received by the client, it is expected to begin heartbeating. See below.


Heartbeating

Heartbeating is effectively a PING/PONG chain which is communicated to the server over a regular interval to inform the server that the connection is still in use.

The first heartbeat should be sent after heartbeat_interval * jitter milliseconds, where jitter is a random value between 0.1 and 1.0. After the initial heartbeat is sent, the client should continue heartbeating at the precise interval given in the HELLO payload. You do not need to account for network latency as the server gives the client some leeway either side of the interval before closing a potentially zombied connection.

Whenever the server receives an Op 0 HEARTBEAT, it will reply with an Op 1 HEARTBEAT_ACK message, indicating that the heartbeat was successfully received. If the client does not receive this response, the connection should be closed and a new connection established.

{
  "op" 0
}
{
  "op": 1
}

Authenticating

Authenticating the websocket connection is done through sending an IDENTIFY payload through the connection which contains a token generated by hitting the appropriate token generation endpoint.

Identify Data Schema

Field Name

Type

Description

token

String

Authentication token generated from the appropriate endpoint.

type

Integer

Connection type. Value from the IdentifyType enum.

IdentifyType Enum

Name

Value

User (Producer)

0

Developer (Consumer)

1

{
    "op": 3,
    "d": {
        "token": "OTYwNWFi5ZWQMTAxMjg0Y2Qw.gzrPzZcS3Gy8QDOxbiPRwu30PTB3VxW0eE",
        "type": 0
    }
}

If identification is successful, the server will respond with an Op 4 READY payload:

{
    "op": 4
}

At this point, the connection is ready to send/receive data to/from the server.


Websocket Commands

There are two commands you can send through the websocket connection other than those used for authentication and heartbeating. These are Op 6 SUBMIT and Op 7 REPLAY.

The SUBMIT command is used by a producer client connection to send data to the server for dispatch to consumers.

The REPLAY command is used by a consumer client to request the re-sending of payloads between the given seq lower (and optionally upper) bounds. This is useful when the websocket connection may have closed erroneously so the consumer client missed out on a couple of payloads during that period.

If a producer connection attempts to use the SUBMIT command (and likewise if a consumer attempts to use the REPLAY command) the connection will be immediately closed by the server with a close code of 4004.

Replay Data Object Structure

Field Name

Type

Description

after

Long

Replay all payloads after this seq value

before?

Long

Optional upper bound for replaying of payloads

Example Payloads

{
  "op": 7,
  "d": {
    "after": 28,
    "before": 43
  }
}
{
  "op": 6,
  "d": {...},
  "t": "HEART_RATE"
}

Receiving Data

Data can only be received through consumer connections. When new data is available, an Op 5 DISPATCH payload will be send through the websocket connection containing all information available for the event.

All DISPATCH events will always contains a uid key, which will contain the Terra user ID of the user that the data belongs to. It will also contain a t key, which will contain the event type, i.e. the type of data that the event represents (e.g. HEART_RATE etc). The d sub-object will contain the actual timestamps and values for the data.

{
  "op": 5,
  "d": {
    "t": "2022-05-04T10:26:11.268507+01:00",
    "val": 95
  },
  "uid": "8e864e3a-979a-4d04-b4e9-b6d020f20ba0",
  "seq": 73,
  "t": "HEART_RATE"
}