BetaRead the CS2 API docs

Historical CS2 data for your model.

Every finished pro match with its veto, maps and per-player lines (kills, deaths, ADR, KAST, rating, opening kills, headshots), the world ranking and VRS as they stood on any past date, and the odds and prop lines with every price change. Pull it over the API, or ask for a one-time CSV export.

  • 32,222 finished matches
  • 723,564 player-map lines
  • CSV export on request
GET /cs2/players/zywoo/matches?limit=1200 OK
$ curl "https://api.citoapi.com/api/v1/cs2/players/zywoo/matches?limit=1" \ -H "x-api-key: $CITO_API_KEY"
{  "success": true,  "data": [    {      "matchId": "cs2-match-2399758",      "playerName": "ZywOo",      "teamName": "Vitality",      "kills": 7,      "deaths": 14,      "adr": 46.9,      "kast": 0.65,      "rating": 0.76,      "headshotPercent": 0.4286,      "firstKills": 1,      "map": {        "mapName": "Inferno",        "team1Score": 7,        "team2Score": 13,        "match": {          "eventName": "PGL Masters Bucharest 2026",          "team1Name": "Vitality",          "team2Name": "MOUZ"        }      }    }  ]}

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

How much historical CS2 data is there?

32,222 finished matches and 723,564 per-map player stat lines across 67,149 maps and 8,532 players, counted on 9 November 2026. Coverage is dense from 2023, when CS2 launched, with a smaller set of earlier matches back to 2017.

ADR and KAST are filled on 99.4% of player-map lines, rating on 97.9%, opening kills and headshots on about 94%.
YearFinished matchesMaps with per-player stats
2026 (to 9 Nov)10,02421,245
202510,24521,735
20249,20618,258
20232,3175,151
2017 to 2022430760

What tables can I build from it?

The same tables every CS2 model ends up with. Each one is a GET, keyed by stable ids, so a nightly job can extend them without duplicates.

TableColumnsEndpoint
matchesmatch_id, date, event, tier, best_of, teams, series score, winner, vetoGET /cs2/matches/results?date_start=&date_end=
mapsmap_id, map, number, picked by, score, halves, winnerGET /cs2/matches/{matchId}/maps
player_map_statskills, deaths, assists, ADR, KAST, rating, headshots, opening kills and deaths, with CT and T side splits where recordedGET /cs2/matches/{matchId}/player-stats
rounds and economyround winner, side, how it ended, team buy per roundGET /cs2/maps/{mapId}/rounds and /economy
rankingsrank and points per team on a given date (no look-ahead)GET /cs2/rankings/world?date=2025-06-02 and /cs2/rankings/vrs
rosterswho played for whom, with datesGET /cs2/teams/{slug}/roster-history
oddsmatch and map winner prices, every change since 16 Oct 2026GET /cs2/matches/{matchId}/odds/history
prop lineskills and headshot lines with every line change since 26 Oct 2026GET /cs2/props?status=all&include_history=true

How do I load it into pandas?

Walk the results one day at a time, then fetch each match's player lines. This builds a player-map table you can save as Parquet and extend each night.

load_cs2_history.py
import os, datetime as dt, requests, pandas as pd

API = "https://api.citoapi.com/api/v1"
S = requests.Session()
S.headers["x-api-key"] = os.environ["CITO_API_KEY"]

def get(path, **params):
    r = S.get(API + path, params=params, timeout=30)
    r.raise_for_status()
    return r.json()["data"]

rows = []
day, end = dt.date(2025, 1, 1), dt.date(2025, 1, 31)
while day <= end:
    for m in get("/cs2/matches/results", date_start=day.isoformat(), date_end=day.isoformat(), limit=100):
        for p in get(f"/cs2/matches/{m['id']}/player-stats") or []:
            rows.append({"match_id": m["id"], "date": m["startsAt"], "event": m["eventName"],
                         "best_of": m["bestOf"], "winner": m["winnerTeamId"],
                         **{k: p.get(k) for k in ("mapId", "playerId", "playerName", "teamId", "kills", "deaths",
                                                  "assists", "adr", "kast", "rating", "headshots", "firstKills",
                                                  "firstDeaths", "ctRating", "tRating")}})
    day += dt.timedelta(days=1)

df = pd.DataFrame(rows)
df.to_parquet("cs2_player_maps_2025_01.parquet")
print(len(df), "player-map rows")

How do I avoid look-ahead bias?

Use values as they stood before the match. Rankings take a date parameter and return the table on or before that day, odds history marks each price with capturedAt, and prop lines carry recordedAt on every change, so features can be cut at kick-off.

Can I get it as one CSV file instead?

Yes. If you would rather start from a file than from 30,000 API calls, we run a one-time export of the matches, maps and player lines you need (by date range, tier or team) as CSV or Parquet. Pricing depends on the size of the extract: email support@citoapi.com with what you need.

Endpoints you can ship with

Start on results: finished matches, their maps, and each player's line.

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

Depth, plans, exports and backtesting

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

Read the CS2 docs

Train match models

Pull a month on a free key, then open the full archive on Pro.