For the complete documentation index, see llms.txt. This page is also available as Markdown.

Terra -> Your backend

Set up and manage a consumer connection to the Terra WebSocket service to receive real-time health data.

This guide will walk you through the essential steps, from connecting and authenticating to managing heartbeats and receiving data.

Setting up a Consumer Connection

A consumer connection delivers your developer ID's real-time data stream. To set up your consumer connection to the Terra WebSocket service, follow the steps below.

WebSocket endpoint: wss://ws.tryterra.co/connect


Connecting to the WebSocket

Once you open a WebSocket connection to the server, you will immediately receive an Op 2 HELLO payload. This payload contains the heartbeat_interval value (in milliseconds), which the client will use to maintain the connection.

Example payload:

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

After receiving this payload, the client must start sending heartbeat messages, as described below.


Heartbeating

To keep the WebSocket connection alive, the client needs to send regular heartbeats.

This lets the server know the connection is still active and waiting for data.

To send a heartbeat, send the following payload:

You'll always receive the following response (acknowledging your heartbeat):


Authenticating the Connection

Once heartbeating is set up, the client must authenticate the connection by sending an IDENTIFY payload containing a token.

IDENTIFY payload:

The type field specifies the connection type:

Type
Name
Description

0

USER

Producer connection (mobile SDKs sending data). Uses a token from POST /auth/user.

1

DEVELOPER

Consumer connection (your backend receiving data). Uses a token from POST /auth/developer.

For consumer connections (this guide), use type: 1 with a developer token.

Tokens are single-use. Each token is deleted from the server after a successful IDENTIFY. If your connection drops, you must generate a new token before reconnecting.

When authentication is successful, the server will respond with an Op 4 READY message:


Listening for Data Updates

Once the connection is established and authenticated, data from your connected users will be streamed to you in real time.

When new data is available, an Op 5 DISPATCH payload is sent:

Each dispatch contains:

  • op: Opcode 5 (DISPATCH).

  • uid: The Terra user ID of the user whose device produced this data.

  • t: The data type (e.g., "HEART_RATE", "STEPS", "ACCELERATION", "ECG", "HRV", "CALORIES", "LOCATION", "GYROSCOPE", etc.).

  • seq: A sparse, time-ordered cursor — values generally increase over time, but gaps between consecutive values are normal and do not indicate lost data (treat it as a cursor, not a counter). Two readings produced in the same instant may arrive in either order. Use it to order DISPATCHes and as the after bound for replay.

  • d: The data payload:

    • ts: ISO 8601 timestamp of the reading.

    • val: Scalar value (e.g., heart rate BPM, step count). Present for single-value types.

    • d: Array of doubles (e.g., [x, y, z] for accelerometer/gyroscope, or [lat, lng] for location). Present for multi-axis types.


Requesting missed Data

If your connection drops and you miss some data, you can request it using the REPLAY command once you reconnect.

To backfill the gap on reconnect:

  1. Re-IDENTIFY, then wait for the first live DISPATCH and note its seq (call it firstLive).

  2. Send a REPLAY with after = the last seq you processed before the drop, and before = firstLive.

  3. Process the replayed DISPATCHes (they arrive as op 5 payloads), then resume handling live data.

If no live DISPATCH has arrived yet, there's nothing to backfill — REPLAY once one does.

REPLAY Command (Op 7)

  • after (required): Replay messages with sequence numbers greater than this value — typically the last seq you successfully processed before disconnecting.

  • before (required): Replay messages with sequence numbers less than this value. Set it to the seq of the first live DISPATCH you receive after reconnecting, so you backfill exactly the gap. Both bounds are required — a REPLAY without before returns no messages.

Bounds are exclusiveafter: 28, before: 43 replays sequence numbers 29 through 42.

Replayed messages arrive as standard DISPATCH (op 5) payloads.

Replay reads from Terra's data warehouse, so a payload becomes replayable a few seconds after it is delivered live. If a REPLAY returns fewer messages than you expect, wait a moment and request it again. There is currently no retention limit on replayable data, though this may change in future.


Error Close Codes

The server may close your WebSocket connection with one of the following custom close codes:

Code
Reason
What to do

4000

Identify expected but was not received

Send IDENTIFY within 15 seconds of connecting

4001

Improper token has been passed

Token is invalid or expired — generate a new one

4002

Consumer session limit reached

Another consumer session is already active for your developer ID (current cap) — close it first

4003

Multiple IDENTIFY payloads received

Don't send IDENTIFY more than once per connection

4004

Invalid opcode was received

You sent an opcode the server doesn't recognize, or one not valid for your session type (e.g. SUBMIT on a consumer)

4005

Heartbeat expected but was not received

Send heartbeats within the heartbeat_interval window

The server may also close with the standard WebSocket codes 1000 (normal closure), 1003 (a malformed frame was received), or 1011 (internal server error).

For reconnect logic: 4000, 4003, 4004, and 1003 signal a client-side bug — fix your client rather than reconnecting, since a blind retry just loops on the same error. The rest are safe to reconnect after the remedy above (for 4001, always mint a fresh token; for 4002, close the other session first).


Opcode Reference

Opcode
Name
Direction
Description

0

HEARTBEAT

Client → Server

Keep-alive ping

1

HEARTBEAT_ACK

Server → Client

Keep-alive acknowledgement

2

HELLO

Server → Client

Sent on connection, contains heartbeat_interval

3

IDENTIFY

Client → Server

Authentication with token and connection type

4

READY

Server → Client

Authentication successful

5

DISPATCH

Server → Client

Real-time data payload

6

SUBMIT

Client → Server

Data submission (producer connections only)

7

REPLAY

Client → Server

Request missed data by sequence range

Last updated

Was this helpful?