CS2 Teams API
Team profiles by id or slug ("vitality", "natus-vincere"): roster and roster history, results, upcoming matches, form, map stats, head-to-head and a map-by-map comparison of two teams. Up to 50 teams in one call with ?ids=.
15 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, Matches, Maps & rounds, Rankings, Players, Events, Stats & leaderboards, Skins, Transfers, Search & reference.
Team transfers
Players who joined or left a team.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| after | string | Only rows after this time (ISO 8601). |
| before | string | Only rows before this time (ISO 8601). |
| from_team | string | Filter by from_team. |
| include_computed | string | Filter by include_computed. |
| include_undated | string | Filter by include_undated. |
| limit | integer | Rows to return. Maximum 200; larger values are reduced to 200. |
| page | integer | Page number, starting at 1. |
| player | string | Player id or slug. |
| player_id | string | Player id or slug. |
| status | string | Filter by status. |
| team | string | Team id or slug. |
| team_id | string | Team id or slug. |
| to_team | string | Filter by to_team. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/transfers" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": {
"entityType": "cs2_player_transfers",
"dataAvailable": true,
"transfers": [
{
"transferKey": "profile-history:2025-01-01:source-player-18221:source-team-9565:source-team-4494:joined",
"playerId": "cs2-player-18221",
"playerName": "Spinx",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/7d7cefdee564f870c5a9e9e34646883d.webp",
"fromTeamId": "cs2-team-9565",
"fromTeamName": "Vitality",
"fromTeamLogoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/0cd34febd1ad61ff888f21b55756003b.webp",
"fromTeamAlternateLogoUrl": null,
"fromTeamDarkUiLogoUrl": null,
"fromTeamIsNoTeam": false,
"toTeamId": "cs2-team-4494",
"toTeamName": "MOUZ",
"toTeamLogoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/0ad08abfc7542d74ca19505208967289.svg",
"toTeamAlternateLogoUrl": null,
"toTeamDarkUiLogoUrl": null,
"toTeamIsNoTeam": false,
"status": "joined",
"role": null,
"transferDate": "2025-01-01T12:00:00.000Z",
"joinDate": "2025-01-01T12:00:00.000Z",
"leaveDate": null,
"detectedAt": "2026-07-10T00:54:23.160Z",
"playerImageIsPlaceholder": false,
"fromTeamLogoIsPlaceholder": false,
"…": "1 more fields"
},
{
"transferKey": "profile-history:2025-01-01:source-player-11816:source-team-6667:source-team-9565:joined",
"playerId": "cs2-player-11816",
"playerName": "ropz",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/6a3d396c8189d1f97ae03a36e4f194d9.webp",
"fromTeamId": "cs2-team-6667",
"fromTeamName": "FaZe",
"fromTeamLogoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/b9b1714c98b7f5ba2f329d35548eba3f.webp",
"fromTeamAlternateLogoUrl": null,
"fromTeamDarkUiLogoUrl": null,
"fromTeamIsNoTeam": false,
"toTeamId": "cs2-team-9565",
"toTeamName": "Vitality",
"toTeamLogoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/0cd34febd1ad61ff888f21b55756003b.webp",
"toTeamAlternateLogoUrl": null,
"toTeamDarkUiLogoUrl": null,
"toTeamIsNoTeam": false,
"status": "joined",
"role": null,
"transferDate": "2025-01-01T12:00:00.000Z",
"joinDate": "2025-01-01T12:00:00.000Z",
"leaveDate": null,
"detectedAt": "2026-07-09T20:16:18.067Z",
"playerImageIsPlaceholder": false,
"fromTeamLogoIsPlaceholder": false,
"…": "1 more fields"
}
]
},
"meta": {
"count": 2,
"total": 33,
"page": 1,
"limit": 2,
"dataAvailable": true,
"totalPages": 17,
"hasNext": true,
"hasPrev": false
}
}Team roster
A team's current players and coach, with role, country and join date where known. `meta.activePlayers` / `meta.coaches` are the active roster counts (equal to `activePlayerCount` / `coachCount`). A team with no active players serves its last known lineup, each row with `lastKnownSource` (`roster_rows`, or `last_match_lineup` with `lastMatchId`, `lastPlayedAt` and `tenureUnavailableReason: derived_from_match_lineup`); its size is `meta.lastKnownPlayerCount` / `lastKnownCoachCount`. `meta.dataAvailable` and `meta.unavailableReason` (`no_active_players` when the team lists none). Roster summary fields count active roster rows only: `rosterStatus` (`complete`, `partial`, `no_active_players`), `activePlayerCount`, `noActivePlayers`, `unknownRosterSlots` (5 minus active players), `partialRoster`. `teamPageRosterStatus` is what the team's own page said when last read. A team with no active players carries its last known lineup: `lastKnownRosterAvailable`, `lastKnownPlayerCount`, `lastKnownCoachCount`, `lastKnownRosterSource` (`roster_rows` or `last_match_lineup`), `lastKnownRosterAsOf` and `rosterAvailableAt`. 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
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/roster" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": [
{
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"playerId": "cs2-player-11893",
"playerNickname": "ZywOo",
"playerName": "Mathieu Herbaut",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/9a20575a48df13463513233c6314f72c.webp",
"playerSlug": "zywoo",
"countryName": "France",
"countryCode": "FR",
"age": 25,
"rating": 1.24,
"mapsPlayed": 167,
"role": "AWPer",
"fromAt": "2018-10-01T12:00:00.000Z",
"toAt": null,
"isActive": true,
"tenureKnown": true,
"tenureUnavailableReason": null,
"lastSyncedAt": "2026-11-11T12:51:13.764Z",
"playerImageIsPlaceholder": false
},
{
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"playerId": "cs2-player-9086",
"playerNickname": "XTQZZZ",
"playerName": "Rémy Quoniam",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/b689e77e923fa8285d5fd19cd911b6b0.webp",
"playerSlug": "xtqzzz",
"countryName": "France",
"countryCode": "FR",
"age": 37,
"rating": null,
"mapsPlayed": null,
"role": "coach",
"fromAt": null,
"toAt": null,
"isActive": true,
"tenureKnown": false,
"tenureUnavailableReason": "source_join_date_unavailable",
"lastSyncedAt": "2026-11-11T12:51:13.373Z",
"playerImageIsPlaceholder": false
}
],
"meta": {
"count": 6,
"dataAvailable": true,
"unavailableReason": null,
"rosterCheckedAt": "2026-11-11T12:51:14.327Z",
"rosterStatus": "complete",
"noActivePlayers": false,
"unknownRosterSlots": 0,
"partialRoster": false,
"activePlayerCount": 5,
"coachCount": 1,
"rosterTenureKnown": false,
"rosterTenureUnavailableReason": "source_join_date_unavailable",
"teamPageRosterStatus": "complete",
"lastKnownRosterAvailable": true,
"lastKnownPlayerCount": 5,
"lastKnownCoachCount": 1,
"lastKnownRosterAsOf": "2026-11-11T12:51:14.327Z",
"rosterAvailableAt": "/api/v1/cs2/teams/vitality/roster",
"activePlayers": 5,
"coaches": 1,
"lastKnownRoster": false,
"limit": 6,
"total": 6,
"page": 1,
"…": "3 more fields"
}
}Team roster history
Every player who has played for a team, with start and end dates. Roster summary fields count active roster rows only: `rosterStatus` (`complete`, `partial`, `no_active_players`), `activePlayerCount`, `noActivePlayers`, `unknownRosterSlots` (5 minus active players), `partialRoster`. `teamPageRosterStatus` is what the team's own page said when last read. A team with no active players carries its last known lineup: `lastKnownRosterAvailable`, `lastKnownPlayerCount`, `lastKnownCoachCount`, `lastKnownRosterSource` (`roster_rows` or `last_match_lineup`), `lastKnownRosterAsOf` and `rosterAvailableAt`. 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
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| changesLimit | string | Filter by changesLimit. |
| limit | integer | Rows to return. Maximum 250; larger values are reduced to 250. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/roster-history" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": {
"entityType": "cs2_team_roster_history",
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"dataAvailable": true,
"rosterStatus": "partial",
"noActivePlayers": false,
"unknownRosterSlots": 3,
"partialRoster": true,
"activePlayerCount": 2,
"coachCount": 0,
"rosterTenureKnown": true,
"rosterTenureUnavailableReason": null,
"teamPageRosterStatus": "complete",
"lastKnownRosterAvailable": true,
"lastKnownPlayerCount": 2,
"lastKnownCoachCount": 0,
"lastKnownRosterAsOf": "2026-11-11T12:51:14.327Z",
"rosterAvailableAt": "/api/v1/cs2/teams/vitality/roster",
"currentRoster": [
{
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"playerId": "cs2-player-11816",
"playerNickname": "ropz",
"playerName": "Robin Kool",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/6a3d396c8189d1f97ae03a36e4f194d9.webp",
"playerSlug": "ropz",
"countryName": "Estonia",
"countryCode": "EE",
"age": 26,
"rating": 1.12,
"mapsPlayed": 170,
"role": "rifler",
"fromAt": "2025-01-01T12:00:00.000Z",
"toAt": null,
"isActive": true,
"tenureKnown": true,
"tenureUnavailableReason": null,
"lastSyncedAt": "2026-11-11T12:51:14.327Z",
"playerImageIsPlaceholder": false
},
{
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"playerId": "cs2-player-18462",
"playerNickname": "mezii",
"playerName": "William Merriman",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/8e03966f6fdc8d8ad9479e45918277c3.webp",
"playerSlug": "mezii",
"countryName": "United Kingdom",
"countryCode": "GB",
"age": 27,
"rating": 1.05,
"mapsPlayed": 119,
"role": "rifler",
"fromAt": "2023-11-01T12:00:00.000Z",
"toAt": null,
"isActive": true,
"tenureKnown": true,
"tenureUnavailableReason": null,
"lastSyncedAt": "2026-11-11T12:51:14.155Z",
"playerImageIsPlaceholder": false
}
],
"activePlayers": [
{
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"playerId": "cs2-player-11816",
"playerNickname": "ropz",
"playerName": "Robin Kool",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/6a3d396c8189d1f97ae03a36e4f194d9.webp",
"playerSlug": "ropz",
"countryName": "Estonia",
"countryCode": "EE",
"age": 26,
"rating": 1.12,
"mapsPlayed": 170,
"role": "rifler",
"fromAt": "2025-01-01T12:00:00.000Z",
"toAt": null,
"isActive": true,
"tenureKnown": true,
"tenureUnavailableReason": null,
"lastSyncedAt": "2026-11-11T12:51:14.327Z",
"playerImageIsPlaceholder": false
},
{
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"playerId": "cs2-player-18462",
"playerNickname": "mezii",
"playerName": "William Merriman",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/8e03966f6fdc8d8ad9479e45918277c3.webp",
"playerSlug": "mezii",
"countryName": "United Kingdom",
"countryCode": "GB",
"age": 27,
"rating": 1.05,
"mapsPlayed": 119,
…Team matches
A team's matches, upcoming and finished. Every row carries `teamPerspective` {teamScore, opponentScore, result (W/L/upcoming/live), resultType, isForfeit} for the team in the path; `score` keeps the raw team1/team2 order. 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
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| bestOf | string | Only 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_end | string | Same as to. |
| date_start | string | Same as from. |
| from | string | Start of the date range (YYYY-MM-DD or ISO 8601, UTC). Alias date_start. |
| limit | integer | Rows to return. Maximum 250; larger values are reduced to 250. |
| offset | integer | Rows to skip, for paging. |
| opponent | string | Only matches against this team (id or slug): the head-to-head history. Aliases opponentId, opponent_id. |
| opponentId | string | Filter by opponentId. |
| opponent_id | string | Filter by opponent_id. |
| order | string | Filter by order. |
| page | integer | Page number, starting at 1. |
| sort | string | asc (oldest first) or desc (newest first). Default: asc for upcoming, desc otherwise. |
| status | string | Filter by status. |
| to | string | End of the date range (YYYY-MM-DD or ISO 8601, UTC); a date-only value includes that whole day. Alias date_end. |
| type | string | all (default), upcoming or completed (recent, results, past are aliases). Every row carries teamPerspective {teamScore, opponentScore, result W/L/upcoming/live} for the team in the path. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/matches" \
-H "x-api-key: YOUR_API_KEY"Response
{
"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": null,
"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": null,
"startsAt": "2026-11-11T04:15:00.000Z",
"endsAt": "2026-11-11T06:18:51.447Z",
"bestOf": 3,
"status": "completed"
…Team upcoming matches
A team's scheduled matches. When there are none, `meta.dataAvailable: false`, `meta.message` and `meta.unavailableReason`: `no_scheduled_matches` (the team was in the world or VRS ranking in the last 21 days, so its schedule is covered), `team_not_tracked_for_schedules` (unranked: fixtures may only appear once played) or `team_inactive` (unranked, no active players, no match in 90 days). Every row carries `teamPerspective` {teamScore, opponentScore, result (W/L/upcoming/live), resultType, isForfeit} for the team in the path; `score` keeps the raw team1/team2 order. These routes are equivalent; use whichever reads best.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| bestOf | string | Only 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. |
| limit | integer | Rows to return. Maximum 50; larger values are reduced to 50. |
| order | string | Filter by order. |
| sort | string | asc (oldest first) or desc (newest first). Default: asc for upcoming, desc otherwise. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/upcoming" \
-H "x-api-key: YOUR_API_KEY"Response
{
"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": null,
"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"
}
],
"meta": {
"count": 1,
"limit": 2,
"type": "upcoming",
"sort": "asc",
"dataAvailable": true,
"unavailableReason": null,
"total": 1,
"page": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}Team results
A team's finished matches, newest first. Filter with `from` / `to` (a bad date is 400 `INVALID_DATE`). Every row carries `teamPerspective` {teamScore, opponentScore, result (W/L/upcoming/live), resultType, isForfeit} for the team in the path; `score` keeps the raw team1/team2 order. 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. These routes are equivalent; use whichever reads best.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| bestOf | string | Only 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_end | string | Same as to. |
| date_start | string | Same as from. |
| from | string | Start of the date range (YYYY-MM-DD or ISO 8601, UTC). Alias date_start. |
| limit | integer | Rows to return. Maximum 250; larger values are reduced to 250. |
| order | string | Filter by order. |
| sort | string | asc (oldest first) or desc (newest first). Default: asc for upcoming, desc otherwise. |
| to | string | End of the date range (YYYY-MM-DD or ISO 8601, UTC); a date-only value includes that whole day. Alias date_end. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/results" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": [
{
"entityType": "cs2_match",
"id": "cs2-match-2399852",
"eventId": "cs2-event-8251",
"eventName": "BLAST Rivals 2026 Season 2",
"eventSlug": "blast-rivals-2026-season-2",
"stageName": null,
"startsAt": "2026-11-11T04:15:00.000Z",
"endsAt": "2026-11-11T06:18:51.447Z",
"bestOf": 3,
"status": "completed",
"team1Id": "cs2-team-9565",
"team2Id": "cs2-team-11283",
"team1Name": "Vitality",
"team2Name": "Falcons",
"team1Score": 2,
"team2Score": 0,
"winnerTeamId": "cs2-team-9565",
"vetoOrder": [
{
"map": "cache",
"order": 1,
"action": "ban",
"teamId": "cs2-team-11283",
"teamName": "Falcons",
"mapName": "cache",
"mapNumber": null,
"played": false
},
{
"map": "ancient",
"order": 2,
"action": "ban",
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"mapName": "ancient",
"mapNumber": null,
"played": false
}
],
"lastSyncedAt": "2026-11-11T12:46:10.483Z",
"lastVerified": "2026-11-11T12:46:10.483Z",
"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-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
},
"team2": {
"id": "cs2-team-11283",
"name": "Falcons",
"slug": "falcons",
"teamTag": "FALCONS",
"logoUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/9e65d7e8195170eaf8992f54dea0f112.webp",
"countryName": "Europe",
"countryCode": null,
"worldRanking": 6,
"worldRankingStatus": "ranked",
"vrsRanking": 9,
"vrsRankingStatus": "ranked",
"vrsRegion": "Europe",
"logoIsPlaceholder": false
},
"…": "18 more fields"
},
{
"entityType": "cs2_match",
"id": "cs2-match-2399758",
"eventId": "cs2-event-8050",
"eventName": "PGL Masters Bucharest 2026",
"eventSlug": "pgl-masters-bucharest-2026",
"stageName": null,
"startsAt": "2026-10-31T08:00:00.000Z",
"endsAt": "
…Team trends
A team's form over time: win rate and rating by period.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| limit | integer | Rows to return. Maximum 200; larger values are reduced to 200. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/trends" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": {
"entityType": "cs2_team_performance_trends",
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"dataAvailable": true,
"trends": [
{
"trendKey": "career:source-team-9565",
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"windowType": "career",
"periodStart": null,
"periodEnd": "2026-11-11T04:41:06.213Z",
"matches": 284,
"matchWins": 221,
"matchLosses": 61,
"maps": 834,
"mapWins": 471,
"mapLosses": 181,
"mapsDecided": 652,
"mapsUnresolved": 182,
"winRate": 0.7837,
"mapWinPercent": 0.7224,
"mapWinPercentBasis": "decided_maps",
"roundsFor": 8313,
"roundsAgainst": 6361,
"opponentDifficulty": null,
"recentForm": {
"endpoint": "/api/v1/cs2/teams/{teamId}/form"
},
"mapStats": {
"endpoint": "/api/v1/cs2/teams/{teamId}/map-stats"
},
"computedAt": "2026-11-11T04:41:06.213Z"
},
{
"trendKey": "last_30_days:source-team-9565",
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"windowType": "last_30_days",
"periodStart": "2026-10-12T04:41:06.213Z",
"periodEnd": "2026-11-11T04:41:06.213Z",
"matches": 8,
"matchWins": 4,
"matchLosses": 3,
"maps": 24,
"mapWins": 9,
"mapLosses": 7,
"mapsDecided": 16,
"mapsUnresolved": 8,
"winRate": 0.5714,
"mapWinPercent": 0.5625,
"mapWinPercentBasis": "decided_maps",
"roundsFor": 180,
"roundsAgainst": 159,
"opponentDifficulty": null,
"recentForm": {
"endpoint": "/api/v1/cs2/teams/{teamId}/form"
},
"mapStats": {
"endpoint": "/api/v1/cs2/teams/{teamId}/map-stats"
},
"computedAt": "2026-11-11T04:41:06.213Z"
}
]
},
"meta": {
"count": 2,
"dataAvailable": true,
"limit": 2,
"total": 2,
"page": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}Team stats
Aggregate team stats over a recent window. `forfeitWins` / `forfeitLosses` count the awarded series inside the totals (wins and losses include forfeits). `recentForm[]` rows carry `resultType`, `isForfeit` and `teamPerspective`. Side (CT/T) and economy numbers are refreshed hourly.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| date_end | string | Same as to. |
| date_start | string | Same as from. |
| days | integer | Only matches from the last N days (e.g. 90). Without a window: the team's last 250 matches. |
| from | string | Start of the date range (YYYY-MM-DD or ISO 8601, UTC). Alias date_start. |
| to | string | End of the date range (YYYY-MM-DD or ISO 8601, UTC); a date-only value includes that whole day. Alias date_end. |
| window | string | Same as days, written as 90d, 12w, 3m or 1y. |
| windowDays | integer | Look-back window in days. |
| window_days | integer | Look-back window in days. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/stats" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": {
"entityType": "cs2_team_stats",
"teamId": "cs2-team-9565",
"window": {
"from": null,
"to": null,
"days": null,
"defaultLastMatches": 250
},
"matches": 247,
"wins": 194,
"losses": 53,
"winRate": 0.7854251012145749,
"forfeitWins": 0,
"forfeitLosses": 0,
"maps": 580,
"mapWinRates": [
{
"mapName": "Inferno",
"played": 112,
"wins": 84,
"losses": 28,
"winRate": 0.75,
"isUnknownMap": false,
"unavailableReason": null,
"mapNameCanonical": "Inferno",
"imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/inferno.png",
"mapImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/inferno.png",
"coverImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/inferno.png",
"inPool": true,
"poolStatus": "in_pool",
"inPoolSince": null,
"removedAt": null,
"poolWindows": [
{
"from": null,
"to": null
}
],
"playedInPool": 112,
"playedOutOfPool": 0,
"playedPoolUnknown": 0,
"lastPlayedInPoolAt": "2026-10-31T08:00:00.000Z",
"inPoolWhenPlayed": true
},
{
"mapName": "Mirage",
"played": 112,
"wins": 80,
"losses": 32,
"winRate": 0.7142857142857143,
"isUnknownMap": false,
"unavailableReason": null,
"mapNameCanonical": "Mirage",
"imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/mirage.png",
"mapImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/mirage.png",
"coverImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/mirage.png",
"inPool": true,
"poolStatus": "in_pool",
"inPoolSince": null,
"removedAt": null,
"poolWindows": [
{
"from": null,
"to": null
}
],
"playedInPool": 112,
"playedOutOfPool": 0,
"playedPoolUnknown": 0,
"lastPlayedInPoolAt": "2026-10-29T10:15:00.000Z",
"inPoolWhenPlayed": true
}
],
"unknownMapCount": 0,
"averageRating": 1.0992642026009583,
"recentForm": [
{
"matchId": "cs2-match-2399852",
"opponentId": "cs2-team-11283",
"opponentName": "Falcons",
"result": "W",
"startsAt": "2026-11-11T04:15:00.000Z",
"score": {
"team1": 2,
"team2": 0
},
"resultType": "played",
"isForfeit": false,
"teamPerspective": {
"teamId": "cs2-team-9565",
"side": "team1",
"opponentId": "cs2-team-11283",
"opponentName": "Falcons",
"teamScore": 2,
"opponentScore": 0,
"result": "W",
"resultType": "played",
"isForfeit": false
}
},
{
"matchId": "cs2-match-2399758",
"opponentId": "cs2-team-4494",
"opponentName": "MOUZ",
"result": "L",
"startsAt": "2026-10-31T08:00:00.000Z",
"score": {
"team1": 0,
"team2": 2
},
"resultType": "played",
"isForfeit": false,
"teamPerspective": {
"teamId": "cs2-team-9565",
"side": "team1",
"opponentId": "cs2-team-4494",
"opponentName": "MOUZ",
"teamS
…Team maps
Maps from a team's matches, one row per map (played or scheduled) with score, halves and winner. Each row has `inPool` (in the current Active Duty pool), `poolStatus` (`in_pool`, `removed`, `never_in_pool`) and `inPoolWhenPlayed` (whether the map was in the Active Duty pool when the match started; null before 2021-05-04). These routes are equivalent; use whichever reads best.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| date_end | string | Same as to. |
| date_start | string | Same as from. |
| days | integer | Only matches from the last N days (e.g. 90). Without a window: the team's last 250 matches. |
| from | string | Start of the date range (YYYY-MM-DD or ISO 8601, UTC). Alias date_start. |
| limit | integer | Rows to return. Maximum 100; larger values are reduced to 100. |
| to | string | End of the date range (YYYY-MM-DD or ISO 8601, UTC); a date-only value includes that whole day. Alias date_end. |
| window | string | Same as days, written as 90d, 12w, 3m or 1y. |
| windowDays | integer | Look-back window in days. |
| window_days | integer | Look-back window in days. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/maps" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": [
{
"entityType": "cs2_map",
"id": "cs2-match-2400201-map-1",
"matchId": "cs2-match-2400201",
"mapNumber": 1,
"mapName": "TBA",
"status": "upcoming",
"team1Score": null,
"team2Score": null,
"team1Halves": null,
"team2Halves": null,
"winnerTeamId": null,
"durationRounds": null,
"lastSyncedAt": "2026-11-11T12:47:57.187Z",
"inPool": null,
"inPoolWhenPlayed": null,
"poolStatus": null,
"mapImageUrl": null,
"pickTeamId": null,
"objectiveStats": {
"dataAvailable": false,
"unavailableReason": "not_yet_indexed",
"confidence": {
"plants": "high",
"defuses": "high",
"explosions": "high",
"clutchDefuse": "medium"
},
"teamStats": [],
"roundEvents": []
},
"availableSubresources": [],
"unavailableSubresources": [
"player_stats",
"objective_stats"
],
"unavailableFields": {},
"dataQuality": "partial",
"confidence": "medium",
"…": "13 more fields"
},
{
"entityType": "cs2_map",
"id": "cs2-match-2400201-map-2",
"matchId": "cs2-match-2400201",
"mapNumber": 2,
"mapName": "TBA",
"status": "upcoming",
"team1Score": null,
"team2Score": null,
"team1Halves": null,
"team2Halves": null,
"winnerTeamId": null,
"durationRounds": null,
"lastSyncedAt": "2026-11-11T12:47:57.218Z",
"inPool": null,
"inPoolWhenPlayed": null,
"poolStatus": null,
"mapImageUrl": null,
"pickTeamId": null,
"objectiveStats": {
"dataAvailable": false,
"unavailableReason": "not_yet_indexed",
"confidence": {
"plants": "high",
"defuses": "high",
"explosions": "high",
"clutchDefuse": "medium"
},
"teamStats": [],
"roundEvents": []
},
"availableSubresources": [],
"unavailableSubresources": [
"player_stats",
"objective_stats"
],
"unavailableFields": {},
"dataQuality": "partial",
"confidence": "medium",
"…": "13 more fields"
}
],
"meta": {
"count": 2,
"dataAvailable": true,
"unavailableReason": null,
"limit": 2,
"total": 2,
"page": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}Team form
A team's last results as a W/L sequence with scores. Each match has `resultType` (played, partial_forfeit, forfeit, not_played), `isForfeit`, `forfeitedMaps` and `teamPerspective`; each map `resultType` and `isForfeit`. `record` adds `forfeitWins` / `forfeitLosses` (already inside wins / losses).
Query parameters
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| limit | integer | Rows to return. Maximum 50; larger values are reduced to 50. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/form" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": {
"entityType": "cs2_team_form",
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"window": 2,
"record": {
"wins": 1,
"losses": 1,
"unknown": 0,
"winPercent": 50,
"forfeitWins": 0,
"forfeitLosses": 0
},
"matches": [
{
"matchId": "cs2-match-2399852",
"status": "completed",
"startsAt": "2026-11-11T04:15:00.000Z",
"eventName": "BLAST Rivals 2026 Season 2",
"bestOf": 3,
"opponentId": "cs2-team-11283",
"opponentName": "Falcons",
"teamScore": 2,
"opponentScore": 0,
"score": "2-0",
"result": "W",
"resultType": "played",
"isForfeit": false,
"forfeitedMaps": 0,
"teamPerspective": {
"teamId": "cs2-team-9565",
"side": "team1",
"opponentId": "cs2-team-11283",
"opponentName": "Falcons",
"teamScore": 2,
"opponentScore": 0,
"result": "W",
"resultType": "played",
"isForfeit": false
},
"maps": [
{
"mapId": "cs2-match-2399852-map-1",
"mapNumber": 1,
"mapName": "Anubis",
"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,
"inPool": true,
"inPoolWhenPlayed": true,
"poolStatus": "in_pool",
"poolWindows": [
"…"
]
},
{
"mapId": "cs2-match-2399852-map-2",
"mapNumber": 2,
"mapName": "Dust2",
"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,
"inPool": true,
"inPoolWhenPlayed": true,
"poolStatus": "in_pool",
"poolWindows": [
"…"
]
}
]
},
{
"matchId": "cs2-match-2399758",
"status": "completed",
"startsAt": "2026-10-31T08:00:00.000Z",
"eventName": "PGL Masters Bucharest 2026",
"bestOf": 3,
"opponentId": "cs2-team-4494",
"opponentName": "MOUZ",
"teamScore": 0,
"opponentScore": 2,
"score": "0-2",
"result": "L",
"resultType": "played",
"isForfeit": false,
"forfeitedMaps": 0,
"teamPerspective": {
"teamId": "cs2-team-9565",
"side": "team1",
"opponentId": "cs2-team-4494",
"opponentName": "MOUZ",
"teamScore": 0,
"opponentScore": 2,
"result": "L",
"resultType": "played",
"isForfeit": false
},
"maps": [
{
"mapId": "cs2-match-2399758-map-1",
"mapNumber": 1,
"mapName": "Nuke",
"status": "completed",
"teamScore": 7,
"opponentScore": 13,
"score": "7-13",
…Team map stats
Per-map win rate, rounds and pick/ban tendencies. Each map row has `inPool` (in the current Active Duty pool), `poolStatus` (`in_pool`, `removed`, `never_in_pool`), `inPoolSince`, `removedAt`, `poolWindows[]`, and `playedInPool` / `playedOutOfPool` / `playedPoolUnknown` / `lastPlayedInPoolAt` (plays counted by whether the map was in the pool on the match date). Top level: `activeDutyPool[]` and `poolFilter`. Filter with `inPool=true|false` or `pool=current|removed|all`; totals follow the filter.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| date_end | string | Same as to. |
| date_start | string | Same as from. |
| days | integer | Only matches from the last N days (e.g. 90). Without a window: the team's last 250 matches. |
| from | string | Start of the date range (YYYY-MM-DD or ISO 8601, UTC). Alias date_start. |
| inPool | string | true: only maps in the current Active Duty pool; false: only maps outside it. Alias in_pool. |
| in_pool | string | Same as inPool. |
| limit | integer | Rows to return. Maximum 250; larger values are reduced to 250. |
| pool | string | current (= inPool=true), removed (maps that left the pool) or all (default). |
| to | string | End of the date range (YYYY-MM-DD or ISO 8601, UTC); a date-only value includes that whole day. Alias date_end. |
| window | string | Same as days, written as 90d, 12w, 3m or 1y. |
| windowDays | integer | Look-back window in days. |
| window_days | integer | Look-back window in days. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/map-stats" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": {
"entityType": "cs2_team_map_stats",
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"matchWindow": 2,
"windowDays": null,
"totalMaps": 2,
"totalMapWins": 2,
"mapWinPercent": 100,
"sideEconomy": {
"ctRounds": 1138,
"ctWins": 724,
"tRounds": 1096,
"tWins": 562,
"pistolRounds": 208,
"pistolWins": 119,
"ecoRounds": 166,
"ecoWins": 34,
"forceRounds": 271,
"forceWins": 101,
"fullBuyRounds": 1589,
"fullBuyWins": 1032,
"ctWinPercent": 63.6,
"tWinPercent": 51.3,
"pistolWinPercent": 57.2,
"ecoWinPercent": 20.5,
"forceWinPercent": 37.3,
"fullBuyWinPercent": 64.9
},
"activeDutyPool": [
"Ancient",
"Anubis"
],
"poolFilter": "all",
"maps": [
{
"mapName": "Anubis",
"played": 1,
"wins": 1,
"losses": 0,
"ties": 0,
"roundsFor": 13,
"roundsAgainst": 10,
"latestPlayedAt": "2026-11-11T04:15:00.000Z",
"isUnknownMap": false,
"unavailableReason": null,
"mapNameCanonical": "Anubis",
"imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/anubis.png",
"mapImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/anubis.png",
"coverImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/anubis.png",
"pickPercent": 50,
"winPercent": 100,
"lossPercent": 0,
"roundDifferential": 3,
"avgRoundsFor": 13,
"avgRoundsAgainst": 10,
"ctRounds": 183,
"ctWins": 95,
"ctWinPercent": 51.9,
"tRounds": 157,
"…": "23 more fields"
},
{
"mapName": "Dust2",
"played": 1,
"wins": 1,
"losses": 0,
"ties": 0,
"roundsFor": 13,
"roundsAgainst": 10,
"latestPlayedAt": "2026-11-11T04:15:00.000Z",
"isUnknownMap": false,
"unavailableReason": null,
"mapNameCanonical": "Dust2",
"imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/dust2.png",
"mapImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/dust2.png",
"coverImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/dust2.png",
"pickPercent": 50,
"winPercent": 100,
"lossPercent": 0,
"roundDifferential": 3,
"avgRoundsFor": 13,
"avgRoundsAgainst": 10,
"ctRounds": 257,
"ctWins": 168,
"ctWinPercent": 65.4,
"tRounds": 270,
"…": "23 more fields"
}
],
"dataAvailable": true
},
"meta": {
"count": 2,
"dataAvailable": true,
"limit": 2,
"total": 2,
"page": 1,
"totalPages": 1,
"hasNext": false,
"hasPrev": false
}
}Team head-to-head
Record and past matches between two teams. Per-map comparison (win rates, veto tendencies, edge): `/cs2/teams/{teamIdOrSlug}/map-pool/vs/{opponentIdOrSlug}`. These routes are equivalent; use whichever reads best.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| opponentIdOrSlug (path)* | string | Opponent team id or slug. |
| bestOf | string | Only 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. |
| limit | integer | Rows to return. Maximum 250; larger values are reduced to 250. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/vs/natus-vincere" \
-H "x-api-key: YOUR_API_KEY"Response
{
"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 map-pool head-to-head
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`. These routes are equivalent; use whichever reads best.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| opponentIdOrSlug (path)* | string | Opponent team id or slug. |
| date_end | string | Same as to. |
| date_start | string | Same as from. |
| days | integer | Window in days (default 180). Aliases windowDays, window_days. |
| from | string | Start of the date range (YYYY-MM-DD or ISO 8601, UTC). Alias date_start. |
| inPool | string | true or false: same as pool=current / maps outside the current pool. |
| pool | string | current / in_pool (maps in the current pool), removed, or all (default: every map either team played plus every current pool map). |
| to | string | End of the date range (YYYY-MM-DD or ISO 8601, UTC); a date-only value includes that whole day. Alias date_end. |
| window | string | Same as days, written as 90d, 12w, 3m or 1y. |
| windowDays | integer | Look-back window in days. |
| window_days | integer | Look-back window in days. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality/map-pool/vs/natus-vincere" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": {
"entityType": "cs2_team_map_pool_vs",
"team": {
"id": "cs2-team-9565",
"name": "Vitality"
},
"opponent": {
"id": "cs2-team-7020",
"name": "Spirit"
},
"window": {
"from": "2026-05-15T12:57:26.424Z",
"to": "2026-11-11T12:57:26.559Z",
"days": 180,
"defaultApplied": true
},
"pool": {
"name": "Active Duty",
"current": [
"Ancient",
"Inferno"
],
"filter": "all",
"historyAvailable": true
},
"sample": {
"teamMatches": 34,
"teamMatchesWithVeto": 34,
"opponentMatches": 35,
"opponentMatchesWithVeto": 35,
"headToHeadMatches": 0
},
"maps": [
{
"mapSlug": "dust2",
"mapName": "Dust2",
"inPool": true,
"poolStatus": "in_pool",
"removedAt": null,
"team": {
"played": 21,
"wins": 15,
"losses": 6,
"winRate": 71.4,
"roundsFor": 258,
"roundsAgainst": 179,
"roundDiff": 79,
"avgRoundDiff": 3.8,
"lastPlayedAt": "2026-11-11T04:15:00.000Z",
"sample": "high",
"veto": {
"matches": 34,
"picks": 13,
"bans": 0,
"deciders": 6,
"pickRate": 38.2,
"banRate": 0,
"deciderRate": 17.6,
"sample": "high"
}
},
"opponent": {
"played": 21,
"wins": 13,
"losses": 8,
"winRate": 61.9,
"roundsFor": 249,
"roundsAgainst": 200,
"roundDiff": 49,
"avgRoundDiff": 2.3,
"lastPlayedAt": "2026-10-28T16:00:00.000Z",
"sample": "high",
"veto": {
"matches": 35,
"picks": 18,
"bans": 0,
"deciders": 7,
"pickRate": 51.4,
"banRate": 0,
"deciderRate": 20,
"sample": "high"
}
},
"headToHead": {
"played": 0,
"teamWins": 0,
"opponentWins": 0,
"teamRounds": 0,
"opponentRounds": 0,
"lastPlayedAt": null,
"sample": "none",
"maps": []
},
"edge": {
"edge": "even",
"edgeTeamId": null,
"basis": "win_rate",
"winRateDiff": 9.5,
"avgRoundDiffDiff": 1.5,
"summary": "Dust2: even. Vitality 15-6 (71.4%, +3.8 rds/map) vs Spirit 13-8 (61.9%, +2.3 rds/map); Vitality picks it 38.2% of vet…"
},
"mapNameCanonical": "Dust2",
"imageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/dust2.png",
"mapImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/dust2.png",
"coverImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/maps/dust2.png",
"pickTeamId": null,
"objectiveStats": {
"dataAvailable": false,
"unavailableReason": "not_yet_indexed",
"confidence": {
"plants": "high",
"defuses": "high",
"explosions": "high",
"clutchDefuse": "medium"
},
"teamStats": [],
"roundEvents": []
}
},
{
"mapSlug": "mirage",
"mapName": "Mirage",
"inPool": true,
"poolStatus": "in_pool",
"removedAt": null,
"team": {
"played": 13,
…Team details
One team: name, logo, country, region, world ranking and current roster. Roster summary fields count active roster rows only: `rosterStatus` (`complete`, `partial`, `no_active_players`), `activePlayerCount`, `noActivePlayers`, `unknownRosterSlots` (5 minus active players), `partialRoster`. `teamPageRosterStatus` is what the team's own page said when last read. A team with no active players carries its last known lineup: `lastKnownRosterAvailable`, `lastKnownPlayerCount`, `lastKnownCoachCount`, `lastKnownRosterSource` (`roster_rows` or `last_match_lineup`), `lastKnownRosterAsOf` and `rosterAvailableAt`. 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
| Parameter | Type | Description |
|---|---|---|
| teamIdOrSlug (path)* | string | Team id (cs2-team-7020) or slug (spirit). |
| recentLimit | string | Filter by recentLimit. |
| recent_limit | string | Filter by recent_limit. |
| upcomingLimit | string | Filter by upcomingLimit. |
| upcoming_limit | string | Filter by upcoming_limit. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": {
"entityType": "cs2_team",
"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,
"region": "Europe",
"worldRanking": 3,
"lastSyncedAt": "2026-11-11T12:51:12.392Z",
"lastVerified": "2026-11-11T12:51:12.392Z",
"confidence": "high",
"roster": [
{
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"playerId": "cs2-player-11893",
"playerNickname": "ZywOo",
"playerName": "Mathieu Herbaut",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/9a20575a48df13463513233c6314f72c.webp",
"playerSlug": "zywoo",
"countryName": "France",
"countryCode": "FR",
"age": 25,
"rating": 1.24,
"mapsPlayed": 167,
"role": "AWPer",
"fromAt": "2018-10-01T12:00:00.000Z",
"toAt": null,
"isActive": true,
"tenureKnown": true,
"tenureUnavailableReason": null,
"lastSyncedAt": "2026-11-11T12:51:13.764Z",
"playerImageIsPlaceholder": false
},
{
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"playerId": "cs2-player-9086",
"playerNickname": "XTQZZZ",
"playerName": "Rémy Quoniam",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/b689e77e923fa8285d5fd19cd911b6b0.webp",
"playerSlug": "xtqzzz",
"countryName": "France",
"countryCode": "FR",
"age": 37,
"rating": null,
"mapsPlayed": null,
"role": "coach",
"fromAt": null,
"toAt": null,
"isActive": true,
"tenureKnown": false,
"tenureUnavailableReason": "source_join_date_unavailable",
"lastSyncedAt": "2026-11-11T12:51:13.373Z",
"playerImageIsPlaceholder": false
}
],
"recentResults": [
{
"entityType": "cs2_match",
"id": "cs2-match-2399852",
"eventId": "cs2-event-8251",
"eventName": "BLAST Rivals 2026 Season 2",
"eventSlug": "blast-rivals-2026-season-2",
"stageName": null,
"startsAt": "2026-11-11T04:15:00.000Z",
"endsAt": "2026-11-11T06:18:51.447Z",
"bestOf": 3,
"status": "completed",
"team1Id": "cs2-team-9565",
"team2Id": "cs2-team-11283",
"team1Name": "Vitality",
"team2Name": "Falcons",
"team1Score": 2,
"team2Score": 0,
"winnerTeamId": "cs2-team-9565",
"vetoOrder": [
{
"map": "cache",
"order": 1,
"action": "ban",
"teamId": "cs2-team-11283",
"teamName": "Falcons",
"mapName": "cache",
"mapNumber": null,
"played": false
},
{
"map": "ancient",
"order": 2,
"action": "ban",
"teamId": "cs2-team-9565",
"teamName": "Vitality",
"mapName": "ancient",
"mapNumber": null,
"played": false
}
],
"lastSyncedAt": "2026-11-11T12:46:10.483Z",
"lastVerified": "2026-11-11T12:46:10.483Z",
"confidence": "high",
"event": {
"id": "cs2-event-8251",
"name": "BLAST Riva
…List teams
Teams ordered by world ranking, with logo, country and roster. `compact=true` returns lighter rows. Roster summary fields count active roster rows only: `rosterStatus` (`complete`, `partial`, `no_active_players`), `activePlayerCount`, `noActivePlayers`, `unknownRosterSlots` (5 minus active players), `partialRoster`. `teamPageRosterStatus` is what the team's own page said when last read. A team with no active players carries its last known lineup: `lastKnownRosterAvailable`, `lastKnownPlayerCount`, `lastKnownCoachCount`, `lastKnownRosterSource` (`roster_rows` or `last_match_lineup`), `lastKnownRosterAsOf` and `rosterAvailableAt`. **Many teams in one call:** `?ids=a,b,c` (comma-separated, or repeat `ids=`; up to 50 ids or slugs, anything the single-team 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
| Parameter | Type | Description |
|---|---|---|
| expand | string | full with ids: each item is the full single-team response. |
| fields | string | Comma-separated list of fields to return. |
| ids | string | Batch read: up to 50 comma-separated team ids or slugs. Billed one call per started 10 ids. |
| limit | integer | Rows to return. Maximum 100; larger values are reduced to 100. |
| offset | integer | Rows to skip, for paging. |
| page | integer | Page number, starting at 1. |
| q | string | Search text. |
| search | string | Search text. |
| summary | boolean | true returns a summary instead of full rows. |
Example
curl "https://api.citoapi.com/api/v1/cs2/teams" \
-H "x-api-key: YOUR_API_KEY"Response
{
"success": true,
"data": [
{
"entityType": "cs2_team",
"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,
"region": "Europe",
"worldRanking": 1,
"lastSyncedAt": "2026-11-11T12:57:09.986Z",
"lastVerified": "2026-11-11T12:57:09.986Z",
"confidence": "high",
"roster": [
{
"teamId": "cs2-team-4494",
"teamName": "MOUZ",
"playerId": "cs2-player-18072",
"playerNickname": "torzsi",
"playerName": "Ádám Torzsás",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/8f6c7f48ec93ae0e4fb8daf6bfd782b7.webp",
"playerSlug": "torzsi",
"countryName": "Hungary",
"countryCode": "HU",
"age": 24,
"rating": 1.11,
"mapsPlayed": 176,
"role": "AWPer",
"fromAt": "2022-01-01T12:00:00.000Z",
"toAt": null,
"isActive": true,
"tenureKnown": true,
"tenureUnavailableReason": null,
"lastSyncedAt": "2026-11-11T12:51:03.551Z",
"playerImageIsPlaceholder": false
},
{
"teamId": "cs2-team-4494",
"teamName": "MOUZ",
"playerId": "cs2-player-9295",
"playerNickname": "sycrone",
"playerName": "Dennis Nielsen",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/1bc75d13f7ab89e38dd882fa9d2e9b9b.png",
"playerSlug": "sycrone",
"countryName": "Denmark",
"countryCode": "DK",
"age": 30,
"rating": null,
"mapsPlayed": null,
"role": "coach",
"fromAt": null,
"toAt": null,
"isActive": true,
"tenureKnown": false,
"tenureUnavailableReason": "source_join_date_unavailable",
"lastSyncedAt": "2026-11-11T12:51:03.374Z",
"playerImageIsPlaceholder": false
}
],
"rankingHistoryCount": 180,
"rankingDevelopmentCount": 180,
"trophiesCount": 15,
"achievementsCount": 15,
"newsLinksCount": 10,
"heavyFieldsOmitted": [
"rankingHistory",
"rankingDevelopment"
],
"heavyFieldsAvailableAt": "/api/v1/cs2/teams/mouz",
"rosterStatus": "complete",
"noActivePlayers": false,
"unknownRosterSlots": 0,
"…": "24 more fields"
},
{
"entityType": "cs2_team",
"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",
"region": "South America",
"worldRanking": 2,
"lastSyncedAt": "2026-11-11T12:51:07.252Z",
"lastVerified": "2026-11-11T12:51:07.252Z",
"confidence": "high",
"roster": [
{
"teamId": "cs2-team-8297",
"teamName": "FURIA",
"playerId": "cs2-player-24144",
"playerNickname": "molodoy",
"playerName": "Danil Golubenko",
"playerImageUrl": "https://api.citoapi.com/api/v1/public/images/cs2/logos/a957d7dbdef15cf9bdc816727f6da173.webp",
"playerSlug": "molodoy",
"count
…Try the CS2 Teams API
Run a real request with your key, then wire the same call into your app. The free plan includes 500 requests a month.
curl "https://api.citoapi.com/api/v1/cs2/teams/vitality" \
-H "x-api-key: YOUR_API_KEY"