Docs/CS2 API

Counter-Strike 2 API

Beta

Live matches down to the round, results with every map score, per-map player stats, teams, players, events, and the world and VRS rankings. This is the endpoint reference; the CS2 API overview covers plans, coverage and skin prices.

CS2 is in beta. The data is live and checked continuously, but if something looks wrong (a score, a stat line, a roster, a missing match), email support@citoapi.com with the endpoint you called and the match, team or player id. Reports go straight to the people fixing it.

BASEhttps://api.citoapi.com/api/v1
CS2 API RootAppend any endpoint path below.

Webhooks: a signed POST when a match starts, a round ends, a bomb is planted or a result is final. CS2 webhooks

Quick start

Bash
curl "https://api.citoapi.com/api/v1/cs2/matches/recent?limit=5" \
  -H "x-api-key: YOUR_API_KEY"

Every response is { success, data, meta }. Ids look like cs2-match-2398421, cs2-team-9565 and cs2-player-11893; teams and players also accept their slug (vitality, zywoo). Times are ISO 8601 in UTC.

Full endpoint reference

Every CS2 endpoint, with parameters, a curl example and a real response, grouped by area.

CS2 Live Scores API
Everything about matches in progress: the live list, per-match state and scoreboard, rounds, kill events, live player stats, and the push stream so you do not have to poll. It follows the public scoreboard, which tournaments run behind a broadcast delay: built for live scoreboards, bots, overlays and models, not for betting on the next round.
CS2 Player Props API
Pick'em player prop lines for Counter-Strike 2 from Underdog Fantasy and Sleeper, refreshed every 5 minutes: kills and headshots on maps 1-2. Each line is linked to the match and player ids used everywhere else in the API, shows every app side by side with the spread between them, and is graded against the player's last 5 and 10 series from our own map stats. Underdog prices both sides as odds; Sleeper pays a multiplier per pick, returned as a multiplier. Player props are included on Pro and above.
CS2 Odds API
Prediction-market prices for Counter-Strike 2 matches as decimal odds: the series winner and every map, updated as soon as the market price changes (live matches and matches starting within 6 hours; further out every 15 minutes), all through each map and between rounds. The CS2 live WebSocket pushes every change as a cs2.odds.updated message with the map, round and round phase it happened in. History rows carry the map and round (filter with map, round and phase), and /cs2/matches/{matchId}/odds/rounds gives every market's price at the start and end of each round. Each quote says whether its market is open, suspended (a decided map) or closed. A market is attached to a match only when both teams match and it starts within 6 hours of the market's start time, and every link is re-checked against the current match every 15 minutes, so a rescheduled or re-paired match never keeps another match's odds. Odds are included on Pro and above.
CS2 Positional Data API
Where things happened on each pro map. Every grenade (smoke, flash, HE, molotov, decoy) with the spot it went off, who threw it, the round, seconds into the round and how long smokes and molotovs lasted; every bomb plant, defuse and explosion with its site; and every kill with the attacker's and victim's position and callout (BombsiteA, Banana). Each point comes in game units (x, y, z) and already projected onto the map's 1024x1024 radar as radar.x / radar.y from 0 to 1, so you can draw it on any radar image by multiplying by its width and height; /cs2/map-radars has the calibration per map. Heatmaps bin any of these over a grid laid on the radar, per map or per player. Grenade positions cover every map with round data; kill and death positions cover maps processed from 31 October 2026 on. Not included: where a grenade was thrown from, and player movement paths. Positional data is on paid plans.
Watch live: embed the CS2 stream
Every broadcast of a match with a ready-to-use iframe URL, the tournament organiser's official stream first: Twitch, YouTube and Kick, with the language and platform for a switcher, like the player on a match page. Live matches carry the official stream's embed too.
CS2 Pro Player Skins API
The skins pros actually use in matches: each player's knife, gloves and weapon skins per side (CT and T loadouts differ), with float, wear, pattern seed, Doppler phase, StatTrak and Souvenir, the current market price, and the date and map it was last seen. Every item, and any catalogue skin, has an inspect link to open that exact item in 3D.
CS2 Matches API
Schedules, results and everything recorded about a single series: maps played, player stats per map, lineup form, head-to-head history, streams and demo links.
CS2 Maps and Rounds API
Map-level data: the active duty pool with its dated history, the map catalog, and for each map played in a series its duration, player stats, round history, events and per-player economy (start money, spend and buy type each round). Grenade, kill and bomb positions and heatmaps for a map are in Positions & heatmaps.
CS2 Rankings API
Team rankings: the world ranking, Valve Regional Standings, and regional boards. The VRS ranks rosters, not organisations, so an organisation whose new and previous lineups are both ranked appears twice: the lower entry carries alsoRankedAt.
CS2 Teams API
Team profiles by id or slug ("vitality", "natus-vincere"): roster and roster history, results, upcoming matches, form, map stats, head-to-head and a map-by-map comparison of two teams. Up to 50 teams in one call with ?ids=.
CS2 Player Stats API
Player profiles by id or slug ("donk", "zywoo"): headline stats, career and seasons, map and weapon splits, clutches and flash assists, form and team history.
CS2 Tournaments API
Tournaments and events (the two route families are equivalent): calendar, participants, matches, standings, brackets, results and event-level stats.
CS2 Stats and Leaderboards API
Aggregated leaders and scene-wide stats: leaderboards by metric, and deep dives into duels, clutches, utility and economy.
CS2 Skin Prices API
The skin market: search and filter skins, compare prices across marketplaces, read order books and price history, and track movers.
CS2 Transfers API
Roster moves across the scene, filterable by player, team, status and date range.
CS2 Search and Reference API
Search across teams, players, events and matches, the reference catalogs, webhook event types and freshness endpoints.

