Tracking Live Games
Game data feeds update in real time as games are played, and every UFL game carries full play-by-play coverage. This scenario follows one game from pregame preload to validated final: which feed to poll at each status, and what each payload contributes.
This scenario is commonly used to:
- Drive a live gamecast with score, clock, down-and-distance, and last play
- Stream drive-by-drive and play-by-play detail
- Show live team and player box statistics
- Capture the validated final for permanent storage
Between game days and outside the spring season, Simulations replay past UFL games as if they were live, so every step below can be exercised on demand.
Relevant Feeds
| Feed | Use |
|---|---|
| Game Boxscore | Score, clock, situation, last event, scoring drives and plays |
| Game Play-by-Play | The full drive and play tree with per-play statistics |
| Game Statistics | Team and player box statistics |
| Game Roster | Game-day availability and player game statuses |
| Current Week Schedule | Finding the games to track |
Real-time push delivery of the same game detail is available through the Push Events and Push Statistics feeds; the Push Feeds page covers the connection workflow.
High-Level Workflow
Integration Steps
1. Find the game and watch for created
createdPull the Current Week Schedule to get the game GUID and kickoff time. In the hours before kickoff the game moves to created while rosters and officials load; the Game Roster is populated at this point with every player marked dnp, adjusting to started and played at the game's conclusion. The Game Status Workflow page shows the created payload.
2. Poll the Boxscore while in play
The Boxscore is the one-call live view: status and clock, quarter-by-quarter scoring, the current situation (down, distance, possession, location), and the last_event. Mid-game it reads like this, mid-drive, first and goal moments after a 43-yard completion:
{
"id": "c5cce400-a716-49d0-bbbe-1a84fb200fa3",
"status": "inprogress",
"quarter": 3,
"clock": "9:24",
"scoring": [
{
"period_type": "quarter",
"id": "5846b0e1-3091-479f-8ff4-c04d5e8a3c9f",
"number": 1,
"sequence": 1,
"home_points": 3,
"away_points": 10
},
{
"period_type": "quarter",
"id": "00166fe0-0b42-4402-9465-ee642e8ea5b2",
"number": 2,
"sequence": 2,
"home_points": 3,
"away_points": 0
},
{
"period_type": "quarter",
"id": "c1d90be3-47c7-4388-a4c9-a264b3f145df",
"number": 3,
"sequence": 3,
"home_points": 0,
"away_points": 0
}
],
"situation": {
"clock": "9:24",
"down": 1,
"yfd": 5,
"possession": {
"id": "d4799bc0-c045-11ee-ad92-cf16c0a8aa31",
"name": "Battlehawks",
"market": "St. Louis",
"alias": "STL",
"sr_id": "sr:competitor:661855"
},
"location": {
"id": "a3407150-c045-11ee-b66f-5d382d09dbaf",
"name": "Defenders",
"market": "DC",
"alias": "DC",
"sr_id": "sr:competitor:661851",
"yardline": 5
}
},
"last_event": {
"type": "play",
"id": "36d18160-2ad0-11f1-8651-491a83d99372",
"sequence": 1774720977502,
"clock": "9:24",
"play_type": "pass",
"description": "B.Silvers pass complete. Catch made by K.Latulas for 43 yards. Tackled by DC at DC 5."
}
}The response is shown trimmed to the live-view fields. The full response also carries the game's weather node, whose optional stadium_status value reports whether a roof is open or closed; the field is omitted when it does not apply, and Game Statistics and Play-by-Play carry it the same way. The same fields persist on a finished game, where situation and last_event hold the final snap and the game-over marker. These fields drive a live score bug directly: quarter and clock from the header, the score from scoring, the down-and-distance chip from situation, and the play text from last_event; club marks are placeholders for your own or licensed assets:
3. Read scoring plays and drives
The Boxscore's scoring_plays and scoring_drives arrays summarize how points went up. Touchdown entries score 7 points when the point-after kick is good, and the entry references its point-after play; standalone conversion and extra-point plays also appear. UFL point-after attempts can be worth one, two, or three points, so read the score object rather than assuming values:
{
"id": "e23feee0-6763-11f1-9cc1-b52eac12e9e3",
"type": "play",
"play_type": "rush",
"sequence": 1781381499664.0,
"clock": "9:56",
"quarter": {
"id": "61fbfe3a-14ff-4e3b-a7cf-9dd66df39623",
"number": 2,
"sequence": 2
},
"home_points": 7,
"away_points": 9,
"description": "X.Valladay rushed right tackle for 51 yards. TOUCHDOWN.",
"scoring_description": "X.Valladay rushed right tackle for 51 yards. TOUCHDOWN.",
"score": {
"sequence": 5,
"clock": "9:45",
"points": 7,
"home_points": 7,
"away_points": 9,
"points-after-play": {
"id": "16e28310-6764-11f1-9cc1-b52eac12e9e3",
"sequence": 1781381510519.0,
"type": "extra_point"
}
}
}4. Add Play-by-Play depth
The Play-by-Play feed nests periods[] > pbp[], where each item is a drive (with events[] of plays), a standalone play (such as a no-play penalty between drives), or an event marker (TV timeouts, period boundaries). Drives carry start and end reasons, play counts, and yardage:
{
"id": "faa63c8e-fd35-496f-886e-b42787b54122",
"sequence": 10,
"start_reason": "Kickoff",
"end_reason": "Touchdown",
"play_count": 4,
"duration": "1:50",
"first_downs": 2,
"gain": 74,
"net_yards": 74,
"offensive_team": {
"id": "a3407150-c045-11ee-b66f-5d382d09dbaf"
},
"defensive_team": {
"id": "ff1f47e0-b8ef-11f0-9440-2f32b8d49d12"
},
"events": [
{
"type": "play",
"id": "e23feee0-6763-11f1-9cc1-b52eac12e9e3",
"sequence": 1781381499664.0,
"clock": "9:56",
"play_type": "rush",
"description": "X.Valladay rushed right tackle for 51 yards. TOUCHDOWN.",
"home_points": 7,
"away_points": 9
},
{
"type": "play",
"id": "16e28310-6764-11f1-9cc1-b52eac12e9e3",
"sequence": 1781381510519.0,
"clock": "9:45",
"play_type": "extra_point",
"description": "M.McCrane extra point is good.",
"home_points": 7,
"away_points": 10
}
]
}The drive is shown trimmed to its final two events; full events carry location, situation, and per-play statistics attributions.
5. Show live leaders from Game Statistics
The Game Statistics feed carries team and player box statistics organized by category, updating as plays resolve. Reading the top line of each category's players[] array yields a game leaders panel; the United Bowl's numbers, with yardage per category:
6. Wind down at complete and closed
complete and closedAt complete the game is over and scores land in the schedule feeds; at closed the stats are validated. Take one final pull of the Boxscore, Play-by-Play, and Game Statistics once the game reads closed, then stop polling: closed-game payloads move to a 600-second cache TTL, and to multi-hour once seven days pass.
Common Use Cases
- Score ticker: Boxscore only, on a short cadence
- Gamecast: Boxscore for state plus Play-by-Play for the play stream
- Live player stats: Game Statistics alongside the Boxscore
- Post-game recap: one
closedpull of all four game feeds
Best Practices
- Branch on
statusat every poll:halftimeis a normal mid-game status,delayedandsuspendedmean pause but keep watching, and onlyclosed(orcancelled) ends the loop - Poll the Boxscore as your heartbeat and fetch Play-by-Play on a slower cadence or on score change; the Update Frequencies page carries cadence guidance
- Ingest play-by-play idempotently by event
idandsequence; entries can be corrected while a game is live - Treat
complete-state stats as provisional and re-ingest atclosed
Updated about 2 hours ago
