CS2 data reference

Player depth

Weapons, grenades, hitgroups, duels and flashes — the deepest layer, and the least universal.

GET /v1/{game}/matches/{id}/depth returns a single object containing five arrays. Each is [] when unavailable, never null.

This is the least universally available layer — check data_available.depth on the match, or filter the match list with ?has=depth, before requesting it.

weapons

One row per player per weapon per side they held it on, so a player who used an AK-47 on both sides appears twice.

weapon_slug (ak-47) is the stable key to group on; weapon_name (AK-47) is for display; weapon_class buckets it (Rifle, Pistols, SMG, Heavy, Grenade, Equipment, or an empty string where the source didn't classify it).

Counters: shots, hits, kills, headshots, damage, wall_bangs, trade_kills. hits/shots is an accuracy rate — guard the zero denominator, since a weapon can be equipped without being fired.

grenades

One row per player per grenade type per side: throws, hits, kills, owns. grenade_name is one of Flashbang, Smoke Grenade, HE Grenade, Molotov, Incendiary Grenade or Decoy Grenade.

hitgroups

Where shots landed: hit_group — one of Head, Chest, Stomach, LeftArm, RightArm, LeftLeg, RightLeg, Gear or Generic — with hits, damage and kills whose finishing shot landed there.

duels

One row per ordered (killer, victim) pair, match-level. A mutual rivalry is two rows — swap the ids to find the reverse direction.

kills is how many times the killer killed the victim; weapon_names is a comma-separated string in kill order.

flashes

One row per ordered (flasher, flashed) pair. Self-flashes are real rows where flasher_player_id == flashed_player_id — they are recorded, not filtered, and dropping them is a decision you should make deliberately.

count is how many times; duration_ns is total blind time in nanoseconds — divide by 1e9 for seconds. It's an int64 because a match total exceeds 32-bit range.

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

for f in depth["flashes"]:
    if f["flasher_player_id"] == f["flashed_player_id"]:
        continue  # self-flash
    print(f"{f['flasher_player_id']} blinded {f['flashed_player_id']} "
          f"{f['count']}× for {f['duration_ns'] / 1e9:.1f}s")

Everything here is match-level

None of the five arrays carry map_number — the upstream exposes them per match, not per map. If you need per-map weapon usage, that isn't available.

On this page