Blackline Real-Time Event Streaming API v1

Blackline Real-Time Event Streaming API allows you to get live events in real-time.

Overview

This API provides WebSocket-based streaming of real-time events from Blackline Safety devices. Connect once and receive live updates as events occur.

Supported Event Types

  • Sensor Readings: Real-time sensor data as devices emit measurements
  • Device Presence: Online/offline status updates for devices
  • Device Events: Safety events such as falls, no motion, emergencies, or low battery
  • Text Message Read Receipts: Acknowledgements emitted when a device user reads a text message
  • Location: Device location updates including GPS and beacon sources

Key Features

  • Topic-based subscriptions (sensor_readings, device_presence, device_event, text_message, location)
  • Automatic device authorization based on organization access
  • Real-time event delivery with no message buffering
  • Echo endpoint for connection testing

Authentication

Authenticate each WebSocket connection by passing a bearer token in the Sec-WebSocket-Protocol header during the handshake. Browser WebSocket APIs do not allow custom headers on the upgrade request, and the subprotocol field is the only client-settable value available.

Token source: Obtain a bearer token from Connect V4 using the standard OAuth 2.0 client credentials flow. The same token is valid for this streaming API.

Server handshake contract: The server echoes the supplied subprotocol value back in the handshake response. Reverse proxies and load balancers in front of the streaming endpoint must preserve the Sec-WebSocket-Protocol header on both the request and response.

Example (Browser, JavaScript):

// 1. Obtain a bearer token from Connect V4
const tokenResponse = await fetch("https://api.blacklinesafety.com/live/v4/oauth2/token", {
  method: "POST",
  headers: {
    "x-api-key": "<your-api-key>",
    "Content-Type": "application/x-www-form-urlencoded",
  },
  body: new URLSearchParams({
    grant_type: "client_credentials",
    client_id: "<your-client-id>",
    client_secret: "<your-client-secret>",
  }),
});
const { access_token } = await tokenResponse.json();

// 2. Open the WebSocket connection, passing the token as the subprotocol
const ws = new WebSocket("wss://streaming.blacklinesafety.com/v1/ws", access_token);

// 3. Register for topics once the connection is open
const orgId = 123;
const topics = ["sensor_readings", "device_presence", "text_message", "device_event", "location"];
ws.addEventListener("open", () => {
  for (const topic of topics) {
    ws.send(JSON.stringify({
      type: "register",
      orgId,
      token: access_token,
      data: { topic },
    }));
  }
});

// 4. Handle incoming events
ws.addEventListener("message", (event) => {
  const msg = JSON.parse(event.data);
  console.log(`I received ${JSON.stringify(msg)} from ${msg.meta.topic}`);
});

Example (Python, websockets + requests):

import asyncio
import json
import requests
import websockets

async def main():
    # 1. Obtain a bearer token from Connect V4
    token_response = requests.post(
        "https://api.blacklinesafety.com/live/v4/oauth2/token",
        headers={"x-api-key": "<your-api-key>"},
        data={
            "grant_type": "client_credentials",
            "client_id": "<your-client-id>",
            "client_secret": "<your-client-secret>",
        },
    )
    access_token = token_response.json()["access_token"]

    # 2. Open the WebSocket connection, passing the token as the subprotocol
    async with websockets.connect(
        "wss://streaming.blacklinesafety.com/v1/ws",
        subprotocols=[access_token],
    ) as ws:
        # 3. Register for topics
        org_id = 123
        for topic in ["sensor_readings", "device_presence", "text_message", "device_event", "location"]:
            await ws.send(json.dumps({
                "type": "register",
                "orgId": org_id,
                "token": access_token,
                "data": {"topic": topic},
            }))

        # 4. Handle incoming events
        async for raw in ws:
            msg = json.loads(raw)
            print(f"I received {msg} from {msg['meta']['topic']}")

asyncio.run(main())

Failure modes: Missing or invalid tokens cause the upgrade to fail with 401 Unauthorized.

Important Implementation Notes

  • No message buffering: Clients only receive messages generated AFTER successful registration. Historical messages are not sent. You must use the companion REST API to query most recent state of devices.
  • Automatic disconnection: When a client de-registers from all event types, the connection is automatically closed.
  • Organization-scoped access: Registering to an event type subscribes you to all devices you have access to within the specified organization (this also supports all client organizations with active relationship).
  • Server-side authorization: Device access is determined server-side based on your token. You cannot specify individual devices to subscribe to.

