Docs/CS2 API/CS2 Matches API

CS2 Matches API

Schedules, results and everything recorded about a single series: maps played, player stats per map, lineup form, head-to-head history, streams and demo links.

19 endpoints in this section. Authenticate with the x-api-key header; every response is { success, data, meta }. Other sections: Live, Player props, Odds, Positions & heatmaps, Watch live (embeds), Pro skins & 3D, Maps & rounds, Rankings, Teams, Players, Events, Stats & leaderboards, Skins, Transfers, Search & reference.

Today's matches

GET/api/v1/cs2/matches/today

Matches scheduled, live or finished today (UTC). **Conditional GET:** the response carries a weak `ETag` that changes only when the data does (not on every poll). Send it back as `If-None-Match` and an unchanged list returns `304 Not Modified` with no body (works from browser `fetch()` too; `Cache-Control: private, no-cache`). The tag is of what your plan receives (delayed plans have their own tags). A 304 is free: it does not count toward your monthly quota and writes no usage row (it still takes one per-minute rate-limit slot).

Query parameters

ParameterTypeDescription
bestOfstringOnly matches of this series length: 1, 3 or 5, or a comma list (3,5). bestOf=3 returns BO3 matches only; paging and totals count the filtered rows. Any other value is 400 INVALID_BEST_OF.
daysintegerLook-back window in days.
eventstringEvent id or slug.
eventIdstringFilter by eventId.
event_idstringFilter by event_id.
expandstringFilter by expand.
fieldsstringComma-separated list of fields to return.
fromstringStart of the date range (ISO 8601, UTC).
includestringodds adds every match's bookmaker odds (odds[], the same rows as /cs2/matches/{matchId}/odds, series winner h2h first); see below. player_props adds playerProps[]: the match's open pick'em lines per player and market, every provider side by side with lineSpread (same access as odds). Combine with a comma: include=odds,player_props.
limitintegerRows to return. Maximum 200; larger values are reduced to 200.
offsetintegerRows to skip, for paging.
orderstringFilter by order.
pageintegerPage number, starting at 1.
playerIdstringPlayer id or slug.
player_idstringPlayer id or slug.
sortstringSort order.
statusstringFilter by status.
summarybooleantrue returns a summary instead of full rows.
teamstringTeam id or slug.
teamIdstringTeam id or slug.
team_idstringTeam id or slug.
tostringEnd of the date range (ISO 8601, UTC).
viewstringFilter by view.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/today" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": [
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2400104",
      "eventId": "cs2-event-9470",
      "eventName": "CCT 2026 South America Series 8",
      "eventSlug": "cct-2026-south-america-series-8",
      "stageName": null,
      "startsAt": "2026-11-11T22:00:00.000Z",
      "endsAt": null,
      "bestOf": 3,
      "status": "upcoming",
      "team1Id": "cs2-team-13902",
      "team2Id": "cs2-team-14008",
      "team1Name": "BORRACHEIROS",
      "team2Name": "your end",
      "team1Score": null,
      "team2Score": null,
      "winnerTeamId": null,
      "vetoOrder": [
        {
          "map": "ancient",
          "order": 1,
          "action": "pick",
          "teamId": null,
          "teamName": null,
          "mapName": "ancient",
          "mapNumber": null,
          "played": false
        },
        {
          "map": "ancient",
          "order": 2,
          "action": "pick",
          "teamId": null,
          "teamName": null,
          "mapName": "ancient",
          "mapNumber": null,
          "played": false
        }
      ],
      "lastSyncedAt": "2026-11-11T12:47:38.699Z",
      "lastVerified": "2026-11-11T12:47:38.699Z",
      "confidence": "high",
      "event": {
        "id": "cs2-event-9470",
        "name": "CCT 2026 South America Series 8",
        "slug": "cct-2026-south-america-series-8",
        "imageUrl": null,
        "prizePool": 15000,
        "currency": "USD",
        "tier": "B",
        "prestigeScore": 55,
        "status": "live",
        "region": null,
        "startsAt": "2026-11-03T00:00:00.000Z",
        "endsAt": "2026-11-15T23:59:59.000Z",
        "eventId": "cs2-event-9470",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/6576d7901af03eaa076d5fb65af3cc14.webp",
        "bannerImageUrl": null
      },
      "team1": {
        "id": "cs2-team-13902",
        "name": "BORRACHEIROS",
        "slug": "borracheiros",
        "teamTag": "BORRACHE",
        "logoUrl": null,
        "countryName": "Brazil",
        "countryCode": "BR",
        "worldRanking": 152,
        "worldRankingStatus": "ranked",
        "vrsRanking": 179,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Americas",
        "logoIsPlaceholder": true
      },
      "team2": {
        "id": "cs2-team-14008",
        "name": "your end",
        "slug": "your-end",
        "teamTag": "YOUREND",
        "logoUrl": null,
        "countryName": "Brazil",
        "countryCode": "BR",
        "worldRanking": 220,
        "worldRankingStatus": "ranked",
        "vrsRanking": 262,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Americas",
        "logoIsPlaceholder": true
      },
      "…": "17 more fields"
    },
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2400103",
      "eventId": "cs2-event-9470",
      "eventName": "CCT 2026 South America Series 8",
      "eventSlug": "cct-2026-south-america-series-8",
      "stageName": null,
      "startsAt": "2026-11-11T19:00:00.000Z",
      "endsAt": null,
      "bestOf": 3,
      "status": "upcoming",
      "team1Id": "cs2-team-13029",
      "team2Id": "cs2-team-13912",
      "team1Name": "RED Canids Academy",
      "team2Name": "Grêmio",
      "team1Score": null,
      "team2Score": null,
      "winnerTeamId": null,
      "vetoOrder": [
        {
          "map": "ancient",
          "order": 1,
          "action": "pick",
          "teamId": null,
          "teamName": n
…

Past matches

GET/api/v1/cs2/matches/past

Finished matches, newest first, with date-range filters. Only one series length: `?bestOf=3` (BO3), `?bestOf=1`, `?bestOf=5` or `?bestOf=3,5`. Each finished match carries resultType (played, forfeit = nothing played and the series awarded, partial_forfeit = some maps played and the rest conceded), isForfeit and forfeitedMaps. An awarded (forfeit) map is served `status: "completed"` with `resultType: "forfeit"`, `isForfeit: true` and `forfeitStage`: `before_start` (awarded before a round was played: `playerStats: []`, `roundsPlayed: 0`) or `mid_map` (forfeited part-way through: player stats, rounds and events are served as for any played map, `roundsPlayed` = rounds on record); `forfeitStage` is null on maps that were not forfeited. A map that was not played is `status: "map_not_played"` and never names a winner.

Query parameters

ParameterTypeDescription
bestOfstringOnly matches of this series length: 1, 3 or 5, or a comma list (3,5). bestOf=3 returns BO3 matches only; paging and totals count the filtered rows. Any other value is 400 INVALID_BEST_OF.
date_endstringSame as to.
date_startstringSame as from.
daysintegerLook-back window in days (default 7, max 90). Ignored when from or to is given.
eventstringEvent id or slug.
eventIdstringFilter by eventId.
event_idstringFilter by event_id.
expandstringFilter by expand.
fieldsstringComma-separated list of fields to return.
fromstringStart of the date range (YYYY-MM-DD or ISO 8601, UTC). Alias date_start.
includestringodds adds every match's bookmaker odds (odds[], the same rows as /cs2/matches/{matchId}/odds, series winner h2h first); see below. player_props adds playerProps[]: the match's open pick'em lines per player and market, every provider side by side with lineSpread (same access as odds). Combine with a comma: include=odds,player_props.
limitintegerRows to return. Maximum 200; larger values are reduced to 200.
offsetintegerRows to skip, for paging.
orderstringFilter by order.
pageintegerPage number, starting at 1.
playerIdstringPlayer id or slug.
player_idstringPlayer id or slug.
sortstringSort order.
statusstringFilter by status.
summarybooleantrue returns a summary instead of full rows.
teamstringTeam id or slug.
teamIdstringTeam id or slug.
team_idstringTeam id or slug.
tostringEnd of the date range (YYYY-MM-DD or ISO 8601, UTC); a date-only value includes that whole day. Alias date_end.
viewstringFilter by view.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/past" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": [
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2399854",
      "eventId": "cs2-event-8251",
      "eventName": "BLAST Rivals 2026 Season 2",
      "eventSlug": "blast-rivals-2026-season-2",
      "stageName": null,
      "startsAt": "2026-11-11T09:30:00.000Z",
      "endsAt": "2026-11-11T12:49:54.997Z",
      "bestOf": 3,
      "status": "completed",
      "team1Id": "cs2-team-4494",
      "team2Id": "cs2-team-5995",
      "team1Name": "MOUZ",
      "team2Name": "G2",
      "team1Score": 1,
      "team2Score": 2,
      "winnerTeamId": "cs2-team-5995",
      "vetoOrder": [
        {
          "map": "anubis",
          "order": 1,
          "action": "ban",
          "teamId": "cs2-team-4494",
          "teamName": "MOUZ",
          "mapName": "anubis",
          "mapNumber": null,
          "played": false
        },
        {
          "map": "cache",
          "order": 2,
          "action": "ban",
          "teamId": "cs2-team-5995",
          "teamName": "G2",
          "mapName": "cache",
          "mapNumber": null,
          "played": false
        }
      ],
      "lastSyncedAt": "2026-11-11T12:57:10.332Z",
      "lastVerified": "2026-11-11T12:57:10.332Z",
      "confidence": "high",
      "event": {
        "id": "cs2-event-8251",
        "name": "BLAST Rivals 2026 Season 2",
        "slug": "blast-rivals-2026-season-2",
        "imageUrl": null,
        "prizePool": 1000000,
        "currency": "USD",
        "tier": "A",
        "prestigeScore": 80,
        "status": "live",
        "region": "Europe",
        "startsAt": "2026-11-11T00:00:00.000Z",
        "endsAt": "2026-11-15T23:59:59.000Z",
        "eventId": "cs2-event-8251",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/ffad5ce2b72e370f6ed5c30a6ddf41cc.webp",
        "bannerImageUrl": null
      },
      "team1": {
        "id": "cs2-team-4494",
        "name": "MOUZ",
        "slug": "mouz",
        "teamTag": "MOUZ",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/0ad08abfc7542d74ca19505208967289.svg",
        "countryName": "Europe",
        "countryCode": null,
        "worldRanking": 1,
        "worldRankingStatus": "ranked",
        "vrsRanking": 1,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Europe",
        "logoIsPlaceholder": false
      },
      "team2": {
        "id": "cs2-team-5995",
        "name": "G2",
        "slug": "g2",
        "teamTag": "G2",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/a602501b47997540e5b51a5b49895204.webp",
        "countryName": "Europe",
        "countryCode": null,
        "worldRanking": 12,
        "worldRankingStatus": "ranked",
        "vrsRanking": 12,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Europe",
        "logoIsPlaceholder": false
      },
      "…": "17 more fields"
    },
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2400331",
      "eventId": "cs2-event-9469",
      "eventName": "NODWIN Clutch Series 14",
      "eventSlug": "nodwin-clutch-series-14",
      "stageName": null,
      "startsAt": "2026-11-11T09:00:00.000Z",
      "endsAt": "2026-11-11T10:55:03.424Z",
      "bestOf": 3,
      "status": "completed",
      "team1Id": "cs2-team-14142",
      "team2Id": "cs2-team-13908",
      "team1Name": "ex-UPGRADE",
      "team2Name": "Butterfly",
      "team1Score": 0,
      "team2Score": 2,
      "winnerTeamId": "cs2-team-13908",
    
…

Search matches

GET/api/v1/cs2/matches/search

Find matches by team or event name.

Query parameters

ParameterTypeDescription
bestOfstringOnly matches of this series length: 1, 3 or 5, or a comma list (3,5). bestOf=3 returns BO3 matches only; paging and totals count the filtered rows. Any other value is 400 INVALID_BEST_OF.
limitintegerRows to return. Maximum 100; larger values are reduced to 100.
q*stringSearch text.
querystringFilter by query.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/search" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": [
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2400201",
      "eventId": "cs2-event-8251",
      "eventName": "BLAST Rivals 2026 Season 2",
      "eventSlug": "blast-rivals-2026-season-2",
      "stageName": "upper bracket",
      "startsAt": "2026-11-12T04:30:00.000Z",
      "endsAt": null,
      "bestOf": 3,
      "status": "upcoming",
      "team1Id": "cs2-team-8297",
      "team2Id": "cs2-team-9565",
      "team1Name": "FURIA",
      "team2Name": "Vitality",
      "team1Score": null,
      "team2Score": null,
      "winnerTeamId": null,
      "vetoOrder": [
        {
          "map": "dust2",
          "order": 1,
          "action": "pick",
          "teamId": null,
          "teamName": null,
          "mapName": "dust2",
          "mapNumber": null,
          "played": false
        },
        {
          "map": "cache",
          "order": 2,
          "action": "pick",
          "teamId": null,
          "teamName": null,
          "mapName": "cache",
          "mapNumber": null,
          "played": false
        }
      ],
      "lastSyncedAt": "2026-11-11T12:47:57.149Z",
      "lastVerified": "2026-11-11T12:47:57.149Z",
      "confidence": "high",
      "event": {
        "id": "cs2-event-8251",
        "name": "BLAST Rivals 2026 Season 2",
        "slug": "blast-rivals-2026-season-2",
        "imageUrl": null,
        "prizePool": 1000000,
        "currency": "USD",
        "tier": "A",
        "prestigeScore": 80,
        "status": "live",
        "region": "Europe",
        "startsAt": "2026-11-11T00:00:00.000Z",
        "endsAt": "2026-11-15T23:59:59.000Z",
        "eventId": "cs2-event-8251",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/ffad5ce2b72e370f6ed5c30a6ddf41cc.webp",
        "bannerImageUrl": null
      },
      "team1": {
        "id": "cs2-team-8297",
        "name": "FURIA",
        "slug": "furia",
        "teamTag": "FURIA",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/ae2903ad6662885facbfedf1183a1b22.svg",
        "countryName": "Brazil",
        "countryCode": "BR",
        "worldRanking": 2,
        "worldRankingStatus": "ranked",
        "vrsRanking": 3,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Americas",
        "logoIsPlaceholder": false
      },
      "team2": {
        "id": "cs2-team-9565",
        "name": "Vitality",
        "slug": "vitality",
        "teamTag": "VITALITY",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/0cd34febd1ad61ff888f21b55756003b.webp",
        "countryName": "Europe",
        "countryCode": null,
        "worldRanking": 3,
        "alternateLogoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/c5e463f9b2347d3aa58794fb8f7ec967.webp",
        "darkUiLogoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/c5e463f9b2347d3aa58794fb8f7ec967.webp",
        "worldRankingStatus": "ranked",
        "vrsRanking": 2,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Europe",
        "logoIsPlaceholder": false
      },
      "…": "18 more fields"
    },
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2399852",
      "eventId": "cs2-event-8251",
      "eventName": "BLAST Rivals 2026 Season 2",
      "eventSlug": "blast-rivals-2026-season-2",
      "stageName": "upper bracket",
      "startsAt": "2026-11-11T04:15:00.000Z",
      "endsAt": "2026-11-11T06:18:51.447Z",
      "bestOf": 3,
     
…

Upcoming matches

GET/api/v1/cs2/matches/upcoming
GET/api/v1/cs2/upcoming

Scheduled matches, soonest first. Page with `limit` + `page` (or `offset`); `meta.total` and `meta.hasNext` say how many there are. **Only BO3s (or BO1s, BO5s):** `GET /api/v1/cs2/matches/upcoming?bestOf=3`. Comma lists work (`bestOf=3,5`). The same filter works on `/cs2/matches/past`, `/cs2/matches`, `/cs2/live`, team, event, player and head-to-head match lists. Any other value is 400 `INVALID_BEST_OF`. Parameters this list does not read are ignored and named in `meta.ignoredParams`. **Odds in the same call:** match lists carry no odds by default (a client reading `odds` gets nothing). Add `?include=odds` (also on `/cs2/matches`, `/live`, `/recent`, `/today` and `/past`) and every match gets `odds[]`: the latest price per bookmaker and market, `h2h` (series winner) first, then `map_h2h_1`, `map_h2h_2`, ... Each row has `team1Odds`, `team2Odds`, `market`, `marketStatus` (`open`, `suspended`, `closed`) and `capturedAt`. `meta.oddsIncluded` and `meta.matchesWithOdds` summarise the list; a match with no market has `odds: []`. **Plans.** Odds are included on Pro and above, and every new account gets a 3-day odds trial. Without odds access the list is still returned, with `meta.oddsIncluded: false` and `meta.oddsError` explaining how to upgrade. These routes are equivalent; use whichever reads best.

Query parameters

ParameterTypeDescription
bestOfstringOnly matches of this series length: 1, 3 or 5, or a comma list (3,5). bestOf=3 returns BO3 matches only; paging and totals count the filtered rows. Any other value is 400 INVALID_BEST_OF.
includestringOdds are embedded by default for keys with odds access (Pro and above, or the 3-day trial): every row has odds[] (series winner h2h first, then each map, with implied probabilities and market depth: liquidityUsd, volumeUsd, spread), h2hOdds (the match-winner line, or null) and oddsAvailable. Without access rows carry odds: [] and meta.oddsError. include=odds is accepted and changes nothing here. include=player_props adds playerProps[]: the match's open pick'em lines per player and market, every provider side by side with lineSpread (same access as odds).
limitintegerRows to return. Maximum 100; larger values are reduced to 100.
offsetintegerRows to skip, for paging.
pageintegerPage number, starting at 1.
teamstringOnly matches of this team (name, id or slug).
teamIdstringOnly matches of this team (id).
team_idstringSame as teamId.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/upcoming" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": [
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2400148",
      "eventId": "cs2-event-9465",
      "eventName": "CCT 2026 Europe Series 13",
      "eventSlug": "cct-2026-europe-series-13",
      "stageName": "playoffs",
      "startsAt": "2026-11-11T15:00:00.000Z",
      "endsAt": null,
      "bestOf": 3,
      "status": "upcoming",
      "team1Id": "cs2-team-7187",
      "team2Id": "cs2-team-11699",
      "team1Name": "Nexus",
      "team2Name": "BAKS",
      "team1Score": null,
      "team2Score": null,
      "winnerTeamId": null,
      "liveState": {
        "status": "upcoming",
        "team1Score": null,
        "team2Score": null,
        "winnerTeamId": null
      },
      "vetoOrder": [
        {
          "map": "ancient",
          "order": 1,
          "action": "pick",
          "teamId": null,
          "teamName": null,
          "mapName": "ancient",
          "mapNumber": null,
          "played": false
        },
        {
          "map": "ancient",
          "order": 2,
          "action": "pick",
          "teamId": null,
          "teamName": null,
          "mapName": "ancient",
          "mapNumber": null,
          "played": false
        }
      ],
      "streamLinks": [
        {
          "url": "https://www.twitch.tv/dayneez",
          "label": null,
          "language": null,
          "platform": "twitch"
        },
        {
          "url": "https://kick.com/cct_cs",
          "label": null,
          "language": null,
          "platform": "kick"
        }
      ],
      "vodLinks": [],
      "lastSyncedAt": "2026-11-11T12:46:20.278Z",
      "lastVerified": "2026-11-11T12:46:20.278Z",
      "confidence": "high",
      "odds": [
        {
          "oddsKey": "market:6916226",
          "matchId": "cs2-match-2400148",
          "provider": "prediction_market",
          "market": "h2h",
          "team1Odds": 2.27,
          "team2Odds": 1.79,
          "drawOdds": null,
          "team1ImpliedProb": 0.4405,
          "team2ImpliedProb": 0.5587,
          "liquidityUsd": 22655.56,
          "volumeUsd": 103397.223996,
          "volume24hUsd": 105553.47384199999,
          "bestBid": 0.43,
          "bestAsk": 0.45,
          "spread": 0.02,
          "marketStatus": "open",
          "capturedAt": "2026-11-11T12:56:51.250Z"
        },
        {
          "oddsKey": "market:6916224",
          "matchId": "cs2-match-2400148",
          "provider": "prediction_market",
          "market": "map_h2h_1",
          "team1Odds": 2.11,
          "team2Odds": 1.9,
          "drawOdds": null,
          "team1ImpliedProb": 0.4739,
          "team2ImpliedProb": 0.5263,
          "liquidityUsd": 2127.0113,
          "volumeUsd": 46.666075,
          "volume24hUsd": 46.666075,
          "bestBid": 0.46,
          "bestAsk": 0.49,
          "spread": 0.03,
          "marketStatus": "open",
          "capturedAt": "2026-11-11T12:56:51.220Z"
        }
      ],
      "…": "22 more fields"
    },
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2400239",
      "eventId": "cs2-event-9472",
      "eventName": "CCT 2026 Europe Series 14",
      "eventSlug": "cct-2026-europe-series-14",
      "stageName": null,
      "startsAt": "2026-11-11T15:00:00.000Z",
      "endsAt": null,
      "bestOf": 3,
      "status": "upcoming",
      "team1Id": "cs2-team-12857",
      "team2Id": "cs2-team-10867",
      "team1Name": "FORZE Reload",
      "team2Name": "MASONIC",
      "te
…

Recent results

GET/api/v1/cs2/matches/recent
GET/api/v1/cs2/matches/results
GET/api/v1/cs2/matches/completed
GET/api/v1/cs2/results
GET/api/v1/cs2/recent

Finished matches with final series score and winner, newest first. These routes are equivalent; use whichever reads best.

Query parameters

ParameterTypeDescription
bestOfstringOnly matches of this series length: 1, 3 or 5, or a comma list (3,5). bestOf=3 returns BO3 matches only; paging and totals count the filtered rows. Any other value is 400 INVALID_BEST_OF.
date_endstringSame as to.
date_startstringSame as from.
fromstringStart of the date range (YYYY-MM-DD or ISO 8601, UTC). Alias date_start.
includestringodds adds every match's bookmaker odds (odds[], the same rows as /cs2/matches/{matchId}/odds, series winner h2h first); see below. player_props adds playerProps[]: the match's open pick'em lines per player and market, every provider side by side with lineSpread (same access as odds). Combine with a comma: include=odds,player_props.
limitintegerRows to return. Maximum 100; larger values are reduced to 100.
tostringEnd of the date range (YYYY-MM-DD or ISO 8601, UTC); a date-only value includes that whole day. Alias date_end.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/recent" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": [
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2399854",
      "eventId": "cs2-event-8251",
      "eventName": "BLAST Rivals 2026 Season 2",
      "eventSlug": "blast-rivals-2026-season-2",
      "stageName": null,
      "startsAt": "2026-11-11T09:30:00.000Z",
      "endsAt": "2026-11-11T12:49:54.997Z",
      "bestOf": 3,
      "status": "completed",
      "team1Id": "cs2-team-4494",
      "team2Id": "cs2-team-5995",
      "team1Name": "MOUZ",
      "team2Name": "G2",
      "team1Score": 1,
      "team2Score": 2,
      "winnerTeamId": "cs2-team-5995",
      "vetoOrder": [
        {
          "map": "anubis",
          "order": 1,
          "action": "ban",
          "teamId": "cs2-team-4494",
          "teamName": "MOUZ",
          "mapName": "anubis",
          "mapNumber": null,
          "played": false
        },
        {
          "map": "cache",
          "order": 2,
          "action": "ban",
          "teamId": "cs2-team-5995",
          "teamName": "G2",
          "mapName": "cache",
          "mapNumber": null,
          "played": false
        }
      ],
      "lastSyncedAt": "2026-11-11T12:57:10.332Z",
      "lastVerified": "2026-11-11T12:57:10.332Z",
      "confidence": "high",
      "event": {
        "id": "cs2-event-8251",
        "name": "BLAST Rivals 2026 Season 2",
        "slug": "blast-rivals-2026-season-2",
        "imageUrl": null,
        "prizePool": 1000000,
        "currency": "USD",
        "tier": "A",
        "prestigeScore": 80,
        "status": "live",
        "region": "Europe",
        "startsAt": "2026-11-11T00:00:00.000Z",
        "endsAt": "2026-11-15T23:59:59.000Z",
        "eventId": "cs2-event-8251",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/ffad5ce2b72e370f6ed5c30a6ddf41cc.webp",
        "bannerImageUrl": null
      },
      "team1": {
        "id": "cs2-team-4494",
        "name": "MOUZ",
        "slug": "mouz",
        "teamTag": "MOUZ",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/0ad08abfc7542d74ca19505208967289.svg",
        "countryName": "Europe",
        "countryCode": null,
        "worldRanking": 1,
        "worldRankingStatus": "ranked",
        "vrsRanking": 1,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Europe",
        "logoIsPlaceholder": false
      },
      "team2": {
        "id": "cs2-team-5995",
        "name": "G2",
        "slug": "g2",
        "teamTag": "G2",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/a602501b47997540e5b51a5b49895204.webp",
        "countryName": "Europe",
        "countryCode": null,
        "worldRanking": 12,
        "worldRankingStatus": "ranked",
        "vrsRanking": 12,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Europe",
        "logoIsPlaceholder": false
      },
      "…": "17 more fields"
    },
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2400331",
      "eventId": "cs2-event-9469",
      "eventName": "NODWIN Clutch Series 14",
      "eventSlug": "nodwin-clutch-series-14",
      "stageName": null,
      "startsAt": "2026-11-11T09:00:00.000Z",
      "endsAt": "2026-11-11T10:55:03.424Z",
      "bestOf": 3,
      "status": "completed",
      "team1Id": "cs2-team-14142",
      "team2Id": "cs2-team-13908",
      "team1Name": "ex-UPGRADE",
      "team2Name": "Butterfly",
      "team1Score": 0,
      "team2Score": 2,
      "winnerTeamId": "cs2-team-13908",
    
…

Match head-to-head

GET/api/v1/cs2/matches/{matchId}/head-to-head

Previous meetings between the two teams in this match.

Query parameters

ParameterTypeDescription
matchId (path)*stringMatch id, e.g. cs2-match-2398421.
limitintegerRows to return. Maximum 250; larger values are reduced to 250.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/MATCH_ID/head-to-head" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": {
    "entityType": "cs2_team_h2h",
    "team": {
      "id": "cs2-team-4494",
      "name": "MOUZ"
    },
    "opponent": {
      "id": "cs2-team-5995",
      "name": "G2"
    },
    "totalMatches": 2,
    "matchRecord": {
      "teamWins": 1,
      "opponentWins": 1,
      "teamWinPercent": 50,
      "opponentWinPercent": 50
    },
    "mapRecord": {
      "teamWins": 3,
      "opponentWins": 3,
      "totalDecidedMaps": 6,
      "teamWinPercent": 50,
      "opponentWinPercent": 50
    },
    "mapBreakdown": [
      {
        "mapName": "Inferno",
        "played": 2,
        "teamWins": 1,
        "opponentWins": 1,
        "teamWinPercent": 50,
        "opponentWinPercent": 50,
        "roundsFor": 20,
        "roundsAgainst": 20,
        "roundDifferential": 0
      },
      {
        "mapName": "Nuke",
        "played": 1,
        "teamWins": 1,
        "opponentWins": 0,
        "teamWinPercent": 100,
        "opponentWinPercent": 0,
        "roundsFor": 13,
        "roundsAgainst": 7,
        "roundDifferential": 6
      }
    ],
    "recent5Matches": [
      {
        "matchId": "cs2-match-2399854",
        "status": "completed",
        "startsAt": "2026-11-11T09:30:00.000Z",
        "eventName": "BLAST Rivals 2026 Season 2",
        "bestOf": 3,
        "opponentId": "cs2-team-5995",
        "opponentName": "G2",
        "teamScore": 1,
        "opponentScore": 2,
        "score": "1-2",
        "result": "L",
        "resultType": "played",
        "isForfeit": false,
        "forfeitedMaps": 0,
        "teamPerspective": {
          "teamId": "cs2-team-4494",
          "side": "team1",
          "opponentId": "cs2-team-5995",
          "opponentName": "G2",
          "teamScore": 1,
          "opponentScore": 2,
          "result": "L",
          "resultType": "played",
          "isForfeit": false
        },
        "maps": [
          {
            "mapId": "cs2-match-2399854-map-1",
            "mapNumber": 1,
            "mapName": "Nuke",
            "status": "completed",
            "teamScore": 13,
            "opponentScore": 7,
            "score": "13-7",
            "result": "W",
            "resultType": "played",
            "isForfeit": false,
            "forfeitStage": null,
            "winnerTeamId": "cs2-team-4494",
            "roundsFor": 13,
            "roundsAgainst": 7
          },
          {
            "mapId": "cs2-match-2399854-map-2",
            "mapNumber": 2,
            "mapName": "Ancient",
            "status": "completed",
            "teamScore": 14,
            "opponentScore": 16,
            "score": "14-16",
            "result": "L",
            "resultType": "played",
            "isForfeit": false,
            "forfeitStage": null,
            "winnerTeamId": "cs2-team-5995",
            "roundsFor": 14,
            "roundsAgainst": 16
          }
        ]
      },
      {
        "matchId": "cs2-match-2394124",
        "status": "completed",
        "startsAt": "2026-05-10T05:00:00.000Z",
        "eventName": "PGL Astana 2026",
        "bestOf": 3,
        "opponentId": "cs2-team-5995",
        "opponentName": "G2",
        "teamScore": 2,
        "opponentScore": 1,
        "score": "2-1",
        "result": "W",
        "resultType": "played",
        "isForfeit": false,
        "forfeitedMaps": 0,
        "teamPerspective": {
          "teamId": "cs2-team-4494",
          "side": "team1",
          "opponentId": "cs2-team-5995",
          "op
…

Match demos

GET/api/v1/cs2/matches/{matchId}/demos

Demo availability per map, and whether each demo has been parsed into round data.

Query parameters

ParameterTypeDescription
matchId (path)*stringMatch id, e.g. cs2-match-2398421.
limitintegerRows to return. Maximum 100; larger values are reduced to 100.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/MATCH_ID/demos" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": {
    "entityType": "cs2_match_demos",
    "matchId": "cs2-match-2399854",
    "teams": {
      "team1Name": "MOUZ",
      "team2Name": "G2"
    },
    "eventName": "BLAST Rivals 2026 Season 2",
    "dataAvailable": true,
    "demos": [
      {
        "demoKey": "cs2-match-2399854:cs2-match-2399854-map-1",
        "matchId": "cs2-match-2399854",
        "mapId": "cs2-match-2399854-map-1",
        "status": "available",
        "parsed": true,
        "parseStatus": "parsed",
        "unavailableReason": null,
        "demoUrl": null,
        "archiveUrl": null,
        "archiveBytes": "732666842",
        "checksum": null,
        "lastCheckedAt": "2026-11-11T12:56:51.485Z"
      },
      {
        "demoKey": "cs2-match-2399854:cs2-match-2399854-map-2",
        "matchId": "cs2-match-2399854",
        "mapId": "cs2-match-2399854-map-2",
        "status": "available",
        "parsed": true,
        "parseStatus": "parsed",
        "unavailableReason": null,
        "demoUrl": null,
        "archiveUrl": null,
        "archiveBytes": "732666842",
        "checksum": null,
        "lastCheckedAt": "2026-11-11T12:57:03.546Z"
      }
    ]
  },
  "meta": {
    "count": 2,
    "dataAvailable": true,
    "limit": 2,
    "total": 2,
    "page": 1,
    "totalPages": 1,
    "hasNext": false,
    "hasPrev": false
  }
}

Match maps

GET/api/v1/cs2/matches/{matchId}/maps

Maps played or scheduled in a match: map name, score, halves and winner. Each map carries `durationSeconds` (wall clock from the end of round 1 freeze time to the end of the last round, pauses and timeouts included), `startedAt` and `endedAt`, and `durationTiming` {seconds, minutes, startedAt, endedAt, durationSource, timestampsSource, definition, round1FreezeEndRecorded, unavailableReason}. When null, `unavailableReason` says why: `not_yet_computed` (finished in the last 15 minutes), `map_in_progress`, `map_not_played`, `timestamps_not_observed_live`, `timestamps_live_disagrees`, `duration_recording_incomplete`, `duration_no_round_timeline`, `duration_map_score_unknown`, `duration_implausible_round_ticks`. `meta.resultStatus` is the match status. Maps with full recordings carry `playerSkins`: every player's knife, gloves and featured weapon on that map, each with `playerId`/`playerName`, `side`, `weapon`, `skinName`, `phase`, `float`, `wear`, `patternSeed`, `stattrak`, `souvenir`, `marketHashName`, `skinId`, `imageUrl`, `inspectLink` and `inspect` (see `/cs2/players/{playerIdOrSlug}/skins`). Each finished match carries resultType (played, forfeit = nothing played and the series awarded, partial_forfeit = some maps played and the rest conceded), isForfeit and forfeitedMaps. An awarded (forfeit) map is served `status: "completed"` with `resultType: "forfeit"`, `isForfeit: true` and `forfeitStage`: `before_start` (awarded before a round was played: `playerStats: []`, `roundsPlayed: 0`) or `mid_map` (forfeited part-way through: player stats, rounds and events are served as for any played map, `roundsPlayed` = rounds on record); `forfeitStage` is null on maps that were not forfeited. A map that was not played is `status: "map_not_played"` and never names a winner.

Query parameters

ParameterTypeDescription
matchId (path)*stringMatch id, e.g. cs2-match-2398421.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/MATCH_ID/maps" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": [
    {
      "entityType": "cs2_map",
      "id": "cs2-match-2399854-map-1",
      "matchId": "cs2-match-2399854",
      "mapNumber": 1,
      "mapName": "Nuke",
      "status": "completed",
      "team1Score": 13,
      "team2Score": 7,
      "team1Halves": [
        6,
        7
      ],
      "team2Halves": [
        6,
        1
      ],
      "winnerTeamId": "cs2-team-4494",
      "durationRounds": 20,
      "lastSyncedAt": "2026-11-11T12:56:51.485Z",
      "playerStats": [
        {
          "id": "cs2-match-2399854-map-1-cs2-player-20447",
          "mapId": "cs2-match-2399854-map-1",
          "matchId": "cs2-match-2399854",
          "playerId": "cs2-player-20447",
          "playerName": "HeavyGod",
          "teamId": "cs2-team-5995",
          "teamName": "G2",
          "kills": 13,
          "deaths": 15,
          "assists": 1,
          "plusMinus": -2,
          "adr": 72.35,
          "kast": 0.5,
          "rating": 0.85,
          "ratingVersion": "cito_rating_1",
          "headshots": 6,
          "headshotPercent": 0.4615,
          "firstKills": 2,
          "firstDeaths": 2,
          "lastSyncedAt": "2026-11-11T12:56:41.809Z",
          "mapNameCanonical": null,
          "imageUrl": null,
          "mapImageUrl": null,
          "coverImageUrl": null,
          "…": "8 more fields"
        },
        {
          "id": "cs2-match-2399854-map-1-cs2-player-21062",
          "mapId": "cs2-match-2399854-map-1",
          "matchId": "cs2-match-2399854",
          "playerId": "cs2-player-21062",
          "playerName": "MATYS",
          "teamId": "cs2-team-5995",
          "teamName": "G2",
          "kills": 11,
          "deaths": 15,
          "assists": 1,
          "plusMinus": -4,
          "adr": 65.4,
          "kast": 0.5,
          "rating": 0.78,
          "ratingVersion": "cito_rating_1",
          "headshots": 6,
          "headshotPercent": 0.5455,
          "firstKills": 3,
          "firstDeaths": 5,
          "lastSyncedAt": "2026-11-11T12:56:41.809Z",
          "mapNameCanonical": null,
          "imageUrl": null,
          "mapImageUrl": null,
          "coverImageUrl": null,
          "…": "8 more fields"
        }
      ],
      "bombEvents": [
        {
          "id": "ae221419-bd73-4107-80bf-3afe6a4a951b",
          "matchId": "cs2-match-2399854",
          "mapId": "cs2-match-2399854-map-1",
          "roundNumber": 1,
          "eventType": "plant",
          "tick": 8809,
          "seconds": 137.641,
          "siteRaw": "429",
          "siteLabel": "B",
          "playerId": "cs2-player-18072",
          "playerName": "torzsi",
          "teamId": "cs2-team-4494",
          "teamName": "MOUZ",
          "side": "T",
          "x": 717.275,
          "y": -1145.522,
          "z": -752.969,
          "enemiesAlive": null,
          "teammatesAlive": null,
          "isClutchDefuse": false,
          "confidence": "high",
          "lastSyncedAt": "2026-11-11T12:56:42.314Z",
          "mapNameCanonical": null,
          "imageUrl": null,
          "…": "10 more fields"
        },
        {
          "id": "fad3b5e1-d3ca-410d-a8ca-b4ad227f7ba0",
          "matchId": "cs2-match-2399854",
          "mapId": "cs2-match-2399854-map-1",
          "roundNumber": 2,
          "eventType": "plant",
          "tick": 16214,
          "seconds": 253.344,
          "siteRaw": "370",
          "siteLabel": "A",
          "playerId": "cs2-player-22279",
          "playe
…

Map economy per player

GET/api/v1/cs2/matches/{matchId}/maps/{mapNumber}/economy/players
GET/api/v1/cs2/matches/{matchId}/maps/{mapNumber}/economy

Round-by-round economy of one map, per player. `by=player` (default), `by=team` or `by=round` (anything else is 400 `INVALID_BY`). The map id also works as `/cs2/games/{gameId}/economy` and `/cs2/matches/{matchId}/maps/{mapNumber}/economy` (each also with `/players`). `data`: `mapId`, `matchId`, `mapNumber`, `mapName`, `status`, `by`, `roundsCount`, `startMoneyAvailable`, `startMoneyCoverage` {playerRounds, withStartMoney}, `startMoneyUnavailableReason` (`not_recorded_for_this_map` for maps processed before 2026-11-02), `fields` (definitions), `dataAvailable`, `unavailableReason` (`round_economy_not_indexed`, `map_not_completed`). - `by=player`: `players[]` {playerId, playerName, teamId, teamName, rounds, `totals` {moneySpent, purchaseSpend, avgEquipmentValue, avgStartMoney, pistolRounds, ecoRounds, forceBuyRounds, halfBuyRounds, fullBuyRounds}, `byRound[]` {round, side, startMoney, moneySpent, moneyLeft, equipmentValue, roundStartEquipmentValue, buyType (`pistol`, `eco`, `force_buy`, `half_buy`, `full_buy`), purchases[] {item, cost, soldBack}, purchaseSpend, hasHelmet, hasDefuser, roundWon, freezeSnapshot}}. - `by=team`: `teams[]` {teamId, teamName, rounds[] {round, equipmentValue, moneySpent, startMoney, players, side, won}}. - `by=round`: `rounds[]` {round, teams[] {teamId, teamName, side, roundWon, equipmentValue, moneySpent, startMoney, players[]}}. Definitions: `startMoney` = money at round start (moneyLeft + moneySpent at the end of freeze time; correct across overtime money resets); `moneySpent`, `moneyLeft`, `equipmentValue` at the end of freeze time; `purchaseSpend` = the whole round's spend including buys after freeze time; `freezeSnapshot: false` = no end-of-freeze-time snapshot for that round. **Plans:** like round events, paid plans; Free accounts created from 2026-10-28 get 403 `PLAN_REQUIRED` (the dashboard sandbox shows it). Same response as `GET /api/v1/cs2/maps/{mapId}/economy`. These routes are equivalent; use whichever reads best.

Query parameters

ParameterTypeDescription
matchId (path)*stringMatch id, e.g. cs2-match-2398421.
mapNumber (path)*stringMap number within the match (1, 2, 3...).
bystringFilter by by.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/MATCH_ID/maps/{mapNumber}/economy/players" \
  -H "x-api-key: YOUR_API_KEY"

Match veto

GET/api/v1/cs2/matches/{matchId}/veto
GET/api/v1/cs2/matches/{matchId}/draft

The map veto in order: each ban, pick and the decider with the team that made it. vetoStatus is complete, forfeit_no_veto (a forfeit, no veto held), unavailable (finished, veto not published) or pending (not played yet); vetoOrder is always an array. These routes are equivalent; use whichever reads best.

Query parameters

ParameterTypeDescription
matchId (path)*stringMatch id, e.g. cs2-match-2398421.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/MATCH_ID/veto" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": {
    "entityType": "cs2_match_veto",
    "matchId": "cs2-match-2399854",
    "status": "completed",
    "bestOf": 3,
    "team1Id": "cs2-team-4494",
    "team2Id": "cs2-team-5995",
    "team1Name": "MOUZ",
    "team2Name": "G2",
    "vetoStatus": "complete",
    "vetoOrder": [
      {
        "map": "anubis",
        "order": 1,
        "action": "ban",
        "teamId": "cs2-team-4494",
        "teamName": "MOUZ",
        "mapName": "anubis",
        "mapNumber": null,
        "played": false
      },
      {
        "map": "cache",
        "order": 2,
        "action": "ban",
        "teamId": "cs2-team-5995",
        "teamName": "G2",
        "mapName": "cache",
        "mapNumber": null,
        "played": false
      }
    ],
    "maps": [
      {
        "id": "cs2-match-2399854-map-1",
        "mapNumber": 1,
        "mapName": "Nuke",
        "status": "completed",
        "pickTeamId": "cs2-team-4494",
        "winnerTeamId": "cs2-team-4494",
        "team1Score": 13,
        "team2Score": 7,
        "mapImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/nuke.png",
        "objectiveStats": {
          "dataAvailable": false,
          "unavailableReason": "not_yet_indexed",
          "confidence": {
            "plants": "high",
            "defuses": "high",
            "explosions": "high",
            "clutchDefuse": "medium"
          },
          "teamStats": [],
          "roundEvents": []
        },
        "mapNameCanonical": "Nuke",
        "imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/nuke.png",
        "coverImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/nuke.png",
        "resultType": "played",
        "resultStatus": "completed",
        "isForfeit": false,
        "forfeitStage": null,
        "roundsPlayed": null,
        "statsEligible": true,
        "unavailableReason": null,
        "dataAvailability": {
          "playerStats": {
            "dataAvailable": false,
            "unavailableReason": "not_yet_indexed"
          }
        }
      },
      {
        "id": "cs2-match-2399854-map-2",
        "mapNumber": 2,
        "mapName": "Ancient",
        "status": "completed",
        "pickTeamId": "cs2-team-5995",
        "winnerTeamId": "cs2-team-5995",
        "team1Score": 14,
        "team2Score": 16,
        "mapImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/ancient.png",
        "objectiveStats": {
          "dataAvailable": false,
          "unavailableReason": "not_yet_indexed",
          "confidence": {
            "plants": "high",
            "defuses": "high",
            "explosions": "high",
            "clutchDefuse": "medium"
          },
          "teamStats": [],
          "roundEvents": []
        },
        "mapNameCanonical": "Ancient",
        "imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/ancient.png",
        "coverImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/ancient.png",
        "resultType": "played",
        "resultStatus": "completed",
        "isForfeit": false,
        "forfeitStage": null,
        "roundsPlayed": null,
        "statsEligible": true,
        "unavailableReason": null,
        "dataAvailability": {
          "playerStats": {
            "dataAvailable": false,
            "unavailableReason": "not_yet_indexed"
          }
        }
      }
    ],
    "vetoSteps": 7,
    "vetoCoversPlayedMaps": true,
    "dataAvailab
…

Match games

GET/api/v1/cs2/matches/{matchId}/games

The match's maps as games, each with the `gameId` used by `/cs2/games/{gameId}`. Each game has `durationSeconds`, `startedAt`, `endedAt` and `durationTiming` (see `/cs2/matches/{matchId}/maps`), and its `duration` object ({rounds, source}) also carries `seconds`, `startedAt`, `endedAt`, `durationSource` and `unavailableReason`.

Query parameters

ParameterTypeDescription
matchId (path)*stringMatch id, e.g. cs2-match-2398421.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/MATCH_ID/games" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": [
    {
      "id": "cs2-match-2399854-map-1",
      "entityType": "cs2_game",
      "matchId": "cs2-match-2399854",
      "mapNumber": 1,
      "map": "Nuke",
      "pickTeamId": null,
      "winnerTeamId": "cs2-team-4494",
      "score": {
        "team1": 13,
        "team2": 7
      },
      "halfScores": {
        "team1": [
          6,
          7
        ],
        "team2": [
          6,
          1
        ]
      },
      "team1Halves": [
        6,
        7
      ],
      "team2Halves": [
        6,
        1
      ],
      "overtime": null,
      "durationRounds": 20,
      "duration": {
        "rounds": 20,
        "seconds": null,
        "startedAt": null,
        "endedAt": "2026-11-11T10:17:22.960Z",
        "unavailableReason": "duration_no_round_timeline"
      },
      "status": "completed",
      "resultType": "played",
      "resultStatus": "completed",
      "isForfeit": false,
      "forfeitStage": null,
      "roundsPlayed": null,
      "statsEligible": true,
      "unavailableReason": null,
      "playerStatsAvailable": true,
      "playerStats": [
        {
          "playerId": "cs2-player-20447",
          "playerName": "HeavyGod",
          "teamId": "cs2-team-5995",
          "teamName": "G2",
          "kills": 13,
          "deaths": 15,
          "assists": 1,
          "plusMinus": -2,
          "adr": 72.35,
          "kast": 0.5,
          "rating": 0.85,
          "ratingVersion": "cito_rating_1",
          "headshots": 6,
          "headshotPercent": 0.4615,
          "openingKills": 2,
          "openingDeaths": 2,
          "ratingProfile": {
            "rating": 0.85,
            "ratingVersion": "cito_rating_1",
            "components": {
              "…": "…"
            },
            "openingDuels": {
              "…": "…"
            },
            "formula": "Cito Rating 1.0 per map: 0.30*KPR/0.683 + 0.25*(1-DPR)/0.305 + 0.25*ADR/74.1 + 0.15*KAST/0.716 + 0.05*APR/0.223 (per-round kills, deaths, assists; missing ADR/KAST/assists terms are dropped and the weights rescaled). An average map is ab..."
          },
          "lastSyncedAt": "2026-11-11T12:56:41.809Z"
        },
        {
          "playerId": "cs2-player-21062",
          "playerName": "MATYS",
          "teamId": "cs2-team-5995",
          "teamName": "G2",
          "kills": 11,
          "deaths": 15,
          "assists": 1,
          "plusMinus": -4,
          "adr": 65.4,
          "kast": 0.5,
          "rating": 0.78,
          "ratingVersion": "cito_rating_1",
          "headshots": 6,
          "headshotPercent": 0.5455,
          "openingKills": 3,
          "openingDeaths": 5,
          "ratingProfile": {
            "rating": 0.78,
            "ratingVersion": "cito_rating_1",
            "components": {
              "…": "…"
            },
            "openingDuels": {
              "…": "…"
            },
            "formula": "Cito Rating 1.0 per map: 0.30*KPR/0.683 + 0.25*(1-DPR)/0.305 + 0.25*ADR/74.1 + 0.15*KAST/0.716 + 0.05*APR/0.223 (per-round kills, deaths, assists; missing ADR/KAST/assists terms are dropped and the weights rescaled). An average map is ab..."
          },
          "lastSyncedAt": "2026-11-11T12:56:41.809Z"
        }
      ],
      "…": "10 more fields"
    },
    {
      "id": "cs2-match-2399854-map-2",
      "entityType": "cs2_game",
      "matchId": "cs2-match-2399854",
      "mapNumber": 2,
      "map": "Ancient",
      "pickTeamId": null,
      "wi
…

Match player stats

GET/api/v1/cs2/matches/{matchId}/player-stats
GET/api/v1/cs2/matches/{matchId}/players
GET/api/v1/cs2/matches/{matchId}/stats

Per-player stats for each map of a match: kills, deaths, ADR, KAST and rating. Player photos: `imageUrl` on a player (`playerImageUrl` on roster and transfer rows) is always an image URL. A player with no photo gets a neutral silhouette placeholder (400x417 transparent WebP, the same size as the photos) and `imageIsPlaceholder: true` (`playerImageIsPlaceholder` on roster and transfer rows); a real photo has `false`. Check the flag, not the URL. These routes are equivalent; use whichever reads best.

Query parameters

ParameterTypeDescription
matchId (path)*stringMatch id, e.g. cs2-match-2398421.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/MATCH_ID/player-stats" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": [
    {
      "entityType": "cs2_player_stat",
      "id": "cs2-match-2399854-map-1-cs2-player-20447",
      "mapId": "cs2-match-2399854-map-1",
      "matchId": "cs2-match-2399854",
      "playerId": "cs2-player-20447",
      "playerName": "HeavyGod",
      "teamId": "cs2-team-5995",
      "teamName": "G2",
      "kills": 13,
      "deaths": 15,
      "assists": 1,
      "plusMinus": -2,
      "adr": 72.35,
      "kast": 0.5,
      "rating": 0.85,
      "ratingVersion": "cito_rating_1",
      "headshots": 6,
      "headshotPercent": 0.4615,
      "firstKills": 2,
      "firstDeaths": 2,
      "lastSyncedAt": "2026-11-11T12:56:41.809Z",
      "player": {
        "id": "cs2-player-20447",
        "nickname": "HeavyGod",
        "slug": "heavygod",
        "realName": "Nikita Martynenko",
        "imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/a296b180d56afc8225017ecaa68217b6.webp",
        "countryName": "Israel",
        "countryCode": "IL",
        "age": 23,
        "rating": 1.09,
        "mapsPlayed": 127,
        "careerStats": {
          "rating": 1.09,
          "lastKnownRating": 1.09
        },
        "currentTeamId": "cs2-team-5995",
        "status": "active",
        "primaryRole": "rifler",
        "roleConfidence": "low",
        "statusUpdatedAt": "2026-11-11T12:51:52.813Z",
        "lastSyncedAt": "2026-11-11T12:57:12.514Z",
        "lastVerified": "2026-11-11T12:57:12.514Z",
        "imageIsPlaceholder": false
      },
      "team": {
        "id": "cs2-team-5995",
        "name": "G2",
        "slug": "g2",
        "teamTag": "G2",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/a602501b47997540e5b51a5b49895204.webp",
        "countryName": "Europe",
        "countryCode": null,
        "region": "Europe",
        "worldRanking": 12,
        "lastSyncedAt": "2026-11-11T12:57:10.243Z",
        "lastVerified": "2026-11-11T12:57:10.243Z",
        "confidence": "high",
        "worldRankingStatus": "ranked",
        "vrsRanking": 12,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Europe",
        "logoIsPlaceholder": false
      },
      "ctKills": 11,
      "…": "17 more fields"
    },
    {
      "entityType": "cs2_player_stat",
      "id": "cs2-match-2399854-map-1-cs2-player-21062",
      "mapId": "cs2-match-2399854-map-1",
      "matchId": "cs2-match-2399854",
      "playerId": "cs2-player-21062",
      "playerName": "MATYS",
      "teamId": "cs2-team-5995",
      "teamName": "G2",
      "kills": 11,
      "deaths": 15,
      "assists": 1,
      "plusMinus": -4,
      "adr": 65.4,
      "kast": 0.5,
      "rating": 0.78,
      "ratingVersion": "cito_rating_1",
      "headshots": 6,
      "headshotPercent": 0.5455,
      "firstKills": 3,
      "firstDeaths": 5,
      "lastSyncedAt": "2026-11-11T12:56:41.809Z",
      "player": {
        "id": "cs2-player-21062",
        "nickname": "MATYS",
        "slug": "matys",
        "realName": "Matúš Šimko",
        "imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/66c5795b51cea5db7dfb8417d812e51b.webp",
        "countryName": "Slovakia",
        "countryCode": "SK",
        "age": 24,
        "rating": 1.05,
        "mapsPlayed": 111,
        "careerStats": {
          "rating": 1.05,
          "lastKnownRating": 1.05
        },
        "currentTeamId": "cs2-team-5995",
        "status": "active",
        "primaryRole": "entry",
        "roleConfidence": "medium",
     
…

Match lineup stats

GET/api/v1/cs2/matches/{matchId}/lineup-stats

Each team's lineup for the match with recent form stats. Player photos: `imageUrl` on a player (`playerImageUrl` on roster and transfer rows) is always an image URL. A player with no photo gets a neutral silhouette placeholder (400x417 transparent WebP, the same size as the photos) and `imageIsPlaceholder: true` (`playerImageIsPlaceholder` on roster and transfer rows); a real photo has `false`. Check the flag, not the URL.

Query parameters

ParameterTypeDescription
matchId (path)*stringMatch id, e.g. cs2-match-2398421.
windowDaysintegerLook-back window in days.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/MATCH_ID/lineup-stats" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": {
    "entityType": "cs2_match_lineup_stats",
    "matchId": "cs2-match-2399854",
    "windowDays": 90,
    "dataAvailable": true,
    "teams": [
      {
        "teamId": "cs2-team-4494",
        "players": [
          {
            "playerId": "cs2-player-24457",
            "teamId": "cs2-team-4494",
            "nickname": "xelex",
            "name": "Adrian Vincze",
            "imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/b8501af66109e7d6f0928b2e600fccad.webp",
            "slug": "xelex",
            "countryName": "Hungary",
            "countryCode": "HU",
            "role": "rifler",
            "windowDays": 90,
            "dataAvailable": true,
            "maps": 72,
            "matches": 29,
            "rating": 1.05,
            "adr": 73.3,
            "kast": 0.738,
            "kdRatio": 1.05,
            "kills": 1025,
            "deaths": 980,
            "assists": 326,
            "unavailableSubratings": [
              "…"
            ],
            "imageIsPlaceholder": false
          },
          {
            "playerId": "cs2-player-20312",
            "teamId": "cs2-team-4494",
            "nickname": "xertioN",
            "name": "Dorian Berman",
            "imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/f910329dcc3ab91ed1ebb7e64c6714e2.webp",
            "slug": "xertion",
            "countryName": "Israel",
            "countryCode": "IL",
            "role": "entry",
            "windowDays": 90,
            "dataAvailable": true,
            "maps": 72,
            "matches": 29,
            "rating": 1.08,
            "adr": 80.1,
            "kast": 0.734,
            "kdRatio": 1.05,
            "kills": 1089,
            "deaths": 1033,
            "assists": 432,
            "unavailableSubratings": [
              "…"
            ],
            "imageIsPlaceholder": false
          }
        ]
      },
      {
        "teamId": "cs2-team-5995",
        "players": [
          {
            "playerId": "cs2-player-21062",
            "teamId": "cs2-team-5995",
            "nickname": "MATYS",
            "name": "Matúš Šimko",
            "imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/66c5795b51cea5db7dfb8417d812e51b.webp",
            "slug": "matys",
            "countryName": "Slovakia",
            "countryCode": "SK",
            "role": "entry",
            "windowDays": 90,
            "dataAvailable": true,
            "maps": 59,
            "matches": 23,
            "rating": 0.98,
            "adr": 69.3,
            "kast": 0.702,
            "kdRatio": 0.94,
            "kills": 824,
            "deaths": 879,
            "assists": 280,
            "unavailableSubratings": [
              "…"
            ],
            "imageIsPlaceholder": false
          },
          {
            "playerId": "cs2-player-9436",
            "teamId": "cs2-team-5995",
            "nickname": "NertZ",
            "name": "Guy Iluz",
            "imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/698cd347ed451f5b3495eff9ab115b46.webp",
            "slug": "nertz",
            "countryName": "Israel",
            "countryCode": "IL",
            "role": "entry",
            "windowDays": 90,
            "dataAvailable": true,
            "maps": 59,
            "matches": 23,
            "rating": 1.04,
            "adr": 80.8,
            "kast": 0.727,
            "kdRatio": 1.01,
    
…

Match details

GET/api/v1/cs2/matches/{matchId}

One match: event, teams, series score, maps, veto and which sub-resources have data. Every map in `maps[]` has its wall-clock duration (`durationSeconds`, `startedAt`, `endedAt`, `durationTiming`; see `/cs2/matches/{matchId}/maps`). Each finished match carries resultType (played, forfeit = nothing played and the series awarded, partial_forfeit = some maps played and the rest conceded), isForfeit and forfeitedMaps. An awarded (forfeit) map is served `status: "completed"` with `resultType: "forfeit"`, `isForfeit: true` and `forfeitStage`: `before_start` (awarded before a round was played: `playerStats: []`, `roundsPlayed: 0`) or `mid_map` (forfeited part-way through: player stats, rounds and events are served as for any played map, `roundsPlayed` = rounds on record); `forfeitStage` is null on maps that were not forfeited. A map that was not played is `status: "map_not_played"` and never names a winner. Player photos: `imageUrl` on a player (`playerImageUrl` on roster and transfer rows) is always an image URL. A player with no photo gets a neutral silhouette placeholder (400x417 transparent WebP, the same size as the photos) and `imageIsPlaceholder: true` (`playerImageIsPlaceholder` on roster and transfer rows); a real photo has `false`. Check the flag, not the URL.

Query parameters

ParameterTypeDescription
matchId (path)*stringMatch id, e.g. cs2-match-2398421.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/MATCH_ID" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": {
    "entityType": "cs2_match",
    "id": "cs2-match-2399854",
    "eventId": "cs2-event-8251",
    "eventName": "BLAST Rivals 2026 Season 2",
    "eventSlug": "blast-rivals-2026-season-2",
    "stageName": "upper bracket",
    "startsAt": "2026-11-11T09:30:00.000Z",
    "endsAt": "2026-11-11T12:49:54.997Z",
    "bestOf": 3,
    "status": "completed",
    "team1Id": "cs2-team-4494",
    "team2Id": "cs2-team-5995",
    "team1Name": "MOUZ",
    "team2Name": "G2",
    "team1Score": 1,
    "team2Score": 2,
    "winnerTeamId": "cs2-team-5995",
    "vetoOrder": [
      {
        "map": "anubis",
        "order": 1,
        "action": "ban",
        "teamId": "cs2-team-4494",
        "teamName": "MOUZ",
        "mapName": "anubis",
        "mapNumber": null,
        "played": false
      },
      {
        "map": "cache",
        "order": 2,
        "action": "ban",
        "teamId": "cs2-team-5995",
        "teamName": "G2",
        "mapName": "cache",
        "mapNumber": null,
        "played": false
      }
    ],
    "streamLinks": [],
    "vodLinks": [],
    "lastSyncedAt": "2026-11-11T12:57:10.332Z",
    "lastVerified": "2026-11-11T12:57:10.332Z",
    "confidence": "high",
    "event": {
      "id": "cs2-event-8251",
      "name": "BLAST Rivals 2026 Season 2",
      "slug": "blast-rivals-2026-season-2",
      "imageUrl": null,
      "prizePool": 1000000,
      "currency": "USD",
      "location": "Chek Lap Kok, Hong Kong",
      "format": "Group stage: Double elimination Bo3 / Playoffs: Single elimination Bo3 - Grand final Bo5",
      "teamCount": 8,
      "standings": [
        {
          "seed": null,
          "prize": null,
          "teamId": "cs2-team-4494",
          "teamName": "MOUZ",
          "placement": null,
          "seedStage": null,
          "placementTo": null,
          "placementFrom": null,
          "vrsRankAtEvent": 1,
          "worldRankAtEvent": 1,
          "seedUnavailableReason": "source_publishes_no_seeding",
          "placementUnavailableReason": "event_not_finished"
        },
        {
          "seed": null,
          "prize": null,
          "teamId": "cs2-team-8297",
          "teamName": "FURIA",
          "placement": null,
          "seedStage": null,
          "placementTo": null,
          "placementFrom": null,
          "vrsRankAtEvent": 3,
          "worldRankAtEvent": 2,
          "seedUnavailableReason": "source_publishes_no_seeding",
          "placementUnavailableReason": "event_not_finished"
        }
      ],
      "startsAt": "2026-11-11T00:00:00.000Z",
      "endsAt": "2026-11-15T23:59:59.000Z",
      "status": "live",
      "tier": "A",
      "prestigeScore": 80,
      "region": "Europe",
      "isLan": true,
      "confirmedStatus": "source_detail",
      "streamLinks": null,
      "vodLinks": null,
      "lastSyncedAt": "2026-11-11T12:55:02.939Z",
      "lastVerified": "2026-11-11T12:55:02.939Z",
      "confidence": "high",
      "eventId": "cs2-event-8251",
      "…": "2 more fields"
    },
    "…": "19 more fields"
  },
  "meta": {}
}

List matches

GET/api/v1/cs2/matches

Matches with filters for status, team, event and date range. Every map in a row says whether player stats exist for it (`dataAvailability.playerStats`). Each finished match carries resultType (played, forfeit = nothing played and the series awarded, partial_forfeit = some maps played and the rest conceded), isForfeit and forfeitedMaps. An awarded (forfeit) map is served `status: "completed"` with `resultType: "forfeit"`, `isForfeit: true` and `forfeitStage`: `before_start` (awarded before a round was played: `playerStats: []`, `roundsPlayed: 0`) or `mid_map` (forfeited part-way through: player stats, rounds and events are served as for any played map, `roundsPlayed` = rounds on record); `forfeitStage` is null on maps that were not forfeited. A map that was not played is `status: "map_not_played"` and never names a winner. **Many matches in one call:** `?ids=a,b,c` (comma-separated, or repeat `ids=`; up to 50 ids or slugs, anything the single-matche endpoint accepts). Items have the list row shape, in request order; an entity named twice is returned once; inputs that name nothing are listed in `meta.notFound`. `meta.batch` = {requested, returned, notFound, billedRequests, idsPerBilledRequest: 10, maxIds: 50, itemShape, fullShape}. **Billing:** a batch costs one call per started block of 10 ids (1-10 ids = 1 call, 11-20 = 2, 50 = 5), on both the per-minute limit and the month; with fewer calls left this month than the batch needs, the first (calls left x 10) ids are served and the rest are listed in `meta.batch.notFetched` (`notFetchedReason: MONTHLY_LIMIT_REACHED`). More than 50 ids is a 400. `?expand=full` (or any `include=`) returns each item as the single-entity response (sections under `included`), the batch shape served before 2026-11-02; API keys that used batches before then keep that shape by default.

Query parameters

ParameterTypeDescription
bestOfstringOnly matches of this series length: 1, 3 or 5, or a comma list (3,5). bestOf=3 returns BO3 matches only; paging and totals count the filtered rows. Any other value is 400 INVALID_BEST_OF.
date_endstringSame as to.
date_startstringSame as from.
daysintegerLook-back window in days.
eventstringEvent id or slug.
eventIdstringFilter by eventId.
event_idstringFilter by event_id.
expandstringfull with ids: each item is the full single-match response.
fieldsstringComma-separated list of fields to return.
fromstringStart of the date range (YYYY-MM-DD or ISO 8601, UTC). Alias date_start.
idsstringBatch read: up to 50 comma-separated match ids. Billed one call per started 10 ids.
includestringodds adds every match's bookmaker odds (odds[], the same rows as /cs2/matches/{matchId}/odds, series winner h2h first); see below. player_props adds playerProps[]: the match's open pick'em lines per player and market, every provider side by side with lineSpread (same access as odds). Combine with a comma: include=odds,player_props. With status=live or status=upcoming odds are embedded by default for keys with odds access.
limitintegerRows to return. Maximum 200; larger values are reduced to 200.
offsetintegerRows to skip, for paging.
orderstringFilter by order.
pageintegerPage number, starting at 1.
playerIdstringPlayer id or slug.
player_idstringPlayer id or slug.
sortstringSort order.
statusstringFilter by status.
summarybooleantrue returns a summary instead of full rows.
teamstringTeam id or slug.
teamIdstringTeam id or slug.
team_idstringTeam id or slug.
tostringEnd of the date range (YYYY-MM-DD or ISO 8601, UTC); a date-only value includes that whole day. Alias date_end.
viewstringFilter by view.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/matches" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": [
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2400501",
      "eventId": "cs2-event-9303",
      "eventName": "PGL Major Singapore 2026 Stage 1",
      "eventSlug": "pgl-major-singapore-2026-stage-1",
      "stageName": null,
      "startsAt": "2026-11-24T07:00:00.000Z",
      "endsAt": null,
      "bestOf": 1,
      "status": "upcoming",
      "team1Id": "cs2-team-11251",
      "team2Id": "cs2-team-12774",
      "team1Name": "Eternal Fire",
      "team2Name": "FlyQuest",
      "team1Score": null,
      "team2Score": null,
      "winnerTeamId": null,
      "vetoOrder": [
        {
          "map": "dust2",
          "order": 1,
          "action": "pick",
          "teamId": null,
          "teamName": null,
          "mapName": "dust2",
          "mapNumber": null,
          "played": false
        },
        {
          "map": "anubis",
          "order": 2,
          "action": "pick",
          "teamId": null,
          "teamName": null,
          "mapName": "anubis",
          "mapNumber": null,
          "played": false
        }
      ],
      "lastSyncedAt": "2026-11-11T12:50:44.023Z",
      "lastVerified": "2026-11-11T12:50:44.023Z",
      "confidence": "high",
      "event": {
        "id": "cs2-event-9303",
        "name": "PGL Major Singapore 2026 Stage 1",
        "slug": "pgl-major-singapore-2026-stage-1",
        "imageUrl": null,
        "prizePool": null,
        "currency": null,
        "tier": "S",
        "prestigeScore": 100,
        "status": "upcoming",
        "region": null,
        "startsAt": "2026-11-24T00:00:00.000Z",
        "endsAt": "2026-11-27T23:59:59.000Z",
        "eventId": "cs2-event-9303",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/3d243df9e55b3252320526320ebfa51e.webp",
        "bannerImageUrl": null
      },
      "team1": {
        "id": "cs2-team-11251",
        "name": "Eternal Fire",
        "slug": "eternal-fire",
        "teamTag": "EF",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/800a57a1e59a9ca428faf6b6a890ced0.webp",
        "countryName": "Europe",
        "countryCode": null,
        "worldRanking": 23,
        "worldRankingStatus": "ranked",
        "vrsRanking": 22,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Europe",
        "logoIsPlaceholder": false
      },
      "team2": {
        "id": "cs2-team-12774",
        "name": "FlyQuest",
        "slug": "flyquest",
        "teamTag": "FLYQUEST",
        "logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/8c4b645e4ba882c1c6e0759120597464.webp",
        "countryName": "Australia",
        "countryCode": "AU",
        "worldRanking": 60,
        "worldRankingStatus": "ranked",
        "vrsRanking": 45,
        "vrsRankingStatus": "ranked",
        "vrsRegion": "Asia",
        "logoIsPlaceholder": false
      },
      "…": "17 more fields"
    },
    {
      "entityType": "cs2_match",
      "id": "cs2-match-2400500",
      "eventId": "cs2-event-9303",
      "eventName": "PGL Major Singapore 2026 Stage 1",
      "eventSlug": "pgl-major-singapore-2026-stage-1",
      "stageName": null,
      "startsAt": "2026-11-24T07:00:00.000Z",
      "endsAt": null,
      "bestOf": 1,
      "status": "upcoming",
      "team1Id": "cs2-team-6667",
      "team2Id": "cs2-team-12257",
      "team1Name": "FaZe",
      "team2Name": "Wildcard",
      "team1Score": null,
      "team2Score": null,
      "winnerTeamId": null
…

Head-to-head pairs

GET/api/v1/cs2/h2h/pairs

Team pairs that have played each other, for building head-to-head pages.

Query parameters

ParameterTypeDescription
limitintegerRows to return. Maximum 500; larger values are reduced to 500.
minMeetingsstringFilter by minMeetings.
min_meetingsstringFilter by min_meetings.
windowDaysintegerLook-back window in days.
window_daysintegerLook-back window in days.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/h2h/pairs" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": {
    "entityType": "cs2_h2h_pair",
    "pairs": [
      {
        "teamA": {
          "id": "cs2-team-12510",
          "name": "The Huns",
          "slug": "the-huns"
        },
        "teamB": {
          "id": "cs2-team-12646",
          "name": "Chinggis Warriors",
          "slug": "chinggis-warriors"
        },
        "meetings": 27,
        "lastMeetingAt": "2026-10-10T08:20:00.000Z"
      },
      {
        "teamA": {
          "id": "cs2-team-8536",
          "name": "Ground Zero",
          "slug": "ground-zero"
        },
        "teamB": {
          "id": "cs2-team-9881",
          "name": "Rooster",
          "slug": "rooster"
        },
        "meetings": 20,
        "lastMeetingAt": "2026-09-27T09:00:00.000Z"
      }
    ],
    "dataAvailable": true
  },
  "meta": {
    "count": 2,
    "limit": 2,
    "minMeetings": 2,
    "windowDays": 730,
    "dataAvailable": true,
    "total": 2,
    "page": 1,
    "totalPages": 1,
    "hasNext": false,
    "hasPrev": false
  }
}

Head-to-head by query

GET/api/v1/cs2/h2h

The same head-to-head record as `/cs2/h2h/{teamIdOrSlug}/{opponentIdOrSlug}`, with the two teams as query parameters: `team1` and `team2` (id or slug). Missing either returns 400.

Query parameters

ParameterTypeDescription
bestOfstringOnly matches of this series length: 1, 3 or 5, or a comma list (3,5). bestOf=3 returns BO3 matches only; paging and totals count the filtered rows. Any other value is 400 INVALID_BEST_OF.
limitintegerRows to return. Maximum 250; larger values are reduced to 250.
team1stringFirst team: id or slug (vitality). Also accepted as teamA / team.
team2stringSecond team: id or slug (mouz). Also accepted as teamB / opponent.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/h2h" \
  -H "x-api-key: YOUR_API_KEY"

Response

json
{
  "success": true,
  "data": {
    "entityType": "cs2_team_h2h",
    "team": {
      "id": "cs2-team-9565",
      "name": "Vitality"
    },
    "opponent": {
      "id": "cs2-team-7020",
      "name": "Spirit"
    },
    "totalMatches": 2,
    "matchRecord": {
      "teamWins": 2,
      "opponentWins": 0,
      "teamWinPercent": 100,
      "opponentWinPercent": 0
    },
    "mapRecord": {
      "teamWins": 5,
      "opponentWins": 0,
      "totalDecidedMaps": 5,
      "teamWinPercent": 100,
      "opponentWinPercent": 0
    },
    "mapBreakdown": [
      {
        "mapName": "Mirage",
        "played": 2,
        "teamWins": 2,
        "opponentWins": 0,
        "teamWinPercent": 100,
        "opponentWinPercent": 0,
        "roundsFor": 35,
        "roundsAgainst": 30,
        "roundDifferential": 5
      },
      {
        "mapName": "Dust2",
        "played": 2,
        "teamWins": 2,
        "opponentWins": 0,
        "teamWinPercent": 100,
        "opponentWinPercent": 0,
        "roundsFor": 26,
        "roundsAgainst": 13,
        "roundDifferential": 13
      }
    ],
    "recent5Matches": [
      {
        "matchId": "cs2-match-2393245",
        "status": "completed",
        "startsAt": "2026-04-19T17:00:00.000Z",
        "eventName": "IEM Rio 2026",
        "bestOf": 5,
        "opponentId": "cs2-team-7020",
        "opponentName": "Spirit",
        "teamScore": 3,
        "opponentScore": 0,
        "score": "3-0",
        "result": "W",
        "resultType": "played",
        "isForfeit": false,
        "forfeitedMaps": 0,
        "teamPerspective": {
          "teamId": "cs2-team-9565",
          "side": "team2",
          "opponentId": "cs2-team-7020",
          "opponentName": "Spirit",
          "teamScore": 3,
          "opponentScore": 0,
          "result": "W",
          "resultType": "played",
          "isForfeit": false
        },
        "maps": [
          {
            "mapId": "cs2-match-2393245-map-1",
            "mapNumber": 1,
            "mapName": "Mirage",
            "status": "completed",
            "teamScore": 16,
            "opponentScore": 13,
            "score": "16-13",
            "result": "W",
            "resultType": "played",
            "isForfeit": false,
            "forfeitStage": null,
            "winnerTeamId": "cs2-team-9565",
            "roundsFor": 16,
            "roundsAgainst": 13
          },
          {
            "mapId": "cs2-match-2393245-map-2",
            "mapNumber": 2,
            "mapName": "Nuke",
            "status": "completed",
            "teamScore": 13,
            "opponentScore": 10,
            "score": "13-10",
            "result": "W",
            "resultType": "played",
            "isForfeit": false,
            "forfeitStage": null,
            "winnerTeamId": "cs2-team-9565",
            "roundsFor": 13,
            "roundsAgainst": 10
          }
        ]
      },
      {
        "matchId": "cs2-match-2388128",
        "status": "completed",
        "startsAt": "2025-12-13T16:00:00.000Z",
        "eventName": "StarLadder Budapest Major 2025",
        "bestOf": 3,
        "opponentId": "cs2-team-7020",
        "opponentName": "Spirit",
        "teamScore": 2,
        "opponentScore": 0,
        "score": "2-0",
        "result": "W",
        "resultType": "played",
        "isForfeit": false,
        "forfeitedMaps": 0,
        "teamPerspective": {
          "teamId": "cs2-team-9565",
          "side": "team2",
          "opponentId": "cs2-
…

Team head-to-head

GET/api/v1/cs2/h2h/{teamIdOrSlug}/{opponentIdOrSlug}

Record and past matches between two teams. Per-map comparison (win rates, veto tendencies, edge): `/cs2/teams/{teamIdOrSlug}/map-pool/vs/{opponentIdOrSlug}`. Same response as `GET /api/v1/cs2/teams/{teamIdOrSlug}/vs/{opponentIdOrSlug}`.

Query parameters

ParameterTypeDescription
teamIdOrSlug (path)*stringTeam id (cs2-team-7020) or slug (spirit).
opponentIdOrSlug (path)*stringOpponent team id or slug.
bestOfstringFilter by bestOf.
limitintegerRows to return. Maximum 250; larger values are reduced to 250.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/h2h/vitality/natus-vincere" \
  -H "x-api-key: YOUR_API_KEY"

Team map-pool head-to-head

GET/api/v1/cs2/h2h/{teamIdOrSlug}/{opponentIdOrSlug}/map-pool

Two teams compared map by map over a window (default the last 180 days, `window.defaultApplied: true`): every map either team played plus every current pool map. `data`: `team`, `opponent` ({id, name}), `window` {from, to, days, defaultApplied}, `pool` {name, current[], filter, historyAvailable}, `sample` {teamMatches, teamMatchesWithVeto, opponentMatches, opponentMatchesWithVeto, headToHeadMatches}, `countingRules` and `maps[]`. Each map: `mapSlug`, `mapName`, `inPool`, `poolStatus` (`in_pool`, `removed`, `never_in_pool`), `removedAt`, image fields; `team` and `opponent` each {played, wins, losses, winRate (%), roundsFor, roundsAgainst, roundDiff, avgRoundDiff, lastPlayedAt, sample (`none`, `low` <5, `medium` <15, `high`), `veto` {matches (veto matches with the map in the pool: the denominator), picks, bans, deciders, pickRate, banRate, deciderRate, sample}}; `headToHead` {played, teamWins, opponentWins, teamRounds, opponentRounds, lastPlayedAt, sample, maps[] {matchId, playedAt, teamScore, opponentScore, winner}}; `edge` {edge (`team`, `opponent`, `even` or null), edgeTeamId, basis (`win_rate`, `head_to_head_sweep`, `insufficient_sample`), winRateDiff, avgRoundDiffDiff, summary}. Counting: finished maps with a real round score only (forfeits, awarded and unplayed maps are left out). Errors: 404 unknown team or opponent, 400 `SAME_TEAM`, 400 `INVALID_WINDOW`. Same response as `GET /api/v1/cs2/teams/{teamIdOrSlug}/map-pool/vs/{opponentIdOrSlug}`.

Query parameters

ParameterTypeDescription
teamIdOrSlug (path)*stringTeam id (cs2-team-7020) or slug (spirit).
opponentIdOrSlug (path)*stringOpponent team id or slug.
date_endstringFilter by date_end.
date_startstringFilter by date_start.
daysintegerLook-back window in days.
fromstringStart of the date range (ISO 8601, UTC).
inPoolstringFilter by inPool.
poolstringFilter by pool.
tostringEnd of the date range (ISO 8601, UTC).
windowstringFilter by window.
windowDaysintegerLook-back window in days.
window_daysintegerLook-back window in days.

Example

bash
curl "https://api.citoapi.com/api/v1/cs2/h2h/vitality/natus-vincere/map-pool" \
  -H "x-api-key: YOUR_API_KEY"

Try the CS2 Matches API

Run a real request with your key, then wire the same call into your app. The free plan includes 500 requests a month.

bash
curl "https://api.citoapi.com/api/v1/cs2/matches/results?limit=5" \
  -H "x-api-key: YOUR_API_KEY"
Was this page helpful?