Endpoints

GET/api/v1/cs2/live
Live MatchesMatches in progress: series score, map in play, map score and round.

Summary

Matches in progress: series score, map in play, map score and round.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/live" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/live/{matchId}/state
StateOne live match: round, round score, sides, players, bomb.

Summary

One live match: round, round score, sides, players, bomb.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/live/{matchId}/state" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/live/stream
StreamServer-Sent Events push of live updates. Every plan; billed like polling (see below).

Summary

Server-Sent Events push of live updates. Every plan; billed like polling (see below).

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/live/stream" \
  -H "x-api-key: YOUR_API_KEY"
WS/api/v1/cs2/live/ws
WsWebSocket with a room per match: snapshot on subscribe, then every score, round, map and bomb change. Live WebSockets plans.

Summary

WebSocket with a room per match: snapshot on subscribe, then every score, round, map and bomb change. Live WebSockets plans.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/live/ws" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/matches/upcoming
Upcoming ScheduleThe schedule, soonest first. Add ?include=odds for each match's bookmaker odds in the same call, ?bestOf=3 for BO3s only.

Summary

The schedule, soonest first. Add ?include=odds for each match's bookmaker odds in the same call, ?bestOf=3 for BO3s only.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/matches/upcoming" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/matches/past?bestOf=3
PastFinished matches, newest first: last 7 days by default, ?days= up to 90 or ?from=/?to=. bestOf=1, 3 or 5 keeps one series length.

Summary

Finished matches, newest first: last 7 days by default, ?days= up to 90 or ?from=/?to=. bestOf=1, 3 or 5 keeps one series length.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/matches/past?bestOf=3" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/matches/recent
Recent MatchesLatest results with every map and its score.

Summary

Latest results with every map and its score.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/matches/recent" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/matches/{matchId}
MatchIdOne match: maps, veto, event, streams.

Summary

One match: maps, veto, event, streams.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/matches/{matchId}" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/matches/{matchId}/player-stats
Player StatsPer-map player lines: kills, deaths, assists, ADR, KAST, rating.

Summary