Servers

  • wss://streaming.blacklinesafety.com/v1/wswssproduction-na

    Production server - North America

    Security:
    • HTTP API key
      • Name: Sec-WebSocket-Protocol
      • In: header

      Bearer token obtained from Connect V4, passed as the WebSocket subprotocol during the handshake. The server echoes this value back in the handshake response.

  • wss://eu.streaming.blacklinesafety.com/v1/wswssproduction-eu

    Production server - Europe

    Security:
    • HTTP API key
      • Name: Sec-WebSocket-Protocol
      • In: header

      Bearer token obtained from Connect V4, passed as the WebSocket subprotocol during the handshake. The server echoes this value back in the handshake response.

  • wss://uae.streaming.blacklinesafety.com/v1/wswssproduction-uae

    Production server - United Arab Emirates

    Security:
    • HTTP API key
      • Name: Sec-WebSocket-Protocol
      • In: header

      Bearer token obtained from Connect V4, passed as the WebSocket subprotocol during the handshake. The server echoes this value back in the handshake response.

Operations

  • SEND /

    Register to receive events from a specific topic for all authorized devices in specified organization

    Operation IDregister

    Accepts the following message:

    Registration request payloadregisterMessage

    Registration request payload, describing the topic which the client wants to register for

    Message IDregisterMessage

    Sent by the client to subscribe to a topic within a specific organization. Once registered, the client receives events on that topic for every device the authenticated user is authorized to access in the given organization. Individual devices cannot be targeted; device access is determined server-side from the token.

    Send a separate register message for each topic the client wants to receive. The token field must match the token used during the WebSocket handshake.

    When at least one device is successfully registered, the server replies with a success message that lists the device IDs the client is now subscribed to and any devices that failed to register. When every device fails to register, the server replies with an error message and closes the connection. When the registration request itself is invalid (bad topic, missing fields), the server replies with an error message and keeps the connection open so the client can retry.

    Only events generated after a successful registration are delivered. No historical or buffered events are sent; use the companion REST API to fetch current state.

    object

    Examples

  • SEND /

    Unregister from a specific topic. If topic is null, disconnects the client entirely.

    Operation IDderegister

    Accepts the following message:

    Deregistration request payloadderegisterMessage

    Deregistration request to stop receiving events from a specific topic

    Message IDderegisterMessage

    Sent by the client to stop receiving events on a previously registered topic. After deregistration the client no longer receives events for that topic on this connection. The server does not send a success or error response to a deregistration request; the effect is silent.

    Setting data.topic to null deregisters the client from every topic it is currently subscribed to. Once a client has no remaining subscriptions (either through a null deregister or after the last individual topic is removed), the server closes the WebSocket connection. This is the recommended way to cleanly disconnect.

    Deregistering from a topic the client is not subscribed to is a no-op.

    object

    Examples

  • SEND /

    Send an echo message to verify the WebSocket is working

    Operation IDecho

    Accepts the following message:

    Echo requestechoRequest

    Echo request to verify WebSocket functionality

    Message IDechoRequest

    Sent by the client to verify the WebSocket connection is alive. The server replies with an echoResponse carrying the same data value.

    Echo messages do not require any topic registration and can be sent at any point during the connection's lifetime.

    object

    Examples

  • RECEIVE /

    Success response for registration/deregistration requests

    Operation IDonSuccess

    Accepts the following message:

    Success response payloadsuccessMessage

    Success response payload sent when operations complete successfully

    Message IDsuccessMessage

    Delivered by the server in response to a register request that succeeded for at least one device. The data.message field is a human-readable summary describing how many devices were successfully registered and which devices, if any, failed to register.

    A registration that succeeds for some devices but fails for others is still reported as a success; the failed device IDs are listed inside data.message. A registration where every device fails is reported as an error, not as a success.

    Deregistration requests and echo requests do not produce a success message.

    The content of data.message is intended for logging and diagnostics and should not be parsed for programmatic logic.

    object

    Examples

  • RECEIVE /

    Error response for failed requests

    Operation IDonError

    Accepts the following message:

    Error response payloaderrorMessage

    Error response payload sent when operations fail

    Message IDerrorMessage

    Delivered by the server when a client request cannot be processed. Common triggers include malformed JSON, failed validation of a register or de-register payload, unknown message types, and registration attempts where every device fails to register.

    The data.msg field is a human-readable explanation of the failure and is intended for logging and operator visibility, not for programmatic parsing.

    Most errors are recoverable: the server keeps the connection open after sending an error message, and the client may continue to send other requests. The connection is closed immediately after the error in only one case: when a register request fails for every authorized device in the organization.

    object

    Examples

  • RECEIVE /

    Echo response with timing information

    Operation IDonEcho

    Accepts the following message:

    Echo responseechoResponse

    Echo response from server for connection health check

    Message IDechoResponse

    Delivered in response to an echoRequest. Used to verify the WebSocket connection is alive.

    object

    Examples

  • RECEIVE /

    Sensor readings event, emitted by a device

    Operation IDonDeviceSensorReadings

    Accepts the following message:

    Sensor readings event, emitted by a devicedeviceSensorReadings

    Sensor reading values from a device. Each message can include multiple sensor readings, as devices have multiple sensors.

    Message IDdeviceSensorReadings

    Delivered to clients registered to the sensor_readings topic when a device publishes new sensor measurements.

    Sensor readings are forwarded to subscribers as they are received from the upstream event pipeline; they are not aggregated, sampled, or deduplicated by the streaming API. Clients that need historical data or roll-ups should use the companion REST API.

    object

    Examples

  • RECEIVE /

    Device presence status update event

    Operation IDonDevicePresence

    Accepts the following message:

    Device presence eventdevicePresence

    Device presence status updates including online/offline state and the trigger that caused the change.

    Message IDdevicePresence

    Delivered to clients registered to the device_presence topic when a device's presence state changes.

    The eventTimestamp field reflects when the presence change actually occurred, not when the message was delivered. Clients should order presence events by eventTimestamp, not by receive time.

    object

    Examples

  • RECEIVE /

    Read receipt emitted when a device acknowledges a text message

    Operation IDonTextMessageReadReceipt

    Accepts the following message:

    Text message read receipttextMessageReadReceipt

    A read receipt emitted when a device acknowledges a text message

    Message IDtextMessageReadReceipt

    Delivered to clients registered to the text_message topic when a device user reads a text message previously sent to the device.

    Only read receipts are delivered on this topic. Outbound text message sends and non-read delivery events are not part of this stream and must be handled through the messaging REST API.

    Read receipts carry meta.type of text_message_read_receipt.

    object

    Examples

  • RECEIVE /

    Non-sensor event for a device

    Operation IDonDeviceEvent

    Accepts the following message:

    Event, emitted by a devicedeviceEvent

    Safety events emitted by a device, such as falls, no motion, emergencies, or low battery.

    Message IDdeviceEvent

    Delivered to clients registered to the device_event topic when a device reports a safety alert. Current alert types are:

    • EMERGENCY
    • FALL_DETECTED
    • NO_MOTION
    • SILENT_EMERGENCY
    • DEVICE_TIPPED_OVER
    • PUMP_BLOCK_DETECTED
    • MISSED_CHECK_IN
    • LOW_BATTERY
    • TWA_ALERT_DETECTED
    • STEL_ALERT_DETECTED

    New alert types may be added over time; clients should tolerate unknown values without failing.

    object

    Examples

  • RECEIVE /

    Device location update with all location sources

    Operation IDonDeviceLocation

    Accepts the following message:

    Device location eventdeviceLocation

    Location update for a device, including all location sources and the selected best location.

    Message IDdeviceLocation

    Delivered to clients registered to the location topic when a device publishes a new location update.

    Each message contains the full array of location entries (GPS and/or beacon) from the source event, along with a bestLocationIndex indicating which entry was selected as the best location. Clients that only need the best location can index directly into the array; clients that need all location sources can iterate the full array.

    Location updates are forwarded as they are received from the upstream event pipeline; they are not aggregated or deduplicated by the streaming API.

    object

    Examples

