Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.4casters.io/llms.txt

Use this file to discover all available pages before exploring further.

The price feed streams market/orderbook updates as JSON messages over a raw WebSocket connection.
// price_feed_quickstart.js 
const WebSocket = require('ws'); 
const token = process.env.FOURCASTERS_TOKEN; 
 
function connectPriceFeed() { 
  const ws = new 
  WebSocket('wss://streaming-api.4casters.io/price-stream', { 
    headers: { Authorization: token }, 
  }); 
 
  let pingTimer; let lastPong = Date.now(); 
 
  ws.on('open', () => { 
    console.log('price stream connected'); 
    pingTimer = setInterval(() => { 
      if (ws.readyState === WebSocket.OPEN) ws.ping(); 
      if (Date.now() - lastPong > 30000) { 
        console.warn('price stream: missed pong >30s, closing'); 
        ws.terminate(); 
      } 
    }, 10000); 
  }); 
 
  ws.on('pong', () => { lastPong = Date.now(); }); 
 
  ws.on('message', (buf) => { 
    try { 
      const msg = JSON.parse(buf.toString()); 
      console.log('price update:', JSON.stringify(msg, null, 2)); 
    } catch { console.log('price update (raw):', buf.toString()); } 
  }); 
 
  ws.on('error', (e) => console.error('price stream error:', e.message)); 
 
  ws.on('close', (code, reason) => { 
    console.log(`price stream closed: ${code} ${reason}`); 
    clearInterval(pingTimer); 
    setTimeout(connectPriceFeed, 1000); 
  }); 
} 
connectPriceFeed();

Ping/Pong

Both feeds support standard WebSocket ping/pong. You may proactively ping() on an interval and track pong to verify liveness.

Messages

Every message on /price-stream arrives as a 2-tuple [type, payload]. Three message types are broadcast.

orderUpdate

Emitted whenever an order in any market changes (new, edited, filled, or cancelled). The payload only includes sideOrders the receiving user is allowed to see (own orders plus matchable counterparties).
[
  "orderUpdate",
  {
    "epoch": 1234567,
    "gameID": "62619dce25e2fb049a71cc2e",
    "parentGameID": null,
    "sport": "basketball",
    "league": "NBA",
    "live": false,
    "type": "total",
    "participantID": null,
    "market": "main",
    "side": "under",
    "OU": "under",
    "total": 8.5,
    "spread": null,
    "mainHomeSpread": -6.5,
    "mainAwaySpread": 6.5,
    "mainTotal": 209.5,
    "sideOrders": [
      {
        "id": "62619e6a40e36d0494600f48",
        "type": "total",
        "sumUntaken": 255,
        "odds": 104,
        "bet": 265.2,
        "gameID": "62619dce25e2fb049a71cc2e",
        "takenRatio": 0,
        "participantID": null,
        "market": "main",
        "side": "under",
        "OU": "under",
        "total": 8.5,
        "spread": null,
        "gameStartExpiry": false,
        "isPostArb": false,
        "expiry": "2022-04-21T23:40:12.000Z",
        "createdAt": "2022-04-21T18:11:54.614Z"
      }
    ]
  }
]

gameUpdate

Emitted when a game is created or its state changes (markets opening, closing, start time updates). The payload is the full rendered game.
[
  "gameUpdate",
  {
    "id": "625ecb5f269b7ff13619ca7c",
    "parentGameID": null,
    "league": "NBA",
    "sport": "basketball",
    "start": "2022-04-22T01:00:00.000Z",
    "ended": false,
    "messageType": "marketOpen",
    "participants": [
      { "id": "607349dc22a237cf46b021fb", "longName": "Dallas Mavericks", "shortName": "DAL", "homeAway": "away", "rotationNumber": "571" },
      { "id": "60747bcde3b0844e56d2e7e8", "longName": "Utah Jazz",        "shortName": "UTA", "homeAway": "home", "rotationNumber": "572" }
    ],
    "awayMoneylines": [],
    "homeMoneylines": [],
    "awaySpreads": {},
    "homeSpreads": {},
    "over": {},
    "under": {},
    "mainHomeSpread": -6.5,
    "mainAwaySpread": 6.5,
    "mainTotal": 209.5
  }
]
Known messageType values: marketOpen, marketClosed. Treat the field as extensible and ignore unknown values.

matchedVolumeUpdate

Emitted when the total matched volume on a game changes.
[
  "matchedVolumeUpdate",
  {
    "gameID": "625ecb5f269b7ff13619ca7c",
    "parentGameID": null,
    "league": "NBA",
    "sport": "basketball",
    "matchedVolume": 12450.75
  }
]