CS2 data reference

Round stats

Two rows per round, the signed economy tier, and what each counter measures.

GET /v1/{game}/matches/{id}/rounds returns two rows per round — one per team. Exactly one has won: true.

Join to a map with (match_id, map_number); rounds are numbered from 1 within a map and overtime keeps counting up, so round 25+ on a standard map is overtime rather than a restart.

economy_level is a signed tier, not a sentinel

economy_level can be negative, and a negative value is meaningful. It is a signed classification of the buy — eco and force-buy rounds sit below zero. It is not a missing-data sentinel, and filtering out negatives silently discards every eco round, which is usually the exact population an economy analysis is about.

Read it alongside equipment_value, enemy_equipment_value and money_spent — the raw dollar figures, with the opponent's value denormalised onto the same row so you can judge the buy matchup without a join.

Sides

team_side is lowercase ct or t. Sides swap at the half, so a team's side changes partway through a map — never assume a team's side from the map alone.

pistol_round flags round 1 and the second-half opener.

Counters

All integers, never null:

FieldMeaning
kills / deaths / assistsTeam totals for the round. deaths is 0–5.
damage, headshotsDamage dealt; how many kills were headshots.
first_kills / first_deathsOpening duel. Across a round's two rows these sum to 0 or 1.
trade_kills / trade_deathsTrade discipline — a kill that avenged a teammate who just died, and a death that was subsequently traded.
clutches / clutch_attemptsWon, and reached. Divide for a conversion rate — guard the zero denominator.
bomb_plants / bomb_defuses0 or 1. Plants are always 0 on the CT side, defuses always 0 on the T side.
flash_assists, utility_valueKills enabled by blinding; dollar value of grenades used.
kastA count of 0–5 players who contributed — not a percentage.

Rebuilding a scoreline

rounds = get(f"/v1/cs2/matches/{match_id}/rounds")["data"]

from collections import Counter
score = Counter(r["team_id"] for r in rounds if r["won"] and r["map_number"] == 1)

That should reconcile with map 1's score_a/score_b from map results. If it doesn't, you're probably summing across maps.

On this page