CS2 match history API.
Series, maps, and gamelogs you can grade on.

You're trying to answer a simple question with messy data. A player says the line moved, your dashboard says the match never existed, and the replay you need is already gone from the easiest place to check. That's the normal state of CS2 match history work — and why treating history as a UI feature falls apart the moment you need to backtest, reconcile, or grade anything with consequences.

Why CS2 match history needs a schema

Many teams hit the same wall. Source fragmentation — Steam, HLTV, trackers, and book feeds disagree on keys. Roster churn — free-text joins rot. Retention gaps — client history only keeps recent sessions. A CS2 match history API exists to turn that mess into predictable joins.

What the schema layer protects

The schema does not fix upstream politics. It anchors identity, status, and timing so a query next month still resolves the same series and player.

Practical rule: never let a dashboard query free-text team names across providers. Normalize first, then display.

What a CS2 match record represents

A match is not one row. It is a series container with teams, start time, and one or more map children. One demo maps to one map — a BO3 can produce two or three map records.

Parent series and child maps

Series carries winner, scores, and status. Map gamelogs carry kills, ADR, headshots, and map name — the fields you grade player props on.

What not to blur together

  • Do not treat match_id and map/game_id as interchangeable.
  • Do not grade map-1 kills from series score alone.
  • Do not assume a nickname is a stable join key.

Core match history endpoints

Production paths under /v6/esports/cs2/ plus vault history. Prefer explicit status filters over boolean is_live flags.

EndpointPurposeKey filters
GET /v6/esports/cs2/matchesList upcoming / live / completed seriesstatus, start_date, end_date, limit, offset
GET /v6/esports/cs2/completed/matchesCompleted series board
GET /v6/esports/cs2/players/{slug}/gamelogsMap-level player historylimit
GET /v6/esports/history/contractQuote tape for a prop/bookprop_id, book, market_key
GET /v6/esports/cs2/resultsSettled prop outcomes

Canonical IDs

  • kr_match_id — stable series id
  • canonical player / team ids under display names
  • game_id / map_number on gamelog rows for map scope
  • propId when joining history to the live board
Practical rule: use display names only at the edge, after the join through canonical IDs.

Sample JSON (live production)

Live production shapes below — completed series list, then a ZywOo map gamelog. Second sample path: GET /v6/esports/cs2/players/zywoo/gamelogs?limit=1.

{
  "source": "kashrock",
  "player_slug": "zywoo",
  "sport": "cs2",
  "gamelogs": [
    {
      "eventId": "evt_5b9ccf97693b8027",
      "game_id": "182135",
      "map_name": "Mirage",
      "map_number": 2,
      "begin_at": "2026-09-05T18:01:30+00:00",
      "map_winner": "MOUZ",
      "nickname": "ZywOo",
      "team": "Vitality",
      "opponent": "MOUZ",
      "kills": 21,
      "deaths": 14,
      "assists": 2,
      "headshots": 9,
      "adr": 97.1,
      "first_kills": 2
    }
  ]
}
FieldExampleUsed for
kr_match_idkr_cs2_imperial-vs-…Stable series reference
statusfinishedGrading / cache finalization
event_timeISO-8601 UTCArchive filters
team1 / team2 / score*Imperial / DENDELE / 0-2Series result
gamelogs[].map_nameMirageMap-level analysis
gamelogs[].kills21Prop evaluation
gamelogs[].adr97.1Secondary metrics
GET /v6/esports/cs2/matches?status=completed&limit=1
{
  "source": "kashrock",
  "sport": "cs2",
  "status": "completed",
  "matches": [
    {
      "kr_match_id": "kr_cs2_imperial-vs-dendele-cs-11-09-2026",
      "slug": "imperial-vs-dendele-cs-11-09-2026",
      "status": "finished",
      "event_time": "2026-09-11T20:20:00.000+00:00",
      "team1": "Imperial",
      "team2": "DENDELE",
      "score1": 0,
      "score2": 2,
      "winner_id": 24956
    }
  ]
}

Comparing match history sources

Steam for personal recent matches. HLTV for curated event truth. Trackers for round detail. A normalized CS2 match history API when you need one schema for backtests and grading.

SourceSchemaBest use
Steam in-game historyLow–moderatePersonal recent matches
HLTV curated recordsHigh for eventsTournament truth
TrackersVariesPer-round dashboards
KashRock CS2 match history APIHigh by designBacktests, grading, models

Prop verification from history

  • Bind propId + book + line + direction at placement
  • Resolve against finalized map gamelogs
  • Terminal states: hit / miss / push / unmatched
Practical rule: don't grade from screenshots. Grade from the finalized map record and store evidence beside it.

Operational practices

  • Separate live polls from archive backfills
  • Cache completed series longer than live boards
  • Stamp fetched_at on stored payloads for audits
  • Pair match history with history/contract for line tape

Quick reference

Series → /matches. Maps → /players/{slug}/gamelogs. Lines over time → /history/contract. Full CS2 surface: CS2 API reference.

If you need a normalized feed instead of another UI wrapper, KashRock exposes live boards, schedules, and history on one schema — with the IDs and outcome patterns that keep backtests and grading honest. Start free on Sandbox, or see published pricing.

Frequently asked questions

What is a CS2 match history API?

An API that returns completed and historical Counter-Strike 2 series plus map-level player stats (gamelogs) with stable IDs — so you can backtest and grade without scraping HLTV or Steam UIs.

Does KashRock separate series from maps?

Yes. Matches endpoints return the series container (teams, scores, status). Player gamelogs return per-map rows (map name, kills, ADR, etc.) keyed for joins.

Can I grade DFS props from match history?

Yes. Bind propId + book + line at placement, then resolve against finalized map gamelogs and results — hit, miss, or push.

Is this the same as the historical quote tape?

Related but different. Match history = what happened on the server. history/contract = what line the book posted over time. You usually need both for honest backtests.