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
| Property | Value |
|---|---|
| URL | https://api.botsubscription.com/v2/live-updates |
| Socket.IO namespace | /v2/live-updates |
| Socket.IO path | /v2/live-updates/socket.io/ |
| Transports | websocket, polling |
| Max inbound packet size | 4 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:
| Field | Required | Value |
|---|---|---|
token | yes | A user JWT (the same token format you use for the REST API). |
project_id | yes | The 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",
},
});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:
| Layer | Mechanism | What you do |
|---|---|---|
| Transport | Socket.IO ping/pong, ~25 s interval / 30 s timeout, server-driven. | Nothing — the Socket.IO client handles this automatically. |
| Application | The 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
| Client | Recommendation |
|---|---|
| Browser | List transports: ["websocket", "polling"]. Socket.IO will try WebSocket first and fall back to HTTP long-polling if blocked. |
| Native / mobile | Use a Socket.IO-compatible client (e.g. socket.io-client-swift, socket.io-client-java). Enable polling fallback for corporate networks. |
| Server-to-server | Live updates are designed for client apps. For backend integrations, prefer outbound webhooks. |
Disconnection events
Your client should listen for the following events:
| Event | When it fires | Recommended handling |
|---|---|---|
disconnect | Socket closed (idle timeout, transport error, server shutdown, intentional close). The reason argument explains why. | Reconnect with backoff; resubscribe after the next ready event. |
connect_error | Handshake 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));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
- Send subscribe actions and read system messages in Messages & Actions.
- Track a single payment in Payment Request live updates.
- Mirror Discord and Telegram targets live in Target live updates.