http://localhost:8000 · WebSocket: ws://localhost:8000/ws
REST
GET /matches
Returns matches, most-recent first.
Query: limit (1–100, default 50). No offset/cursor: the endpoint only ever returns the most-recent window (the frontend fetches limit=100 and paginates client-side). Paging past the top 100 would require cursor pagination, see Frontend. Not built.
POST /matches
Creates a match. status is derived from startTime/endTime, not supplied. Broadcasts match_created to all WS clients.
Body: sport, homeTeam, awayTeam, startTime (ISO), endTime (ISO, must be after startTime); optional homeScore, awayScore (default 0). → 201 { data }, or 400 on invalid input.
PATCH /matches/:id/score
Sets a match’s live score and broadcasts score_update to all WS clients (scores show on every client’s grid card, so it’s global, not room-scoped).
Body: required homeScore, awayScore (non-negative ints). → 200 { data } (the updated match), 400 on invalid id/body, 404 if the match doesn’t exist.
GET /matches/:id/commentary
Returns a match’s commentary, most-recent first. Query: limit (1–100). → 200 { data }, 400 on bad id/query.
POST /matches/:id/commentary
Inserts a commentary event, broadcasts commentary to subscribers of that match.
Body: required sequence (positive int), eventType, message; optional minute, period, actor, team, tags, metadata. → 201 { data }, 400 on invalid input.
WebSocket protocol
Connect to/ws. Full walkthrough in Real-Time Deep Dive.
This is hand-written from the route code. A future improvement is generating an OpenAPI spec from the existing Zod schemas (
zod-to-openapi), making the validation rules the single source of truth for these docs and enabling an interactive playground.