Skip to main content
Base URL (local): 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.
Posting to a non-existent match currently returns 500 (foreign-key violation), not 404. Known gap, see ISSUE-004.

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.