Docs/UFC API/Live/WebSocket

UFC Live WebSocket

wss://api.citoapi.com/api/v1/ufc/live/ws · room push for fight night · frames do not count against REST quota

Start using WebSockets

Checking your plan…

Loading

Connect

javascript
const key = process.env.CITO_API_KEY;

// Browser: query param (headers not available on WebSocket upgrade)
const ws = new WebSocket(
  `wss://api.citoapi.com/api/v1/ufc/live/ws?api_key=${encodeURIComponent(key)}`
);

// Node (ws): prefer header
// new WebSocket(url, { headers: { "x-api-key": key } });

ws.onmessage = (ev) => {
  const msg = JSON.parse(ev.data);
  console.log(msg.type, msg);
};

Subscribe

After ready, join rooms. bout:{boutId} for one fight, event:{eventSlug} for the card.

json
{ "action": "subscribe", "rooms": ["bout:ufc-12938", "event:ufc-fight-night-example"] }
{ "action": "unsubscribe", "rooms": ["bout:ufc-12938"] }
{ "action": "ping" }

Payload

Event type ufc.live.update. Same fields as live REST. Empty clocks stay null.

json
{
  "type": "ufc.live.update",
  "room": "bout:ufc-12938",
  "data": {
    "boutId": "ufc-12938",
    "status": "live",
    "currentRound": 2,
    "currentTime": "3:12",
    "red": { "fighterName": "Fighter A" },
    "blue": { "fighterName": "Fighter B" },
    "liveStats": {
      "red": { "sigStrikes": 42, "takedowns": 1 },
      "blue": { "sigStrikes": 38, "takedowns": 0 }
    },
    "lagSeconds": 2,
    "source": "ufc_fightmetric_cdn",
    "degradedReason": null
  }
}

Post-fight round tables: /ufc/bouts/{id}/rounds

Reconnect

javascript
const ROOMS = ["bout:ufc-12938"];
let attempt = 0;

function connect() {
  const ws = new WebSocket(
    `wss://api.citoapi.com/api/v1/ufc/live/ws?api_key=${encodeURIComponent(KEY)}`
  );
  ws.onopen = () => { attempt = 0; };
  ws.onmessage = (ev) => {
    const msg = JSON.parse(ev.data);
    if (msg.type === "ready") {
      ws.send(JSON.stringify({ action: "subscribe", rooms: ROOMS }));
    }
    if (msg.type === "ufc.live.update") renderLive(msg.data);
  };
  ws.onclose = () => {
    const delay = Math.min(30_000, 1000 * 2 ** attempt++) + Math.random() * 500;
    setTimeout(connect, delay);
  };
}
connect();

Re-subscribe after every reconnect. Catch up with GET /ufc/live/{boutId}/state if you missed frames.

Transports

TransportPathNotes
RESTGET /ufc/liveUses request quota
SSEGET /ufc/live/streamHTTP push
WebSocket/ufc/live/wsAdd-on · room subscribe · no REST quota on frames

Start using WebSockets

Checking your plan…

Loading