Per-player CS2 depth breakdowns for one match
The five CS2 depth breakdowns for one match, grouped into a single object: per-player `weapons`, `grenades`, `hitgroups` (body hit-group distribution), `duels` (the killer→victim kills matrix) and `flashes` (the flasher→flashed blind matrix). These are per-MATCH aggregates (not per map). Each group is a flat array whose elements carry their own `player_id` (and, for duels/flashes, the ordered pair of player ids), so a client groups by player itself. A match with no depth on record (older or lower-tier matches — roughly one in six lack it) returns every group as an empty array (never null); an unknown match id does the same. Single-resource envelope: `{"data": {weapons, grenades, hitgroups, duels, flashes}}`.
The five CS2 depth breakdowns for one match, grouped into a single object: per-player weapons, grenades, hitgroups (body hit-group distribution), duels (the killer→victim kills matrix) and flashes (the flasher→flashed blind matrix). These are per-MATCH aggregates (not per map). Each group is a flat array whose elements carry their own player_id (and, for duels/flashes, the ordered pair of player ids), so a client groups by player itself. A match with no depth on record (older or lower-tier matches — roughly one in six lack it) returns every group as an empty array (never null); an unknown match id does the same. Single-resource envelope: {"data": {weapons, grenades, hitgroups, duels, flashes}}.
Primary auth (live). Authorization: Bearer <api-key> — the header takes precedence over the query fallback. The raw key is hashed (SHA-256, hex) and looked up in api.keys.key_hash; the raw value is never stored.
In: header
Path Parameters
Game slug. cs2 is the only populated title today; an un-onboarded game 404s cleanly.
Resource identifier — either a UUID or the resource's human-readable slug, scoped to {game}. /v1/cs2/teams/natus-vincere and /v1/cs2/teams/019f23d1-fb5c-7987-b522-47c3a5e72111 address the same row, so you can go straight from a slug you already have without first looking up its id.
Slugs work on teams, players and tournaments. Matches have no slug, so a match id must be a UUID. Either way, an identifier that resolves to nothing returns 404 not_found.
Response Body
application/json
application/json
application/json
application/json
curl -X GET "https://example.com/v1/cs2/matches/019f2858-e253-7f3d-bdff-bc7738bd1036/depth"{ "data": { "weapons": [ { "id": "019f450a-0a9e-7b3a-8ebe-c49a290e643b", "match_id": "019f3d18-c15f-7319-81a7-343e8a80a578", "player_id": "019f23d2-5a33-739d-a949-76fc744d181d", "weapon_slug": "awp", "weapon_name": "AWP", "weapon_class": "Rifle", "team_side": "ct", "shots": 39, "hits": 22, "kills": 19, "headshots": 1, "damage": 1747, "wall_bangs": 1, "trade_kills": 2, "created_at": "2026-07-09T04:01:53.824101Z" }, { "id": "019f450a-0a9e-7142-ba7a-c3544e63e1cb", "match_id": "019f3d18-c15f-7319-81a7-343e8a80a578", "player_id": "019f23d2-5a33-739d-a949-76fc744d181d", "weapon_slug": "awp", "weapon_name": "AWP", "weapon_class": "Rifle", "team_side": "t", "shots": 9, "hits": 5, "kills": 5, "headshots": 0, "damage": 372, "wall_bangs": 0, "trade_kills": 3, "created_at": "2026-07-09T04:01:53.824101Z" } ], "grenades": [ { "id": "019f450a-0a9e-77a1-9352-a5d910382d83", "match_id": "019f3d18-c15f-7319-81a7-343e8a80a578", "player_id": "019f23d2-5a33-739d-a949-76fc744d181d", "grenade_name": "Flashbang", "team_side": "ct", "owns": 6, "throws": 11, "hits": 16, "kills": 0, "created_at": "2026-07-09T04:01:53.824101Z" }, { "id": "019f450a-0a9e-728a-9b05-78cf3295d687", "match_id": "019f3d18-c15f-7319-81a7-343e8a80a578", "player_id": "019f23d2-5a33-739d-a949-76fc744d181d", "grenade_name": "Flashbang", "team_side": "t", "owns": 8, "throws": 17, "hits": 28, "kills": 0, "created_at": "2026-07-09T04:01:53.824101Z" } ], "hitgroups": [ { "id": "019f450a-0a9f-7c58-9659-74a38bd9d85b", "match_id": "019f3d18-c15f-7319-81a7-343e8a80a578", "player_id": "019f23d2-5a33-739d-a949-76fc744d181d", "hit_group": "Chest", "team_side": "ct", "hits": 19, "damage": 1012, "kills": 8, "created_at": "2026-07-09T04:01:53.824101Z" }, { "id": "019f450a-0a9f-769e-a627-6e2d9442a71d", "match_id": "019f3d18-c15f-7319-81a7-343e8a80a578", "player_id": "019f23d2-5a33-739d-a949-76fc744d181d", "hit_group": "Chest", "team_side": "t", "hits": 13, "damage": 326, "kills": 4, "created_at": "2026-07-09T04:01:53.824101Z" } ], "duels": [ { "id": "019f450a-0a9f-7130-88b6-f2828cd20d97", "match_id": "019f3d18-c15f-7319-81a7-343e8a80a578", "killer_player_id": "019f23d2-5a33-739d-a949-76fc744d181d", "victim_player_id": "019f28e1-e6ae-7032-8255-4c7e26548918", "kills": 10, "weapon_names": "AWP, AWP, AK-47, AWP, AWP, AWP, AWP, AWP, AWP, M4A4", "created_at": "2026-07-09T04:01:53.824101Z" }, { "id": "019f450a-0a9f-783d-9173-79348a2bd8bf", "match_id": "019f3d18-c15f-7319-81a7-343e8a80a578", "killer_player_id": "019f23d2-5a33-739d-a949-76fc744d181d", "victim_player_id": "019f28e1-e6ae-7079-972c-1a525257604f", "kills": 9, "weapon_names": "AK-47, M4A4, Five-SeveN, AWP, AWP, AWP, AWP, AWP, AWP", "created_at": "2026-07-09T04:01:53.824101Z" } ], "flashes": [ { "id": "019f450a-0a9f-7a5b-ac6a-a1bc2f8a35f0", "match_id": "019f3d18-c15f-7319-81a7-343e8a80a578", "flasher_player_id": "019f23d2-5a33-739d-a949-76fc744d181d", "flashed_player_id": "019f28e1-e6ae-73d4-b1b1-268e210492ae", "count": 8, "duration_ns": 23032009024, "created_at": "2026-07-09T04:01:53.824101Z" }, { "id": "019f450a-0a9f-77b7-8a63-fd7fa7f0bb9f", "match_id": "019f3d18-c15f-7319-81a7-343e8a80a578", "flasher_player_id": "019f23d2-5a33-739d-a949-76fc744d181d", "flashed_player_id": "019f28e1-e6ae-7dc8-bcc1-3016328d949d", "count": 6, "duration_ns": 14770789312, "created_at": "2026-07-09T04:01:53.824101Z" } ] }}{ "error": { "code": "not_found", "message": "not found", "request_id": "019f3d18-c15f-7319-81a7-343e8a80a578" }}{ "error": { "code": "not_found", "message": "not found", "request_id": "019f3d18-c15f-7319-81a7-343e8a80a578" }}{ "error": { "code": "not_found", "message": "not found", "request_id": "019f3d18-c15f-7319-81a7-343e8a80a578" }}Mint a short-lived WebSocket ticket POST
Exchanges the caller's API key for a short-lived (60s) signed ticket used to open the WebSocket at `wss://api.esportsodds.gg/v1/ws?token=...`. Keeps the raw key off the wire and out of the browser — browsers can't set headers on a `WebSocket`, which is why tickets exist. Minting is authenticated, rate-limited and metered like any REST call. This is the only part of the WebSocket surface expressible in OpenAPI: the socket itself (`/v1/ws`) is a persistent connection with its own message protocol, so it is documented as prose instead — see **[Live data & WebSocket](/docs/live-data)** for the handshake, the message envelope, subscribing, sequence numbers, reconnection and the connection cap. Read that page before building against this endpoint; a ticket on its own does nothing.
A single match GET
One match by id, with the same fields as a list row minus the denormalised names — a detail row carries bare `team_a_id`/`team_b_id`/`tournament_id`, so resolve those separately or read them off the list route instead. The `data_available` flags tell you which sub-resources (`maps`, `stats`, `vetoes`, `rounds`, `depth`) actually exist for this match, so you can skip requests that would return an empty list.