InsightSentry

Enterprise WebSocket API

1. Getting Started

Enterprise Solution Overview

This documentation describes the WebSocket/PubSub solution specifically for enterprise clients. Enterprise deployments use a different authentication flow than our public plans to provide enhanced security and reliability.

Prerequisites

  1. Azure Active Directory Credentials: You will receive these from our team via email.
  2. WebSocket/PubSub Server Information: You will receive these from our team via email.
  3. Authentication Tokens: You'll need to implement a two-step authentication process described in the next section.

2. Authentication

Enterprise Authentication Flow

The authentication process involves two steps:

  1. Obtain Microsoft Azure OAuth Access Token

    Using the credentials provided to your team, make a request to Microsoft's OAuth endpoint:

    BASH
    curl -X POST "https://login.microsoftonline.com/{tenantId}/oauth2/v2.0/token" \
      -H "Content-Type: application/x-www-form-urlencoded" \
      -d "client_id={clientId}&scope={scope}&client_secret={clientSecret}&grant_type=client_credentials"

    Upon success, you will receive a response like:

    JSON
    {
      "token_type": "Bearer",
      "expires_in": 3599,
      "ext_expires_in": 3599,
      "access_token": "eyJ0eXAiOi...JWT_TOKEN_HERE"
    }
  2. Authenticate with Our Server

    Using the access_token from the previous step, authenticate with our server:

    BASH
    curl -X POST "https://{ourServerName}/.auth/login/aad" \
      -H "Content-Type: application/json" \
      -d '{"access_token": "eyJ0eXAiOi...JWT_TOKEN_HERE"}'

    If successful, you'll receive a response containing your authentication token:

    JSON
    {
      "authenticationToken": "eyad1ad...another_token_here",
      "user": {
        "userId": "sid:a50f42b1481ca31efcf853fabb13e95b"
      }
    }

Using the Authentication Token

To use the token with our WebSocket service:

  1. Include the authenticationToken in your WebSocket connection headers as X-ZUMO-AUTH
  2. This token will authenticate all WebSocket communications with our server
TYPESCRIPT
// Example WebSocket connection with authentication
const socket = new WebSocket('wss://{ourServerName}/ws');

// Set the authentication header before connecting
socket.setRequestHeader('X-ZUMO-AUTH', authenticationToken);

Email Registration

After successfully connecting to the WebSocket server, you must send an email registration message:

  1. Send a JSON message with your email immediately after connection is established
  2. Send this message again after every reconnection
  3. The email should be one where your engineering team can receive support communications
JAVASCRIPT
// Send email registration after connection is established
socket.onopen = function() {
  // Register email for support purposes
  socket.send(JSON.stringify({
    "email": "[email protected]"
  }));
};

Keeping Connections Alive (Optional)

To prevent connection timeouts and detect disconnections early, implement a ping-pong mechanism:

  1. Send a plain text message "ping" every 15 seconds
  2. Our server will respond with "pong" to confirm the connection is active
  3. Filter out these "pong" responses in your message handler
  4. If pings stop receiving responses, your client should reconnect

3. Response Data Formats

Enterprise WebSocket responses use a more compact format to optimize bandwidth and reduce latency. The field names are shortened compared to our public solutions.

Quote Data Format

Real-time market quotes use the following abbreviated field names:

Standard FieldEnterprise FormatDescription
codecSymbol identifier
lp_timeltLast price timestamp
volumevTrading volume
last_pricelpLast trade price
askaAsk price
bidbBid price
ask_sizeasSize of ask orders
bid_sizebsSize of bid orders

Example Quote Response:

JSON
{
  "c": "NASDAQ:AAPL",
  "lt": 1733432340,
  "v": 533779,
  "lp": 243.08,
  "a": 243.09,
  "b": 243.08,
  "as": 520.0,
  "bs": 430.0
}

Series Data Format

OHLCV bar data uses these abbreviated field names:

Standard FieldEnterprise FormatDescription
codecSymbol identifier
bar_endbeBar end timestamp
last_updateluLast update timestamp
bar_typebtBar interval type
seriessArray of OHCLV data

Within each series bar object:

Standard FieldEnterprise FormatDescription
timetBar timestamp
openoOpening price
highhHighest price
lowlLowest price
closecClosing price
volumevTrading volume

Example Series Response:

JSON
{
  "c": "NASDAQ:AAPL",
  "be": 1733432399,
  "lu": 1733432399820,
  "bt": "1m",
  "s": [
    {
      "t": 1733432340,
      "o": 242.89,
      "h": 243.09,
      "l": 242.82,
      "c": 243.08,
      "v": 533779
    }
  ]
}

4. Code Examples

Below are examples demonstrating how to authenticate and connect to our enterprise WebSocket service.

TYPESCRIPT
import axios from 'axios';
import WebSocket from 'ws';

// Your enterprise credentials (provided by our team)
const tenantId = 'your-tenant-id';
const clientId = 'your-client-id';
const clientSecret = 'your-client-secret';
const scope = 'https://yourscope/.default';
const hostName = 'your-enterprise-server.insightsentry.com';

async function main() {
  try {
    // Step 1: Obtain Microsoft Azure access token
    const tokenResponse = await axios.post(
      `https://login.microsoftonline.com/${tenantId}/oauth2/v2.0/token`,
      new URLSearchParams({
        'client_id': clientId,
        'scope': scope,
        'client_secret': clientSecret,
        'grant_type': 'client_credentials'
      }),
      {
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        }
      }
    );
    
    const accessToken = tokenResponse.data.access_token;
    
    // Step 2: Authorize with our app to get authentication token
    const authResponse = await axios.post(
      `https://${hostName}/.auth/login/aad`,
      { 'access_token': accessToken },
      {
        headers: {
          'Content-Type': 'application/json'
        }
      }
    );
    
    const authToken = authResponse.data.authenticationToken;
    
    // Step 3: Connect to WebSocket with the authentication token
    connectToWebSocket(authToken);
  } catch (error) {
    console.error('Authentication error:', error);
  }
}

function connectToWebSocket(authToken: string) {
  // Create WebSocket connection
  const ws = new WebSocket(`wss://${hostName}/ws`, {
    headers: {
      'X-ZUMO-AUTH': authToken
    }
  });
  
  let pingInterval: NodeJS.Timeout;
  
  ws.on('open', () => {
    console.log('WebSocket connection established');
    // Send initialization message
    ws.send(JSON.stringify({ 'email': '[email protected]' }));
    
    // Set up ping interval (every 15 seconds)
    pingInterval = setInterval(() => {
      if (ws.readyState === WebSocket.OPEN) {
        ws.send('ping');
        console.log('Ping sent');
      }
    }, 15000);
  });
  
  ws.on('message', (data) => {
    // Convert buffer to string if needed
    const message = data.toString();
    
    // Ignore pong responses
    if (message === 'pong') {
      return;
    }
    
    // Process actual data messages
    console.log('Received:', message);
    
    try {
      const jsonData = JSON.parse(message);
      // Process your JSON data here
    } catch (e) {
      // Handle non-JSON messages if needed
    }
  });
  
  ws.on('error', (error) => {
    console.error('WebSocket error:', error);
  });
  
  ws.on('close', () => {
    console.log('WebSocket connection closed');
    // Clear ping interval
    clearInterval(pingInterval);
    
    // Optional: Implement reconnection logic here
  });
}

main();