Per-map player lines: kills, deaths, assists, ADR, KAST, rating.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/matches/{matchId}/player-stats" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/maps/{mapId}/economy
EconomyRound-by-round economy per player: start money, spend, equipment value, buy type, purchases.

Summary

Round-by-round economy per player: start money, spend, equipment value, buy type, purchases.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/maps/{mapId}/economy" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/props?market=kills_maps_1_2
PropsPick'em player props (Underdog, Sleeper): kills and headshots on maps 1-2, graded L5/L10. Pro and above.

Summary

Pick'em player props (Underdog, Sleeper): kills and headshots on maps 1-2, graded L5/L10. Pro and above.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/props?market=kills_maps_1_2" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/matches/{matchId}/props
PropsOne match's prop lines, every app side by side with the spread between them.

Summary

One match's prop lines, every app side by side with the spread between them.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/matches/{matchId}/props" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/teams/{teamIdOrSlug}
TeamIdOrSlugTeam profile, current roster (players and coach) and recent results.

Summary

Team profile, current roster (players and coach) and recent results.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/teams/{teamIdOrSlug}" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/teams?ids=vitality,mouz,spirit
List TeamsUp to 50 teams in one call (also /players and /matches); one request per 10 ids.

Summary

Up to 50 teams in one call (also /players and /matches); one request per 10 ids.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/teams?ids=vitality,mouz,spirit" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/teams/{teamIdOrSlug}/map-pool/vs/{opponentIdOrSlug}
OpponentIdOrSlugTwo teams map by map: win rates, pick/ban rates, head-to-head maps and the edge.

Summary

Two teams map by map: win rates, pick/ban rates, head-to-head maps and the edge.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/teams/{teamIdOrSlug}/map-pool/vs/{opponentIdOrSlug}" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/players/{playerIdOrSlug}
PlayerIdOrSlugPlayer profile and current team.

Summary

Player profile and current team.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/players/{playerIdOrSlug}" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/players/{playerIdOrSlug}/stats
PlayerIdOrSlug StatsCareer totals and per-map stat lines.

Summary

Career totals and per-map stat lines.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/players/{playerIdOrSlug}/stats" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/rankings
RankingsWorld ranking. Add ?source=vrs for Valve's VRS ranking.

Summary

World ranking. Add ?source=vrs for Valve's VRS ranking.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/rankings" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/rankings/vrs?before=2025-06-02
VrsVRS as it stood before a date, back to August 2024 (pre-match rankings for models).

Summary

VRS as it stood before a date, back to August 2024 (pre-match rankings for models).

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/rankings/vrs?before=2025-06-02" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/events/upcoming
Upcoming ScheduleTournaments starting soon. Also /events/live and /events/recent.

Summary

Tournaments starting soon. Also /events/live and /events/recent.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/events/upcoming" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/search?q=vitality
SearchTeams, players, events and matches by name.

Summary

Teams, players, events and matches by name.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/search?q=vitality" \
  -H "x-api-key: YOUR_API_KEY"
GET/api/v1/cs2/autocomplete?q=vit
AutocompleteTypeahead: up to 10 best matches in a few KB. ?expand=full for the full search shape.

Summary

Typeahead: up to 10 best matches in a few KB. ?expand=full for the full search shape.

REST
Bash
curl "https://api.citoapi.com/api/v1/cs2/autocomplete?q=vit" \
  -H "x-api-key: YOUR_API_KEY"

These are the main ones. Every CS2 route, with its parameters and a real example response, is in the OpenAPI document (tag CS2).

Filter by series length (BO1, BO3, BO5)

Add bestOf to any CS2 match list to keep one series length: 1, 3, 5, or a comma list such as 3,5. The filter runs before paging, so limit, page and meta.total count only matching matches. Any other value returns 400 INVALID_BEST_OF.

Bash
# Upcoming BO3 matches
curl "https://api.citoapi.com/api/v1/cs2/matches/upcoming?bestOf=3" \
  -H "x-api-key: YOUR_API_KEY"

