Mint a short-lived WebSocket ticket
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.
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 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.
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
Response Body
application/json
application/json
application/json
curl -X POST "https://example.com/v1/{game}/ws-token"{ "data": { "token": "MDE4ZjJjNGEtOWIzMS03ZTAyLWE1ZDctM2MxZjg4YjQwZTE5LjE3ODMwMTUyNjAuaHFKSWtWNUJBV2xXeUdTV2xwTG14OFA3YTFtTUlEaWQtM0tscjhDWFNINA", "expires_at": "2026-07-26T09:14:20.481293Z" }}{ "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" }}Glossary
API terms defined as they are used here, with pointers to the deeper explainers.
Per-player CS2 depth breakdowns for one match GET
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}}`.