This example connects from the browser and subscribes to ticker:BTCUSDT.
type ServerMessage = {
  type: "data" | "subscribed" | "unsubscribed" | "pong" | "error";
  channel?: string;
  data?: unknown;
  error?: {
    code: number;
    message: string;
  };
  id?: number;
  timestamp: number;
};

const socket = new WebSocket("wss://ws.poolthewool.com/ws");

socket.addEventListener("open", () => {
  socket.send(
    JSON.stringify({
      type: "subscribe",
      channel: "ticker:BTCUSDT",
      id: 1,
    })
  );
});

socket.addEventListener("message", (event) => {
  // The server can batch newline-separated JSON messages in one WebSocket frame.
  const messages = String(event.data)
    .split("\n")
    .filter(Boolean)
    .map((line) => JSON.parse(line) as ServerMessage);

  for (const message of messages) {
    if (message.type === "data" && message.channel === "ticker:BTCUSDT") {
      console.log("Ticker update", message.data);
    }

    if (message.type === "error") {
      console.error(message.error?.code, message.error?.message);
    }
  }
});

Keepalive

The server sends WebSocket protocol ping frames. Browser WebSocket clients respond automatically. You can also send an application-level ping when you want to check the connection from application code:
{
  "type": "ping",
  "id": 99
}
The server responds:
{
  "type": "pong",
  "id": 99,
  "timestamp": 1780816674605
}