Messages

  • #1Registration request payloadRegisterMessage

    Registration request payload, describing the topic which the client wants to register for

    Message IDRegisterMessage

    Sent by the client to subscribe to a topic within a specific organization. Once registered, the client receives events on that topic for every device the authenticated user is authorized to access in the given organization. Individual devices cannot be targeted; device access is determined server-side from the token.

    Send a separate register message for each topic the client wants to receive. The token field must match the token used during the WebSocket handshake.

    When at least one device is successfully registered, the server replies with a success message that lists the device IDs the client is now subscribed to and any devices that failed to register. When every device fails to register, the server replies with an error message and closes the connection. When the registration request itself is invalid (bad topic, missing fields), the server replies with an error message and keeps the connection open so the client can retry.

    Only events generated after a successful registration are delivered. No historical or buffered events are sent; use the companion REST API to fetch current state.

    object
  • #2Deregistration request payloadDeregisterMessage

    Deregistration request to stop receiving events from a specific topic

    Message IDDeregisterMessage

    Sent by the client to stop receiving events on a previously registered topic. After deregistration the client no longer receives events for that topic on this connection. The server does not send a success or error response to a deregistration request; the effect is silent.

    Setting data.topic to null deregisters the client from every topic it is currently subscribed to. Once a client has no remaining subscriptions (either through a null deregister or after the last individual topic is removed), the server closes the WebSocket connection. This is the recommended way to cleanly disconnect.

    Deregistering from a topic the client is not subscribed to is a no-op.

    object
  • #3Success response payloadSuccessMessage

    Success response payload sent when operations complete successfully

    Message IDSuccessMessage

    Delivered by the server in response to a register request that succeeded for at least one device. The data.message field is a human-readable summary describing how many devices were successfully registered and which devices, if any, failed to register.

    A registration that succeeds for some devices but fails for others is still reported as a success; the failed device IDs are listed inside data.message. A registration where every device fails is reported as an error, not as a success.

    Deregistration requests and echo requests do not produce a success message.

    The content of data.message is intended for logging and diagnostics and should not be parsed for programmatic logic.

    object
  • #4Error response payloadErrorMessage

    Error response payload sent when operations fail

    Message IDErrorMessage

    Delivered by the server when a client request cannot be processed. Common triggers include malformed JSON, failed validation of a register or de-register payload, unknown message types, and registration attempts where every device fails to register.

    The data.msg field is a human-readable explanation of the failure and is intended for logging and operator visibility, not for programmatic parsing.

    Most errors are recoverable: the server keeps the connection open after sending an error message, and the client may continue to send other requests. The connection is closed immediately after the error in only one case: when a register request fails for every authorized device in the organization.

    object
  • #5Echo requestEchoRequest

    Echo request to verify WebSocket functionality

    Message IDEchoRequest

    Sent by the client to verify the WebSocket connection is alive. The server replies with an echoResponse carrying the same data value.

    Echo messages do not require any topic registration and can be sent at any point during the connection's lifetime.

    object
  • #6Echo responseEchoResponse

    Echo response from server for connection health check

    Message IDEchoResponse

    Delivered in response to an echoRequest. Used to verify the WebSocket connection is alive.

    object
  • #7Sensor readings event, emitted by a deviceDeviceSensorReadings

    Sensor reading values from a device. Each message can include multiple sensor readings, as devices have multiple sensors.

    Message IDDeviceSensorReadings

    Delivered to clients registered to the sensor_readings topic when a device publishes new sensor measurements.

    Sensor readings are forwarded to subscribers as they are received from the upstream event pipeline; they are not aggregated, sampled, or deduplicated by the streaming API. Clients that need historical data or roll-ups should use the companion REST API.

    object
  • #8Device presence eventDevicePresence

    Device presence status updates including online/offline state and the trigger that caused the change.

    Message IDDevicePresence

    Delivered to clients registered to the device_presence topic when a device's presence state changes.

    The eventTimestamp field reflects when the presence change actually occurred, not when the message was delivered. Clients should order presence events by eventTimestamp, not by receive time.

    object
  • #9Event, emitted by a deviceDeviceEvent

    Safety events emitted by a device, such as falls, no motion, emergencies, or low battery.

    Message IDDeviceEvent

    Delivered to clients registered to the device_event topic when a device reports a safety alert. Current alert types are:

    • EMERGENCY
    • FALL_DETECTED
    • NO_MOTION
    • SILENT_EMERGENCY
    • DEVICE_TIPPED_OVER
    • PUMP_BLOCK_DETECTED
    • MISSED_CHECK_IN
    • LOW_BATTERY
    • TWA_ALERT_DETECTED
    • STEL_ALERT_DETECTED

    New alert types may be added over time; clients should tolerate unknown values without failing.

    object
  • #10Text message read receiptTextMessageReadReceipt

    A read receipt emitted when a device acknowledges a text message

    Message IDTextMessageReadReceipt

    Delivered to clients registered to the text_message topic when a device user reads a text message previously sent to the device.

    Only read receipts are delivered on this topic. Outbound text message sends and non-read delivery events are not part of this stream and must be handled through the messaging REST API.

    Read receipts carry meta.type of text_message_read_receipt.

    object
  • #11Device location eventDeviceLocation

    Location update for a device, including all location sources and the selected best location.

    Message IDDeviceLocation

    Delivered to clients registered to the location topic when a device publishes a new location update.

    Each message contains the full array of location entries (GPS and/or beacon) from the source event, along with a bestLocationIndex indicating which entry was selected as the best location. Clients that only need the best location can index directly into the array; clients that need all location sources can iterate the full array.

    Location updates are forwarded as they are received from the upstream event pipeline; they are not aggregated or deduplicated by the streaming API.

    object

Schemas

  • object
  • object
  • object
  • object
  • object
  • object