Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.ticktock.bet/llms.txt

Use this file to discover all available pages before exploring further.

OpenAPI doesn’t describe WebSocket endpoints — this page is the contract.

Endpoints

wss://ticktock.bet/cs2/v1/stream?api_key=<key>           # all matches
wss://ticktock.bet/cs2/v1/stream/{match_id}?api_key=<key> # one match
Browsers can’t set custom headers on the WS upgrade, so the key rides as a query parameter.

Auth and scope filtering

The handshake validates api_key. After upgrade, the server pushes only the message types your key’s scopes allow:
Frame typeRequired scope
match.created, match.updated, match.finishedcs2:stream:matches
round.started, round.finishedcs2:stream:matches
event.kill, event.bomb_planted, event.bomb_defused, event.bomb_explodedcs2:stream:matches
market.created, market.updated, market.suspended, market.unsuspendedcs2:stream:markets
bet_settlementcs2:stream:markets
scoreboard.framecs2:stream:scoreboard
Frames you aren’t entitled to are silently dropped — no 403 per-frame, no errors. Use /v1/whoami to confirm your stream scopes before debugging missing frames.

Frame envelope

{
  "type": "match.updated",
  "data": { "id": "…", "status": "live", "score_a": 8, "score_b": 5,  },
  "meta": { "ts": "2026-05-10T13:42:11.123Z", "seq": 481234 }
}
data is the same shape (and same scope-filtered field set) as the matching REST endpoint — match.updated mirrors GET /cs2/v1/matches/{id}, bet_settlement mirrors a settlement entry, etc.

Snapshot semantics

On connect the server sends a snapshot of currently-relevant state (live matches, active markets) before switching to incremental frames. After that it polls and emits a frame only when the underlying state actually changes — no constant chatter.
ChannelDefault poll cadence
/cs2/v1/stream (list)5s
/cs2/v1/stream/{match_id} (detail)2s
Frames carry a content-hash; if nothing changed in the polling tick, nothing is pushed.

Frame format

WebSocket frames are JSON only. The REST surface offers XML for the seven feed endpoints (see Content negotiation); the WS channel does not — frames are always JSON regardless of the Accept header on the upgrade. Clients that need XML for their archival pipeline can hit the matching REST endpoint with Accept: application/xml after each interesting frame.

Keep-alive

The server sends an alive envelope every 10s — same shape as REST /v1/alive. If you don’t see one for ~30s, reconnect.

Reconnect strategy

  • Reconnect with exponential backoff (start 1s, cap at 30s).
  • After reconnect, kick off a stateful recovery replay — the AMQP path republishes the current market state plus settlements/voids since your last processed timestamp and terminates with <snapshot_complete>.
  • Unique-ish frame ids live in meta.seq — use it to dedupe across reconnects.

Example session

wscat -c "wss://ticktock.bet/cs2/v1/stream?api_key=ttk_live_…"
< { "type": "match.updated", "data": { "id": "…", "score_a": 8, }, "meta": {...} }
< { "type": "market.updated", "data": { "id": "…", "odds": [...], "status": 1 }, "meta": {...} }
< { "type": "round.finished", "data": { "match_id": "…", "round_number": 14, "winner_side": "CT" }, "meta": {...} }
< { "type": "bet_settlement", "data": { "id": "…", "match_id": "…", "result": "won" }, "meta": {...} }
Last modified on May 12, 2026