Match Statistics API
Complete reference for CS2 match stats — endpoint, SDK, response shape, and all fields
Overview
The Match Statistics API returns pre-aggregated analytics for a single CS2 map (match): match metadata, round-level overview, per-player stats (including weapon and utility breakdowns), weapon stats by weapon and category, utility usage, team totals, top performers, and optional recent kills and demos.
Use this when you need full analytics (weapon categories, top weapons, team stats, top performers). For basic match details and player lists only, use matches.get() instead.
Scope
All stats are organization-scoped. You only receive data for maps on servers owned by your organization. The mapId is the unique ID of the map (same as the match/map resource ID).
HTTP API
Endpoint
| Method | Path | Description |
|---|---|---|
GET | /v1/cs2/matches/:mapId/stats | Get comprehensive statistics for a single map |
Path parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
mapId | string | Yes | Unique ID of the map (match). Same as the id from list or get. |
Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <your-api-key> |
Content-Type | No | Response is JSON. |
Query parameters
None. Stats are returned in a single response.
Example request (cURL)
curl -X GET "https://api.sweathost.com/v1/cs2/matches/MAP_UUID_123/stats" \
-H "Authorization: Bearer YOUR_API_KEY"SDK
getStats(matchId, options?)
Fetches full match statistics for the given map ID.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
matchId | string | Yes | The map (match) ID — same as mapId in the HTTP path. |
options | RequestOptions | No | Optional request config (e.g. custom headers, timeout). |
Return type
Promise<MatchStats>
Example
import { createClient } from '@sweathost/sdk';
const client = createClient({ apiKey: process.env.SWEATHOST_API_KEY! });
const stats = await client.matches.getStats('map-uuid-123');
console.log(stats.match.map); // e.g. "de_dust2"
console.log(stats.overview.totalKills); // number
console.log(stats.topPerformers.topKiller.name);Response structure
The response is a single JSON object of type MatchStats with the following top-level keys.
| Key | Type | Description |
|---|---|---|
match | object | Basic match (map) metadata. |
overview | object | Map-wide totals (kills, deaths, rounds, damage, headshots, averages). |
players | Cs2PlayerWithStats[] | All players with extended weapon/utility stats. |
weaponStats | object | Aggregated weapon stats by weapon, by category, and top weapons. |
utilityStats | object | Aggregated utility usage by type and total thrown. |
teamStats | object | Per-team totals and averages (team1, team2). |
topPerformers | object | Top killer, ADR, KD, HS%, and MVPs. |
recentKills | array | (If returned) Last N kill events. |
demos | array | (If returned) Demo file metadata. |
match
Basic information about the map (match).
| Field | Type | Description |
|---|---|---|
id | string | Unique map ID. |
matchId | string | null | Legacy/external match reference. |
seriesId | string | (If present) Parent series ID. |
serverId | string | (If present) Server ID. |
serverName | string | (If present) Server display name. |
map | string | Map name (e.g. de_dust2). |
gameMode | string | Game mode. |
team1Name | string | null | Team 1 name. |
team2Name | string | null | Team 2 name. |
team1Score | number | Team 1 round score. |
team2Score | number | Team 2 round score. |
status | string | e.g. finished, live. |
startedAt | string | ISO 8601 start time. |
finishedAt | string | null | ISO 8601 end time. |
duration | number | null | Duration in seconds. |
overview
Map-wide aggregate numbers.
| Field | Type | Description |
|---|---|---|
totalKills | number | Total kills in the map. |
totalDeaths | number | Total deaths. |
totalAssists | number | Total assists. |
totalRounds | number | Total rounds played. |
totalDamage | number | Sum of damage dealt by all players. |
totalHeadshots | number | Total headshot kills. |
averageKD | number | Average K/D ratio across players. |
players
Array of players with full stats for this map. Each item is Cs2PlayerWithStats: base player stats plus optional weaponStats and utilityStats arrays.
Base player stats (Cs2PlayerStats)
| Field | Type | Description |
|---|---|---|
id | string | Player record ID. |
matchId | string | Map ID. |
steamId | string | Steam ID. |
name | string | In-game name. |
team | number | Team number (e.g. 2 = T, 3 = CT). |
kills | number | Kills. |
deaths | number | Deaths. |
assists | number | Assists. |
headshots | number | Headshot kills. |
mvps | number | MVPs. |
score | number | Score. |
damageDealt | number | null | Total damage dealt. |
utilityDamage | number | null | Damage from utility. |
flashAssists | number | null | Flash assists. |
firstKills | number | null | First kills. |
firstDeaths | number | null | First deaths. |
bombPlants | number | null | Bomb plants. |
bombDefuses | number | null | Bomb defuses. |
clutchWins | number | null | Clutch wins. |
entryKills | number | null | Entry kills. |
tradeKills | number | null | Trade kills. |
bulletsFired | number | null | Bullets fired. |
bulletsHit | number | null | Bullets hit. |
accuracyPercent | number | null | Accuracy %. |
hsPercent | number | null | Headshot %. |
kdRatio | number | null | K/D ratio. |
adr | number | null | Average damage per round. |
kastPercent | number | null | KAST %. |
impactRating | number | null | Impact rating. |
roundsPlayed | number | null | Rounds played. |
roundsWon | number | null | Rounds won. |
roundsLost | number | null | Rounds lost. |
Per-player weapon stats (Cs2PlayerWeaponStats[])
Each element in player.weaponStats:
| Field | Type | Description |
|---|---|---|
id | string | Record ID. |
playerId | string | Player record ID. |
weaponName | string | Weapon name (e.g. weapon_ak47). |
kills | number | Kills with this weapon. |
headshots | number | Headshots with this weapon. |
damage | number | Damage dealt. |
shotsFired | number | Shots fired. |
shotsHit | number | Shots hit. |
accuracyPercent | number | null | Accuracy %. |
Per-player utility stats (Cs2PlayerUtilityStats[])
Each element in player.utilityStats:
| Field | Type | Description |
|---|---|---|
id | string | Record ID. |
playerId | string | Player record ID. |
utilityType | string | e.g. flashbang, he, smoke, molotov. |
thrown | number | Number thrown. |
enemiesFlashed | number | null | Enemies flashed. |
damageDealt | number | null | Damage from utility. |
successfulSmokes | number | null | Successful smokes. |
weaponStats
Aggregated weapon data for the whole map.
| Key | Type | Description |
|---|---|---|
byWeapon | WeaponStat[] | All weapons, sorted by kills (desc). |
byCategory | WeaponCategoryStat[] | Kills/headshots grouped by category. |
topWeapons | WeaponStat[] | Top 5 weapons by kills. |
WeaponStat (byWeapon / topWeapons)
| Field | Type | Description |
|---|---|---|
weapon | string | Weapon name. |
kills | number | Total kills. |
headshots | number | Total headshots. |
damage | number | Total damage. |
hsRate | number | Headshot rate (0–100). |
WeaponCategoryStat (byCategory)
Categories: Rifle, Sniper, SMG, Pistol, Heavy, Other.
| Field | Type | Description |
|---|---|---|
category | string | Category name. |
kills | number | Kills in this category. |
headshots | number | Headshots in this category. |
utilityStats
Aggregated utility usage for the map.
| Key | Type | Description |
|---|---|---|
byType | UtilityStat[] | Per utility type. |
total | number | Total utility items thrown. |
UtilityStat (byType)
| Field | Type | Description |
|---|---|---|
type | string | e.g. flashbang, he, smoke, molotov. |
thrown | number | Count thrown. |
enemiesFlashed | number | (If applicable) Enemies flashed. |
damageDealt | number | (If applicable) Damage. |
successfulSmokes | number | (If applicable) Successful smokes. |
effectiveness | number | (If applicable) Effectiveness metric. |
teamStats
Per-team totals and averages. team1 usually corresponds to the first team (e.g. T side in first half), team2 to the second (e.g. CT).
team1 / team2
| Field | Type | Description |
|---|---|---|
name | string | Team name. |
score | number | Round score. |
mapsWon | number | (If present) Maps won in series. |
totalKills | number | Team total kills. |
totalDeaths | number | Team total deaths. |
totalAssists | number | Team total assists. |
totalDamage | number | Team total damage. |
averageKD | number | Average K/D of players. |
averageADR | number | Average ADR. |
topPerformers
One player per category (full Cs2PlayerWithStats object).
| Key | Type | Description |
|---|---|---|
topKiller | Cs2PlayerWithStats | Most kills. |
topADR | Cs2PlayerWithStats | Highest ADR. |
topKD | Cs2PlayerWithStats | Highest K/D. |
topHS | Cs2PlayerWithStats | Highest headshot %. |
mostMVPs | Cs2PlayerWithStats | Most MVPs. |
(Some responses may expose topDamage instead of or in addition to topADR; same shape.)
recentKills (optional)
When present, an array of the most recent kill events (e.g. last 20). Each item typically includes killer, victim, weapon, headshot, timestamp, round.
demos (optional)
When present, an array of demo file metadata:
| Field | Type | Description |
|---|---|---|
id | string | Demo ID. |
fileName | string | File name. |
fileSize | string | Size (e.g. bigint as string). |
downloadUrl | string | null | Download URL if available. |
recordedAt | string | ISO 8601. |
expiresAt | string | null | URL expiry if applicable. |
TypeScript interfaces
For use in your app or SDK typings:
interface MatchStats {
match: {
id: string;
matchId?: string | null;
seriesId?: string;
serverId?: string;
serverName?: string;
map: string;
gameMode: string;
team1Name?: string | null;
team2Name?: string | null;
team1Score: number;
team2Score: number;
status: string;
startedAt: string;
finishedAt?: string | null;
duration?: number | null;
};
overview: {
totalKills: number;
totalDeaths: number;
totalAssists: number;
totalRounds: number;
totalDamage: number;
totalHeadshots: number;
averageKD: number;
};
players: Cs2PlayerWithStats[];
weaponStats: {
byWeapon: Array<{ weapon: string; kills: number; headshots: number; damage: number; hsRate: number }>;
byCategory?: Array<{ category: string; kills: number; headshots: number }>;
topWeapons: Array<{ weapon: string; kills: number; headshots: number; damage: number; hsRate: number }>;
};
utilityStats: {
byType: Array<{
type: string;
thrown: number;
enemiesFlashed?: number;
damageDealt?: number;
successfulSmokes?: number;
effectiveness?: number;
}>;
total: number;
};
teamStats: {
team1: { name: string; score: number; totalKills: number; totalDeaths: number; totalAssists: number; totalDamage: number; averageKD: number; averageADR: number };
team2: { name: string; score: number; totalKills: number; totalDeaths: number; totalAssists: number; totalDamage: number; averageKD: number; averageADR: number };
};
topPerformers: {
topKiller: Cs2PlayerWithStats;
topADR: Cs2PlayerWithStats;
topKD: Cs2PlayerWithStats;
topHS: Cs2PlayerWithStats;
mostMVPs: Cs2PlayerWithStats;
};
recentKills?: unknown[];
demos?: Array<{ id: string; fileName: string; fileSize: string; downloadUrl?: string | null; recordedAt: string; expiresAt?: string | null }>;
}Full player and weapon/utility types are in @sweathost/shared-types: Cs2PlayerWithStats, Cs2PlayerWeaponStats, Cs2PlayerUtilityStats.
Examples
SDK: Overview and top performers
const stats = await client.matches.getStats('map-uuid-123');
console.log(`${stats.match.team1Name} ${stats.match.team1Score} - ${stats.match.team2Score} ${stats.match.team2Name}`);
console.log(`Map: ${stats.match.map} | Rounds: ${stats.overview.totalRounds}`);
console.log(`Kills: ${stats.overview.totalKills} | Headshots: ${stats.overview.totalHeadshots}`);
const top = stats.topPerformers;
console.log(`Top killer: ${top.topKiller.name} (${top.topKiller.kills}K)`);
console.log(`Top ADR: ${top.topADR.name} (${top.topADR.adr ?? 0})`);
console.log(`Top HS%: ${top.topHS.name} (${top.topHS.hsPercent ?? 0}%)`);SDK: Weapon and utility breakdown
const stats = await client.matches.getStats('map-uuid-123');
// By category (Rifle, Sniper, SMG, Pistol, Heavy, Other)
stats.weaponStats.byCategory?.forEach(cat => {
console.log(`${cat.category}: ${cat.kills} kills, ${cat.headshots} HS`);
});
// Top 5 weapons
stats.weaponStats.topWeapons.forEach((w, i) => {
console.log(`${i + 1}. ${w.weapon}: ${w.kills} kills, ${w.hsRate.toFixed(1)}% HS`);
});
// Utility
console.log(`Total utility thrown: ${stats.utilityStats.total}`);
stats.utilityStats.byType.forEach(u => {
const pct = stats.utilityStats.total ? (u.thrown / stats.utilityStats.total * 100).toFixed(1) : '0';
console.log(` ${u.type}: ${u.thrown} (${pct}%)`);
});SDK: Team comparison
const stats = await client.matches.getStats('map-uuid-123');
const t1 = stats.teamStats.team1;
const t2 = stats.teamStats.team2;
console.log(`${t1.name}: ${t1.totalKills}K / ${t1.totalDeaths}D, ${t1.totalDamage} dmg, avg KD ${t1.averageKD.toFixed(2)}`);
console.log(`${t2.name}: ${t2.totalKills}K / ${t2.totalDeaths}D, ${t2.totalDamage} dmg, avg KD ${t2.averageKD.toFixed(2)}`);SDK: Per-player weapon stats
const stats = await client.matches.getStats('map-uuid-123');
for (const p of stats.players) {
console.log(`\n${p.name} (${p.kills}/${p.deaths}/${p.assists})`);
const weapons = (p.weaponStats ?? []).slice().sort((a, b) => b.kills - a.kills).slice(0, 5);
weapons.forEach(w => console.log(` ${w.weaponName}: ${w.kills}K, ${w.headshots} HS`));
}Errors
| HTTP | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | Invalid or missing API key. |
| 403 | FORBIDDEN | Map belongs to another organization or scope missing. |
| 404 | NOT_FOUND | Map ID not found. |
Ensure your API key has the servers:read scope for CS2 match stats.