Node.jsExamples below

CS2 data from Node.js.

Node 18 and later ship fetch, so there is nothing to install: one helper, then results, live scores and anything else in the API, typed if you want it.

  • Built-in fetch
  • TypeScript-friendly JSON
  • 500 free requests / month
GET /cs2/matches/recent200 OK
$ curl "https://api.citoapi.com/api/v1/cs2/matches/recent" \ -H "x-api-key: $CITO_API_KEY"
{  "data": [    ...    {      "eventName": "NODWIN Clutch Series 12",      "team1Name": "Walczaki",      "team2Name": "BET-M",      "team1Score": 0,      "team2Score": 1,      "isForfeit": true    }  ]}

Seamless Integration with our MCP Server

Give Claude, Cursor and ChatGPT the CS2 data. One command writes the MCP config; agents call live scoreboard, team map stat, opening duel and transfer tools instead of inventing match IDs, and your key stays on your machine.

MCPInstall the Cito MCP server
Claude
Cursor
OpenAI
Python
Cito API
Next.js
Discord
Slack
GitHub

What JavaScript projects build

From a server route to a front-end widget backed by your API.

API routes

Proxy CS2 data through your own backend.

Live widgets

Score tickers fed by polling or SSE.

Discord bots

Slash commands with discord.js.

Static sites

Build-time fetches for schedules and results.

Edge functions

Plain fetch runs on edge runtimes.

Typed clients

Small TypeScript types over the JSON.

Recent results in Node.js

cs2.mjs
// cs2.mjs  (Node 18+, run: CITO_API_KEY=... node cs2.mjs)
const API = "https://api.citoapi.com/api/v1";
const headers = { "x-api-key": process.env.CITO_API_KEY };

async function get(path) {
  const res = await fetch(`${API}${path}`, { headers });
  if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
  return res.json();
}

const { data: results } = await get("/cs2/matches/recent?limit=5");
for (const m of results) {
  const note = m.isForfeit ? " (forfeit)" : "";
  console.log(`${m.team1Name} ${m.team1Score}-${m.team2Score} ${m.team2Name}${note}`);
}

Typing the live response

types.ts
type LiveMatch = {
  matchId: string;
  eventName: string;
  team1Name: string;
  team2Name: string;
  team1Score: number | null;
  team2Score: number | null;
  currentMap: string | null;
  currentMapScore: { team1: number; team2: number } | null;
  currentRound: number | null;
};

const { data } = (await get("/cs2/live")) as { data: LiveMatch[] };

Endpoints you can ship with

Every route here works from fetch.

Results

Finished matches with the series score and winner, every map and its score, and the player lines behind them.

View docs
  • GET/api/v1/cs2/matches/recent

    Finished matches with final series score and winner, newest first.

  • GET/api/v1/cs2/matches/{matchId}

    One match: event, teams, series score, and maps.

  • GET/api/v1/cs2/matches/{matchId}/maps

    Each map: name, score, winner, and the team that picked it.

  • GET/api/v1/cs2/matches/{matchId}/player-stats

    Per-player stats for each map: kills, deaths, ADR, KAST and rating.

  • GET/api/v1/cs2/teams/{teamIdOrSlug}/results

    One team's finished matches, newest first.

  • GET/api/v1/cs2/events/{eventIdOrSlug}/results

    Final placements and prize money of a tournament.

FAQs

Node setup, TypeScript and the browser

Can't find what you're looking for? Contact our customer support team

See pricing

Build in Node: API routes

Get a free key and run cs2.mjs.