# Finished BO3 matches from the last 30 days
curl "https://api.citoapi.com/api/v1/cs2/matches/past?bestOf=3&days=30" \
  -H "x-api-key: YOUR_API_KEY"

# The last BO3 between two teams
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/matches?opponent=mouz&type=completed&bestOf=3&limit=1" \
  -H "x-api-key: YOUR_API_KEY"

bestOf works on /cs2/matches, /matches/upcoming, /matches/past, /matches/results, /matches/today, /cs2/live, team match lists (/teams/{team}/matches, /upcoming, /results), head-to-head (/h2h/{team}/{opponent}), event match lists and /players/{player}/matches. Your plan's history window still applies to past matches.

Live data

Poll GET /cs2/live for everything in progress, then GET /cs2/live/{matchId}/state for one match. In the live list, score is the series (maps won) and currentMapScore is the map being played.

Push instead of polling. GET /cs2/live/stream sends every update as it happens (Server-Sent Events, add ?matchId= to follow one match). An open stream counts toward your monthly quota like polling: one request when it connects, then one for every 15 seconds it stays open. When the quota runs out it sends an error event and closes.

Bash
curl -N "https://api.citoapi.com/api/v1/cs2/live/stream" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Accept: text/event-stream"

If full live tracking goes quiet for a match, a backup takes over within about a minute. The state then carries the series score and the map in play, without rounds or players, until full tracking returns.

Live WebSocket

wss://api.citoapi.com/api/v1/cs2/live/ws pushes the same events as the SSE stream (score, round, map and bomb changes) to one socket, with a room per match. Frames don't count toward your monthly requests. Included on Scale and Enterprise; on Pro with the Live WebSockets add-on (+$15/mo). Turn it on and test it from Dashboard → WebSockets.

  • Auth: your API key in the x-api-key header, Authorization: Bearer YOUR_API_KEY, or ?apiKey= (browsers can't set headers on a WebSocket; proxy through your server so the key stays private).
  • Subscribe: {"action":"subscribe","rooms":["match:cs2-match-2400024"]}, or "rooms":["all"] for every live match. Up to 32 rooms per connection. unsubscribe takes the same shape; {"action":"ping"} answers with pong.
  • Shortcut: ?matchId=cs2-match-2400024 or ?rooms=match:cs2-match-2400024,all on the URL subscribes at connect.
TypeScript
import WebSocket from "ws";

const ws = new WebSocket("wss://api.citoapi.com/api/v1/cs2/live/ws", {
  headers: { "x-api-key": process.env.CITO_API_KEY },
});

ws.on("message", (raw) => {
  const msg = JSON.parse(String(raw));
  if (msg.type === "ready") {
    ws.send(JSON.stringify({ action: "subscribe", rooms: ["match:cs2-match-2400024"] }));
  }
  // subscribed | cs2.live.snapshot | cs2.live.update | ping | pong | error
  console.log(msg.type, msg);
});

Messages from the server:

  • ready: sent first, with stream: "cs2.live", the rooms you hold and the message formats.
  • subscribed / unsubscribed: the rooms you now hold.
  • cs2.live.snapshot: once per match room when you subscribe. team1, team2, seriesScore, currentMap, currentRound, roundScore, roundTimeSeconds, bombPlanted and players.
  • cs2.live.update: every change. matchId, status, team1Score / team2Score (rounds on the current map), currentMap, currentRound, roundTimeSeconds, bombPlanted, playerStatsChanged and capturedAt. When playerStatsChanged is true, fetch GET /cs2/live/{matchId}/state for the new player lines.
  • ping every 15 seconds, and error with a code (BAD_ROOMS, INVALID_JSON, UNKNOWN_ACTION) for a message it can't use.

A refused connection gets an HTTP error instead of the upgrade: 401 MISSING_API_KEY or 401 INVALID_API_KEY, and 403 WEBSOCKETS_REQUIRED when your plan doesn't include Live WebSockets. The SSE stream above works on every plan.

Plans

Choose a plan or read rate limits and pricing.

Was this page helpful?