WebSocket API

Overview

WebSocket API overview, connection lifecycle, and channel model

Use the WebSocket API for market streams and private account updates.

Endpoints

EnvironmentURL
Productionwss://pulse.obsdn.trade/ws
Stagingwss://pulse.staging.obsdn.trade/ws

Quick Start

# Using wscat
wscat -c wss://pulse.obsdn.trade/ws
const ws = new WebSocket("wss://pulse.obsdn.trade/ws")

ws.onopen = () => {
  ws.send(
    JSON.stringify({
      op: "sub",
      channel: "ticker",
      params: { market: "BTC-PERP" },
    })
  )
}

ws.onmessage = (event) => {
  console.log(JSON.parse(event.data))
}

Message Model

Subscribe

{
  "op": "sub",
  "channel": "CHANNEL_NAME",
  "params": { "market": "MARKET_ID" }
}

Unsubscribe

{
  "op": "unsub",
  "channel": "CHANNEL_NAME",
  "params": { "market": "MARKET_ID" }
}

The params field is channel-specific. Market channels use { "market": "BTC-PERP" }, the oracle channel uses { "asset": "BTC" }, and private user channels require no params.

Auth (for private channels)

Send before subscribing to any private channel.

{
  "op": "auth",
  "params": {
    "key": "your_api_key",
    "timestamp": "1734567890",
    "signature": "your_signature"
  }
}

The signature is computed as base64(HMAC-SHA256(api_secret, "${api_key},${timestamp}")) — standard base64 encoding.

timestamp is a Unix time in seconds (string) and must be within ±60 seconds of server time, otherwise the auth message is rejected.

import { createHmac } from "node:crypto"

const timestamp = Math.floor(Date.now() / 1000).toString()
const signature = createHmac("sha256", apiSecret).update(`${apiKey},${timestamp}`).digest("base64")

Heartbeat

The server accepts ping messages and responds with a pong. Send a ping every 10 seconds to keep the connection alive. Close and reconnect if no response is received within 3 seconds.

{ "op": "ping" }
{ "type": "pong" }

Subscribed Confirmation

After a successful subscription, the server sends:

{
  "type": "subscribed",
  "channel": "CHANNEL_NAME",
  "params": { "market": "BTC-PERP" }
}

The params field echoes back the subscription parameters (omitted if no params were provided).

Channel Summary

ChannelAuthparamsSnapshotUpdates
bookNo{ market }YesYes
tradeNo{ market } (optional)NoYes
tickerNo{ market }YesYes
oracleNo{ asset }YesYes
orderYesNoneYesYes
positionYesNoneYesYes
portfolioYesNoneYesYes

Connection Guidance

  1. Implement automatic reconnect with exponential backoff.
  2. Resubscribe to all channels after reconnect.
  3. Process messages in-order per channel/market stream.
  4. Validate order book checksums and resubscribe on mismatch.
  5. Send ping every 10 seconds; reconnect if pong is not received within 3 seconds.

Next

On this page