Player stats — figures, maps, matches, team history, weapons
A player's last-12-month figures with percentiles, per-map figures, recent matches, team history and weapon profile — and what a recorded map is.
Six endpoints describe a player from completed matches: five under /players/{id} and one under
/teams/{id}. Every one identifies a player by nickname, country and role and nothing else — no
response carries a real name. {id} is the player's id or slug; a slug the player was renamed away from
still resolves, and the slug field then gives the current one.
Recorded maps and the window
The figures on /players/{id}/performance, /maps and /weapons, and the player rows of
/teams/{id}/players, cover the last 12 months, and only recorded maps. A recorded map is one
played to a result on a competitive map, in a completed Counter-Strike 2 match that was not a walkover,
where the player's line is complete and attributed to one of the two teams that played. The wording is
served on every performance response in definition, so you can quote it rather than restate it.
- Ratio of sums. A rate is the sum of its numerator over the sum of its denominator across the maps that carry its inputs, never an average of per-map figures. ADR and KAST are weighted by rounds.
nis the sample. Each figure says how many recorded maps it uses; they differ because not every map carries every input.- The 10-map floor. A figure from fewer than 10 maps is
null, and so is its percentile. Anullis an honest absence — never a zero.
KAST is a percentage here
On these endpoints kast is 0–100, like the *_pct fields on team profiles. On a player's stat line
in /matches/{id}/stats it is a 0–1 fraction. See match stats.
Figures with percentiles
GET /v1/{game}/players/{id}/performance — the ten figures in one object, each with its percentile among
every player who has a player page.
curl -H "Authorization: Bearer $ESPORTSODDS_API_KEY" \
"https://api.esportsodds.gg/v1/cs2/players/$PLAYER_ID/performance"Prop
Type
Each entry of metrics is { key, label, unit, value, n, percentile }:
key | unit | What it is |
|---|---|---|
maps | count | Recorded maps. |
matches | count | Matches those maps came from. |
kd | ratio | Kills per death. |
adr | per_round | Average damage per round. |
kast | percent | Rounds with a kill, assist, survival or trade, 0–100. |
headshot_share | percent | Headshot kills over kills. |
opening_success | percent | Opening duels won over opening duels fought. |
multikill_round_share | percent | Rounds with two or more kills over rounds played. |
clutches_per_map | per_map | Clutches per map. |
trade_kill_share | percent | Trade kills over kills. |
{
"data": {
"player_id": "019f…",
"slug": "player-a",
"nickname": "Player A",
"nationality": "FR",
"role": "Rifler",
"level": "established",
"window": { "months": 12, "through": "2026-10-10T13:45:00Z" },
"population": { "n": 1082, "level_definition": "…" },
"metrics": [
{ "key": "maps", "label": "Maps", "unit": "count", "value": 120, "n": 120, "percentile": 71.3 },
{ "key": "adr", "label": "Damage per round", "unit": "per_round", "value": 78.4, "n": 120, "percentile": 80.2 }
]
}
}(definition and the other eight metrics are left out here.)
Reading a percentile. percentile is the share of the population with a strictly lower value,
floored to one decimal place, so it runs from 0 to 99.9 and is never 100. The population is every player
who has a player page, except any whose page was removed on request; population.n is its size. It is
the API's number: read level and percentile as served, and quote definition and
population.level_definition rather than recomputing the rule. A percentile on a small n moves with
every map — read the two together.
Per-map figures
GET /v1/{game}/players/{id}/maps — one row per competitive map the player has at least one recorded map
on in the window, most played first; a map not played is absent.
Each row: map_name, active_pool (in the current Active Duty pool), maps, adr, kast, kd, and
n_adr / n_kast, the maps that carry each input. A figure is null below 10 maps on that map, so a
player with 40 recorded maps can still have null figures on a map they played five times.
Recent matches
GET /v1/{game}/players/{id}/matches — completed matches, newest first. limit default 10, max 25;
not paginated (meta.next_cursor is always null).
Each row: match_id, date, the team the player played for and the opponent, the series score from
their side (score_for, score_against, maps won), the tournament (name, tier), format, and the
player's own kills, deaths and adr over the whole match. Walkovers and matches from before
Counter-Strike 2 are left out. Where the player's line names no team, team, opponent and both scores
are null.
Team history
GET /v1/{game}/players/{id}/teams — stints, newest first. A stint is a run of consecutive matches for
one team (team, from, to, matches, maps, current), taken from the team named on the player's line
in each completed match.
A run of fewer than min_matches matches (three) is a stand-in appearance and is left out unless it is
the current one. The newest stint is current only while its last match is within 90 days of the newest
result in our data; otherwise no stint is current. Measuring against the data rather than the clock keeps
the answer stable if ingestion pauses.
Weapons and hit groups
GET /v1/{game}/players/{id}/weapons — weapon and hit-group totals over the player's matches in the window.
Weapon data is recorded per match, never per map. The eight weapons with the most kills are listed
(slug, name, class, kills, headshots, hits, shots, damage) and the rest are folded into one
other row; hit_groups lists every body part hit, most hits first (hit_group, hits, damage,
kills). matches is how many matches carry weapon data and window.through is the newest of them. A
player with none gets empty lists. Generic is damage not attributed to a body part, such as grenades or
fire.
A team's current players
GET /v1/{game}/teams/{id}/players — the players in the team's newest completed match with stats,
usually five, ordered by nickname. Each carries the figures of their own performance over the last 12
months (maps, adr, kast, kd; null below 10 maps), whether they have a player page (has_page),
and since, when their current run with the team began. as_of is that match's date; a team with no such
match returns as_of: null and no players.
It answers "who plays for them now" from who actually played, not from a signed roster; for the lineups match by match, see roster history.