Dashboard
DocsConnect to BotSubscription Live Updates over Socket.IO | BotSubscription

Connecting to the Live Updates Gateway

Live updates are delivered over Socket.IO, so you connect with an official Socket.IO client (or any protocol-compatible library). WebSocket is the preferred transport. HTTP long-polling is available as a fallback for networks that block WebSockets.

If you are wiring up a Telegram subscription bot or Discord subscription bot front-end, this page covers everything you need to open and maintain a session.


Endpoint

PropertyValue
URLhttps://api.botsubscription.com/v2/live-updates
Socket.IO namespace/v2/live-updates
Socket.IO path/v2/live-updates/socket.io/
Transportswebsocket, polling
Max inbound packet size4 KB. This cap also applies to the Socket.IO CONNECT packet that carries your handshake auth object — a JWT plus project id, well under 1 KB in practice. Frames larger than 4 KB cause the connection to be closed silently before the ready message arrives.

Plain WebSocket libraries (without Socket.IO framing) will not work — use a Socket.IO client.


Authenticating the handshake

Pass your credentials in the Socket.IO auth object during the handshake:

FieldRequiredValue
tokenyesA user JWT (the same token format you use for the REST API).
project_idyesThe project UUID the session is scoped to.
import { io } from "socket.io-client";
 
const socket = io("https://api.botsubscription.com/v2/live-updates", {
  transports: ["websocket", "polling"],
  auth: {
    token: "YOUR_USER_JWT",
    project_id: "YOUR_PROJECT_UUID",
  },
});
Warning

Only user JWTs are accepted at this gateway. API keys / project tokens used for the REST API will be rejected during the handshake. Issue a short-lived user token from your authenticated app and pass it through.

If the handshake fails (invalid token, wrong project, revoked session), Socket.IO emits connect_error with the failure message. The server does not auto-retry — your client controls reconnect attempts.


The ready message

On a successful handshake, the server sends a ready system message via the message event:

{
  "event": "ready",
  "connection_id": "11111111-1111-1111-1111-111111111111",
  "channels": ["payment-requests", "targets", "payment-methods"]
}
  • connection_id — a per-session UUID generated by the gateway. Useful for logs and support tickets.
  • channels — the list of channels enabled for this connection. Treat unknown channel names defensively so your client stays forward compatible.

Wait for ready before sending any subscribe actions — see Messages & Actions.


Keep-alive & idle timeout

There are two layers of liveness checks:

LayerMechanismWhat you do
TransportSocket.IO ping/pong, ~25 s interval / 30 s timeout, server-driven.Nothing — the Socket.IO client handles this automatically.
ApplicationThe gateway disconnects sessions that send no client frames for 9 minutes.If your app may stay quiet that long, send a ping action every 5–8 minutes.

If you are happy to reconnect when the idle timeout fires, you can skip the application-level ping — Socket.IO will emit disconnect and your reconnect logic can resubscribe.


Transport fallback

ClientRecommendation
BrowserList transports: ["websocket", "polling"]. Socket.IO will try WebSocket first and fall back to HTTP long-polling if blocked.
Native / mobileUse a Socket.IO-compatible client (e.g. socket.io-client-swift, socket.io-client-java). Enable polling fallback for corporate networks.
Server-to-serverLive updates are designed for client apps. For backend integrations, prefer outbound webhooks.

Disconnection events

Your client should listen for the following events:

EventWhen it firesRecommended handling
disconnectSocket closed (idle timeout, transport error, server shutdown, intentional close). The reason argument explains why.Reconnect with backoff; resubscribe after the next ready event.
connect_errorHandshake or transport upgrade failed (often auth-related).Stop retrying if the error indicates a permanent auth failure; otherwise back off and retry.
session.revoked (named Socket.IO event)The user's session was revoked (logout). The server disconnects immediately after this event. Bind it with socket.on("session.revoked", handler) — not via the message envelope.Clear your stored token, redirect to login, do not auto-reconnect.

The session.revoked payload is minimal:

{ "reason": "logout" }

Browser quick start

A complete browser session that opens a connection, subscribes after ready, and logs disconnects:

<script src="https://cdn.socket.io/4.7.5/socket.io.min.js"></script>
<script>
  const socket = io("https://api.botsubscription.com/v2/live-updates", {
    transports: ["websocket", "polling"],
    auth: {
      token: "YOUR_USER_JWT",
      project_id: "YOUR_PROJECT_UUID",
    },
    reconnectionAttempts: 5,
  });
 
  socket.on("message", (data) => {
    if (data.event === "ready") {
      console.log("connected", data.connection_id, data.channels);
      socket.send({ action: "subscribe", channel: "targets" });
    }
  });
 
  socket.on("session.revoked", () => {
    // clear stored token and redirect to login
  });
 
  socket.on("disconnect", (reason) => console.log("disconnected:", reason));
  socket.on("connect_error", (err) => console.error("connect error:", err.message));
</script>

Server-side quick start

Open a session from your server runtime. Any Socket.IO v4-compatible client library will work; the snippets below use the most common one for each language.

import { io } from "socket.io-client";
 
const socket = io("https://api.botsubscription.com/v2/live-updates", {
  transports: ["websocket", "polling"],
  auth: {
    token: process.env.USER_JWT,
    project_id: process.env.PROJECT_ID,
  },
});
 
socket.on("message", (data) => {
  if (data.event === "ready") {
    console.log("connected", data.connection_id, data.channels);
    socket.send({ action: "subscribe", channel: "payment-methods" });
  }
});
 
socket.on("session.revoked", () => {
  // clear stored token; do not auto-reconnect
});
 
socket.on("payment-method.added", (frame) => {
  console.log("payment method added", frame.payment_method);
});
 
socket.on("disconnect", (reason) => console.log("disconnected:", reason));
socket.on("connect_error", (err) => console.error("connect error:", err.message));
Note

Socket.IO v4 client support varies across language ecosystems. The JavaScript and Python clients are first-party and best-maintained; PHP, Go, and Ruby rely on community libraries that may differ in API surface or transport coverage. Treat the snippets above as starting points and consult your client library's docs for advanced options like reconnection strategy and binary frames.


Next steps

Last updated: