Where to join a match broadcast
const url = 'https://foxleague.ai/api/matches/1/resume';const options = {method: 'GET'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url https://foxleague.ai/api/matches/1/resumeWhere a viewer should join a match’s broadcast: the phase, the cycle to seek to and the timing to keep in step. The recording runs at 10 cycles per second.
pre_game: playback has not started; watch from the start.playing: playback is running; seek toseek_cycle.finished: the match is over and its result is public.error: the match could not be played.
A ranked or casual match whose result is not applied never reads finished: once its broadcast time has run out it reads playing at the last cycle, so the viewer ends it and reports playback-done. A tournament or challenge match answers Match not found like an unknown id, before and after its broadcast.
Who: anyone, with more for a session. For a ranked or casual match whose result is not applied, anyone but its two players reads phase: "pre_game" ("error" for a failed match), status: "live" (or "error"), tm_game_id null and the standard length of 6000 cycles. A session header that is present but invalid answers 401.
Refusals:
Match not found: no such match; a tournament or challenge match.
Authorizations
Section titled “Authorizations ”- None
- session
Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters ”The match id.
Responses
Section titled “ Responses ”Success or a refusal: read success (the refusals are in the description).
object
A machine-readable reason next to error, set only where the caller must act differently. tx_pending: the payment was not refused but could not be verified yet; keep the transaction hash and confirm again with the same hash, never pay twice.
The answer. Present when success is true.
object
Away goals; null until the result is public.
Away team name.
Cycles per second of the recording: 10.
Seconds since playback started; 0 before it.
Home goals; null until the result is public.
Home team name.
The match id.
casual, ranked or tournament.
pre_game, playing, finished or error (see the description).
The viewer’s default playback speed, from 0.5 to 3.0; 1.0 is real time.
When playback started (RFC 3339); null before it.
The cycle to seek the viewer to.
The match’s status; anyone but the two players reads live (or error) for a ranked or casual match whose result is not applied.
The match server’s game id; null without a recording and for anyone but the two players while a ranked or casual match’s result is not applied.
Cycles in the recording; 6000 when unknown.
Why the request was refused, in plain words. Present when success is false.
true when the request did what it asked. false is a refusal: read error.
Example
{ "data": { "away_score": null, "away_team_name": "Night Owls", "cycle_rate": 10, "elapsed_seconds": 214.3, "home_score": null, "home_team_name": "Red Foxes", "match_id": 5123, "match_type": "ranked", "phase": "playing", "playback_speed_multiplier": 1, "playback_started_at": "2026-10-01T09:15:02+00:00", "seek_cycle": 2140, "status": "finished", "tm_game_id": 90412, "total_cycles": 6000 }, "success": true}No valid session. The body is plain text: Missing Authorization header, Invalid Authorization format, Invalid session token or Session expired or invalid. Sign in again.
Example
Session expired or invalid