Build a real-time UFC fight dashboard
Live REST, SSE, and optional WebSockets
Live overview
bash
curl "https://api.citoapi.com/api/v1/ufc/live" \
-H "x-api-key: YOUR_API_KEY"Poll using recommendedPollSeconds from the response (usually 1–2s on fight night). Empty clocks stay empty — do not invent timers. Reference: Live API.
javascript
async function pollLive() {
const res = await fetch("https://api.citoapi.com/api/v1/ufc/live", {
headers: { "x-api-key": process.env.CITO_API_KEY },
});
const json = await res.json();
const bout = json.data?.liveBouts?.[0];
if (!bout) {
setTimeout(pollLive, 5000);
return;
}
renderBoard(bout);
setTimeout(pollLive, (bout.recommendedPollSeconds ?? 2) * 1000);
}One bout
bash
curl "https://api.citoapi.com/api/v1/ufc/live/ufc-12938" \
-H "x-api-key: YOUR_API_KEY"After the fight finishes, use bout stats / rounds for full totals.
SSE
bash
curl -N "https://api.citoapi.com/api/v1/ufc/live/stream?eventSlug=YOUR_EVENT_SLUG" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: text/event-stream"WebSocket
Room-based push is a paid add-on (+$25/mo). Protocol: WebSocket docs. Enable under billing.
javascript
const ws = new WebSocket(
`wss://api.citoapi.com/api/v1/ufc/live/ws?api_key=${KEY}`
);
ws.onmessage = (ev) => {
const msg = JSON.parse(ev.data);
if (msg.type === "ready") {
ws.send(JSON.stringify({
action: "subscribe",
rooms: ["event:YOUR_EVENT_SLUG", "bout:ufc-12938"],
}));
}
if (msg.type === "ufc.live.update") renderBoard(msg.data);
};Ship a fight-night board
Cito powers MMA dashboards, live cards, and research tools. Poll live in the sandbox first; add WebSockets when you need room-based push.
bash
curl "https://api.citoapi.com/api/v1/ufc/live" \
-H "x-api-key: YOUR_API_KEY"
# One bout (replace id)
curl "https://api.citoapi.com/api/v1/ufc/live/ufc-12938" \
-H "x-api-key: YOUR_API_KEY"
# SSE push
curl -N "https://api.citoapi.com/api/v1/ufc/live/stream" \
-H "x-api-key: YOUR_API_KEY" \
-H "Accept: text/event-stream"