WebSocket Overview
Socket.IO connection, authentication, and channel architecture
Vezta provides real-time data through a Socket.IO WebSocket server. Market data, order updates, portfolio changes, crypto prices, sports state, and platform signals are delivered through a family of channels using a consistent subscribe/unsubscribe pattern. Channels are namespaced by prefix — market:, crypto:, sports:, weather:, monitor:, game:, and user:.
Connection
Connect using the Socket.IO client library. The server runs at the /ws namespace:
import { io } from 'socket.io-client';
const socket = io('wss://backend.vezta.io/ws', {
transports: ['websocket'],
auth: {
token: '<your-jwt-access-token>',
},
reconnection: true,
reconnectionDelay: 1000,
reconnectionDelayMax: 30000,
});
socket.on('connect', () => {
console.log('Connected:', socket.id);
});
socket.on('disconnect', (reason) => {
console.log('Disconnected:', reason);
});For local development, connect to ws://localhost:3001/ws.
Authentication
Pass your JWT access token in the auth.token field during connection. Only user:* channels require a token — every other channel (market:, crypto:, sports:, weather:, monitor:, game:) is public and works without authentication.
Subscribe to a Channel
Send a subscribe event with the channel name:
socket.emit('subscribe', { channel: 'market:prices:<marketId>' });The server responds with a confirmation:
{ "event": "subscribed", "data": { "channel": "market:prices:<marketId>" } }Unsubscribe from a Channel
socket.emit('unsubscribe', { channel: 'market:prices:<marketId>' });Response:
{ "event": "unsubscribed", "data": { "channel": "market:prices:<marketId>" } }Receiving Data
All channel broadcasts arrive on the data event with a consistent envelope:
socket.on('data', (message) => {
// message.channel — the channel name (e.g., "market:prices:<marketId>")
// message.data — the payload
console.log(`[${message.channel}]`, message.data);
});Route messages by inspecting message.channel:
socket.on('data', (message) => {
switch (message.channel) {
case 'market:prices:<marketId>':
updatePrices(message.data);
break;
case 'market:orderbook:<marketId>':
updateOrderbook(message.data);
break;
case 'user:orders':
handleOrderUpdate(message.data);
break;
// ... handle other channels
}
});Available Channels
| Channel | Auth | Description |
|---|---|---|
market:prices:<marketId> | No | Real-time YES/NO price updates |
market:orderbook:<marketId> | No | Order book depth snapshots |
market:trades:<marketId> | No | Live trade feed from exchanges |
market:holders:<marketId> | No | Top 20 token holder concentration per side (Polymarket) |
market:targetprices:<marketId> | No | Target price assignments for short-duration and boundary-resolved markets |
market:sports-state:<marketId> | No | Live sports market state (score, period, clock) keyed by market id |
market:sports-stats:<eventId> | No | Live sports-stats deltas (goals, timeline) keyed by event id |
market:resolved:<marketId> | No | Market resolution notice (auto-close positions) |
crypto:prices:chainlink:<slug> | No | Chainlink oracle crypto price feeds (BTC, ETH, SOL, XRP, DOGE, BNB, HYPE) |
sports:standings:<leagueSlug> | No | League standings refresh (e.g. fifa.world) |
game:<slug>:live | No | Game-level live score/state |
weather:<icao> | No | Weather-station temperature readings |
user:orders | Yes | Order status changes and fills |
user:notifications | Yes | In-app notification delivery |
user:transactions | Yes | Deposit and withdrawal transaction status updates |
user:portfolio | Yes | Portfolio value and position updates |
user:copy-trade | Yes | Copy trade execution events |
user:combo-orders | Yes | Combo (parlay) order status updates |
monitor:signals | No | News signals and insider alerts |
Full Example
import { io } from 'socket.io-client';
const socket = io('wss://backend.vezta.io/ws', {
transports: ['websocket'],
auth: { token: accessToken },
});
socket.on('connect', () => {
// Subscribe to channels
socket.emit('subscribe', { channel: 'market:prices:<marketId>' });
socket.emit('subscribe', { channel: 'user:orders' });
socket.emit('subscribe', { channel: 'monitor:signals' });
});
socket.on('data', (message) => {
switch (message.channel) {
case 'market:prices:<marketId>':
console.log('Price update:', message.data);
break;
case 'user:orders':
console.log('Order update:', message.data);
break;
case 'monitor:signals':
console.log('Signal:', message.data);
break;
}
});
socket.on('disconnect', () => {
console.log('Disconnected from WebSocket');
});The web client uses exponential backoff reconnection starting at 1 second and capping at 30 seconds. The gateway enforces 5000 max total connections, 10 per userId, 20 per IP, and 2,000 messages/min per client (subscribe + unsubscribe combined).