Skip to content

Where to join a match broadcast

GET
/api/matches/{id}/resume
curl --request GET \
--url https://foxleague.ai/api/matches/1/resume

Where 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 to seek_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.
id
required
integer format: int32

The match id.

Success or a refusal: read success (the refusals are in the description).

Media type application/json
object
code

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.

string | null
data

The answer. Present when success is true.

object
away_score

Away goals; null until the result is public.

integer | null format: int32
away_team_name
required

Away team name.

string
cycle_rate
required

Cycles per second of the recording: 10.

number format: double
elapsed_seconds
required

Seconds since playback started; 0 before it.

number format: double
home_score

Home goals; null until the result is public.

integer | null format: int32
home_team_name
required

Home team name.

string
match_id
required

The match id.

integer format: int32
match_type
required

casual, ranked or tournament.

string
phase
required

pre_game, playing, finished or error (see the description).

string
playback_speed_multiplier
required

The viewer’s default playback speed, from 0.5 to 3.0; 1.0 is real time.

number format: double
playback_started_at

When playback started (RFC 3339); null before it.

string | null
seek_cycle
required

The cycle to seek the viewer to.

integer format: int32
status
required

The match’s status; anyone but the two players reads live (or error) for a ranked or casual match whose result is not applied.

string
tm_game_id

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.

integer | null format: int64
total_cycles
required

Cycles in the recording; 6000 when unknown.

integer format: int32
error

Why the request was refused, in plain words. Present when success is false.

string | null
success
required

true when the request did what it asked. false is a refusal: read error.

boolean
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.

Media type text/plain
string
Example
Session expired or invalid