Use cases/Broadcast graphics & overlays

[UC 04]

How broadcasters feed live CS2 data into on-air graphics with Cito

Seen in our API traffic

Live CS2 data is already feeding graphics systems on tournament broadcasts.

GET /cs2/live/{matchId}/state
{
  "success": true,
  "data": {
    "status": "live",
    "currentMap": "de_dust2",
    "currentRound": 22,
    "score": { "team1": 9, "team2": 13 },
    "bombPlanted": false,
    "players": [
      { "name": "m1N1", "side": "T", "alive": false, "money": 750,
        "kills": 23, "deaths": 11, "adr": 85.1 }
    ]
  }
}

Challenge

On-air graphics can't lag the game or show a wrong score. Production teams need a feed that keeps up round by round and never needs a person to retype numbers.

Solution

A live scoreboard per match with score, round, economy and player stats, pushed as it changes and mapped to stable team and player IDs your graphics templates already use.

What you get

  • Round-by-round score and map state for lower thirds
  • Live player stats and economy for stat graphics
  • Pushed updates instead of polling
  • Stable IDs mapped once to your templates

One feed per match

Point your graphics system at the live state for the match on air. It carries the map, round, score, bomb state and every player's live stats.

Push, don't poll

The live stream pushes each change as it happens. In our measurements updates arrive about 0.25 s after the public scoreboard, fast enough for round-result graphics.

// Server-side: the stream takes the key in a header, like every endpoint.
const res = await fetch("https://api.citoapi.com/api/v1/cs2/live/stream", {
  headers: { "x-api-key": process.env.CITO_API_KEY },
});
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
for (let buf = ""; ; ) {
  const { value, done } = await reader.read();
  if (done) break;
  buf += value;
  const events = buf.split("\n\n");
  buf = events.pop();
  for (const e of events) {
    const data = e.split("\n").find((l) => l.startsWith("data:"));
    if (data) updateGraphics(JSON.parse(data.slice(5)));
  }
}

Map once

Team and player IDs are stable, so you map them to your graphics assets once and reuse them all season.

Endpoints used

GET/cs2/live/{matchId}/stateMap, round, score and every player
GET/cs2/live/{matchId}/player-statsLive K/D/ADR per player
GET/cs2/live/streamPushed changes for every live match
GET/ufc/live/{boutId}/stateRound and clock for fight nights

Build it on a free key

500 requests a month, every game, no card.

More use cases