CS2 API reference.
Props, history, and IDs that survive roster churn.

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 book board you need is already gone. That's the normal state of CS2 integration work — and why treating props and match history as UI scrapes falls apart the moment you need to backtest, reconcile, or grade anything with consequences.

Why a CS2 API needs a schema

Many teams hit the same wall for different reasons. The first problem is source fragmentation — the same CS2 event can appear in a DFS app, a sportsbook, HLTV, and a tracker, but none share a key you can trust downstream. The second is roster churn — team tags and handles change often enough that free-text joins degrade. The third is retention gaps— yesterday's PrizePicks line is gone from the app, so scrapers that worked last month fail when you need a backtest.

What the schema layer protects

A schema does not fix upstream politics. It gives every downstream consumer one place to anchor identity, status, and timing — so a query next month still resolves the same player even if they renamed their profile.

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

A good CS2 API schema survives three things: roster churn, partial board coverage, and source disagreement. If your model can't handle all three, it's too thin for production.

What a CS2 record actually represents

A lot of integrations fail because they treat a match like one row. In practice the record is a series container with two teams, a start time, and one or more map children. Player props hang off that series with map scope (map 1, maps 1–2, etc.) — which is why collapsing everything into a single object makes grading and backtests drift.

Series, maps, and player lines

Model the series as the parent, maps as children, and prop offers as book-native lines joined by canonical event and player IDs. Series carries overall status and timing. Maps carry the granular fields you grade on. Props carry the line the book actually posted.

What not to blur together

  • Do not treat match_id and map scope as interchangeable.
  • Do not grade a map-1 kill line from series totals alone.
  • Do not assume a display nickname is a stable join key.

Core CS2 endpoints

A normalized provider should expose endpoint families that match how developers work. Live boards start with props. Schedule and live products need matches. Backtests need gamelogs and history. The shapes below are the production KashRock paths under /v6/esports/cs2/.

Each response should stay boring for client code: the same envelope, UTC timestamps, and explicit status — not a pile of boolean flags that hide delayed or forfeited series.

EndpointPurposeKey filters
GET /v6/esports/cs2/propsLive DFS + book player propsbook, market, market_contains
GET /v6/esports/cs2/matchesSchedule / live / completed seriesstatus, start_date, end_date, limit
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/linesConsensus fair odds (Hobby+)

Canonical IDs for players, teams, and matches

Identifiers decide whether historical joins stay reliable or drift apart. Steam persona names change, team pages get reworked after roster moves, and book labels often stop matching the underlying entity. KashRock mints kr_prop_*, kr_pl_*, and canonical event/team IDs so the join survives the rename.

  • propId — stable contract across books for the same player/market/event
  • canonical_player_id — one person through handle changes
  • canonical_event_id / matchup_key — series join when book event IDs diverge
  • stat_type — sport-prefixed keys like CS2_KILLS_MAPS_1_2
Practical rule: use display names only at the edge, after the join has been resolved through canonical IDs.

Sample JSON for a live CS2 prop

A useful payload is not a raw book dump. It's a normalized object with the fields you need to shop lines, build pick'ems, and grade later — pulled live from production, not invented for the docs.

FieldExampleUsed for
props[].propIdkr_prop_14e79be2b6bcStable contract key across books
props[].stat_typeCS2_KILLS_MAPS_1_2Sport-prefixed, map-scoped market
props[].line26.5Book threshold you grade against
props[].directionoverSide of the market
props[].odds-137American price on the offer
props[].book_namePrizePicksVenue that posted the line
props[].event_timeISO-8601 UTCSeries start for joins
GET /v6/esports/cs2/props
{
  "source": "kashrock",
  "sport": "cs2",
  "props": [
    {
      "propId": "kr_prop_14e79be2b6bc",
      "player_name": "n1ssim",
      "stat_type": "CS2_KILLS_MAPS_1_2",
      "line": 26.5,
      "odds": -137,
      "direction": "over",
      "team": "Legacy",
      "book_name": "PrizePicks",
      "event_time": "2026-09-12T06:00:00.000Z",
      "links": {
        "market": "https://app.prizepicks.com/?projections=14751913-o-26.5"
      }
    }
  ]
}

Comparing CS2 data sources

Choose your CS2 source by query shape: recent personal matches, audit-grade event records, or schema-normalized ingestion — instead of assuming one site covers every workflow.

SourceSchemaBest use
Book app / scrapeFragile, no historyToday's board only
HLTV / trackersHigh for results, not book linesPost-match truth
Raw provider feedsOne venue, one shapeSingle-book tools
KashRock CS2 APINormalized by designProps, models, grading, backtests

Prop verification and outcome status

Grading a prop is a join with sharper consequences. Bind the ticket to propId, book, line, and direction at placement, then resolve against finalized map stats.

  • Hit / miss — the canonical map record contained the stat and the line resolved.
  • Push — the stat landed exactly on the threshold.
  • Unmatched / void — the map or player could not be found; do not invent a grade.
Practical rule: don't grade from screenshots or partial text logs. Grade from the finalized map record, then store the raw evidence beside it.

Operational practices

  • Separate live board polls from archive backfills — they fail differently.
  • Cache completed records longer; keep live boards on a short TTL.
  • Stamp objects with fetched_at and verification status for audits.
  • Prefer path-style GET /v6/esports/cs2/props over slow query-string aliases.

Quick reference

Keep this open beside your IDE: propId stays stable across books, stat_type is sport-prefixed and map-scoped, timestamps are UTC, and Sandbox lets you prove the schema before you pay. Full route index: docs 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 does the KashRock CS2 API cover?

Live player props (kills, headshots, map-scoped lines), matches, player gamelogs, history/contract quote tape, and Hobby+ consensus lines — one schema across PrizePicks, Underdog, Betr, Sleeper, Boom, Pick6, Thunderpick, Kalshi, and Polymarket.

Is there a free CS2 API tier?

Yes. Sandbox is $0/mo with an instant key for CS2 props so you can verify the schema before paying. Paid plans start at $29/mo.

How are CS2 kill markets named?

Sport-prefixed, stat-first keys like CS2_KILLS_MAP_1 and CS2_KILLS_MAPS_1_2 — not ESPORTS_* or wrong-order forms. That keeps joins stable across books.

Can I grade props from match history?

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