Tracking Live Games
Game data feeds update in real time as games are played, and every NFL game carries full play-by-play coverage. This scenario follows one game from the schedule pull to the validated final: which feed to poll at each status, what each payload contributes, and how to pick up the corrections that land after a game ends.
This scenario is commonly used to:
- Drive a live gamecast with score, clock, down-and-distance, and the last play
- Stream drive-by-drive and play-by-play detail, with possession and ball location on every play
- Show live team and player box statistics and game leaders
- Feed fantasy, analytics, broadcast, and editorial products with per-play statistics
- Capture the validated final for permanent storage
Relevant Feeds
| Feed | Scope | Use |
|---|---|---|
| Weekly Schedule | season year, type, and week, or current_week | Finding the game ID and kickoff time |
| Game Boxscore | game ID | Score, clock, situation, last event, scoring plays and drives |
| Game Play-by-Play | game ID | The full drive and play tree with possession, location, and per-play statistics |
| Game Statistics | game ID | Team and player box statistics |
Real-time push delivery of the same play and statistics detail is available through the Push Events and Push Statistics feeds; step 6 covers how they pair with the REST feeds, and the Push Feeds page covers the connection workflow. Corrections that land after a game ends surface in the Daily Change Log; step 7 covers what to refetch.
High-Level Workflow
Integration Steps
1. Find the game and watch for created
createdGame IDs come from the schedule feeds; any of the four returns them:
The Seasons feed lists every season on file; check it before requesting a season that has not started (a schedule ahead of a season, for example) to confirm that season's data is already provided, which prevents unnecessary errors. Schedule feeds need calling only once or twice a day to stay current, with the Daily Change Log picking up scheduling changes in between (see Monitoring Data Changes). Keep them for schedule retrieval rather than live state: they carry each game's status (scheduled, inprogress, complete, closed), but the schedule status updates on a timer, so the game feeds below report status changes first.
One week of the season, trimmed to a single game's header, teams, broadcast, and score. The game id is the key for every game feed below, and scheduled is the kickoff time in UTC:
GET https://api.sportradar.com/nfl/official/trial/v7/en/games/2025/REG/2/schedule.json
x-api-key: YOUR_API_KEY{
"id": "fbe26310-feb8-11ef-a86e-d5de4289b45b",
"year": 2025,
"type": "REG",
"name": "REG",
"week": {
"id": "efb8dd84-bdba-4136-b518-7159a02ff8db",
"sequence": 2,
"title": "2",
"games": [
{
"id": "b0563750-d49e-4362-b862-8439170dd4b7",
"status": "closed",
"scheduled": "2025-09-12T00:15:00+00:00",
"attendance": 77289,
"entry_mode": "LDE",
"sr_id": "sr:match:60574797",
"game_type": "regular",
"conference_game": true,
"title": "Thursday Night Football",
"duration": "3:12",
"home": {
"id": "a20471b4-a8d9-40c7-95ad-90cc30e46932",
"name": "Green Bay Packers",
"alias": "GB",
"game_number": 2,
"sr_id": "sr:competitor:4420"
},
"away": {
"id": "22052ff7-c065-42ee-bc8f-c4691c50e624",
"name": "Washington Commanders",
"alias": "WAS",
"game_number": 2,
"sr_id": "sr:competitor:4432"
},
"broadcast": {
"network": "Amazon Prime Video"
},
"scoring": {
"home_points": 27,
"away_points": 18
}
}
]
}
}The current_week path convention returns the same payload for the ongoing week without the season year and type in the request, which also confirms which week and season type is in progress when you are unsure: https://api.sportradar.com/nfl/official/{access_level}/v7/{language_code}/games/current_week/schedule.{format}. The current_season path does the same for the full season. Both are for schedule retrieval, not live updates, so the query never needs manual changes as the season progresses.
In the days before kickoff the game moves to created: rosters, officials, and game data preload, and the Game Roster populates. Start requests to the game feeds no earlier than 10 minutes before the scheduled time; the coin toss sets inprogress. The Game Status Workflow page shows every status and the payload at each stage.
2. Poll the Game Boxscore while in play
The Game Boxscore is the one-call live view: status, quarter, and clock in the header, both teams' points, timeouts, and challenges under summary, quarter-by-quarter scoring, the current situation (down, distance, possession, and ball location), and the last_event. It is also the scoring feed. Play-by-Play and Push Events carry the score on every play, but the Boxscore adds per-team scoring detail complete with play-by-play breakdowns of every scoring drive (scoring_drives) and each scoring play (scoring_plays, step 3).
- Request the feed no sooner than 10 minutes before the scheduled start (status
scheduled), based on your needs - Once the game is
inprogress, query as needed; the feed refreshes on a 3-second TTL while the game is in progress - After the game has ended, the Daily Change Log captures later data changes (step 7)
The header from Super Bowl LX after closed, trimmed to its scalar fields (a live pull adds summary, situation, last_event, and the scoring arrays around it). Quarter and clock feed a score bug's header, summary its score, situation the down-and-distance chip, and last_event the play text:
GET https://api.sportradar.com/nfl/official/trial/v7/en/games/7391a8d0-6675-4305-92fc-dc65bb4dcd38/boxscore.json
x-api-key: YOUR_API_KEY{
"id": "7391a8d0-6675-4305-92fc-dc65bb4dcd38",
"status": "closed",
"scheduled": "2026-02-08T23:30:00+00:00",
"attendance": 70823,
"entry_mode": "LDE",
"clock": "00:00",
"quarter": 4,
"sr_id": "sr:match:67426020",
"neutral_site": true,
"game_type": "playoff",
"conference_game": false,
"title": "Super Bowl LX",
"duration": "3:42",
"parent_id": "f6c2b12d-966c-41a5-98a7-054620fba38b"
}
Game Status WorkflowsFor more on what feeds look like throughout the duration of a game, see the Game Status Workflow page.
3. Read scoring plays and drives
scoring_plays lists every scoring play with its clock, the running score for both teams, and a description; the scoring_play: true flag distinguishes these entries wherever plays appear. Each entry carries the start and end situation, a score object with the points on the play and the totals after it, the per-play statistics, and the quarter. Here, from the same Boxscore response, J.Myers' 33-yard field goal at 12:02 of the first quarter, the finish of the opening drive shown in step 4, putting the away side up 3-0. The entry is trimmed to its situations, score, and kicking statistic; the full entry also carries details (the snap and hold roles) and the formation flags:
{
"id": "7391a8d0-6675-4305-92fc-dc65bb4dcd38",
"status": "closed",
"clock": "00:00",
"quarter": 4,
"scoring_plays": [
{
"type": "play",
"id": "2c92fa10-0548-11f1-9f1d-d1fc4599995e",
"sequence": 1770594344886.0,
"clock": "12:02",
"home_points": 0,
"away_points": 3,
"play_type": "field_goal",
"scoring_play": true,
"wall_clock": "2026-02-08T23:45:32+00:00",
"description": "J.Myers 33 yard field goal attempt is good, Center-C.Stoll, Holder-M.Dickson.",
"scoring_description": "J.Myers 33 yard field goal attempt is good, Center-C.Stoll, Holder-M.Dickson.",
"created_at": "2026-02-08T23:45:44+00:00",
"updated_at": "2026-06-05T19:55:06+00:00",
"official": true,
"start_situation": {
"clock": "12:02",
"down": 4,
"yfd": 7,
"possession": {
"id": "3d08af9e-c767-4f88-a7dc-b920c6d2b4a8",
"name": "Seahawks",
"market": "Seattle",
"alias": "SEA",
"sr_id": "sr:competitor:4430"
},
"location": {
"id": "97354895-8c77-4fd4-a860-32e62ea7382a",
"name": "Patriots",
"market": "New England",
"alias": "NE",
"sr_id": "sr:competitor:4424",
"yardline": 14
}
},
"end_situation": {
"clock": "11:58",
"down": 0,
"yfd": 0,
"possession": {
"id": "3d08af9e-c767-4f88-a7dc-b920c6d2b4a8",
"name": "Seahawks",
"market": "Seattle",
"alias": "SEA",
"sr_id": "sr:competitor:4430"
},
"location": {
"id": "3d08af9e-c767-4f88-a7dc-b920c6d2b4a8",
"name": "Seahawks",
"market": "Seattle",
"alias": "SEA",
"sr_id": "sr:competitor:4430",
"yardline": 35
}
},
"score": {
"sequence": 1,
"clock": "11:58",
"points": 3,
"home_points": 0,
"away_points": 3
},
"statistics": [
{
"stat_type": "field_goal",
"attempt": 1,
"att_yards": 33,
"yards": 33,
"missed": 0,
"made": 1,
"player": {
"id": "7af4c94b-529b-4403-ab66-2bfed3fcf0c7",
"name": "Jason Myers",
"jersey": "05",
"position": "K",
"sr_id": "sr:player:855698"
},
"team": {
"id": "3d08af9e-c767-4f88-a7dc-b920c6d2b4a8",
"name": "Seahawks",
"market": "Seattle",
"alias": "SEA",
"sr_id": "sr:competitor:4430"
}
}
],
"quarter": {
"id": "e75874a1-40e8-45cf-900f-a756630ef3ae",
"number": 1,
"sequence": 1
}
}
]
}scoring_drives summarizes the same points at drive level, each drive with its start and end reasons, play count, duration, and yardage plus the plays that made it up. A final summary panel built from these feeds: the score from the game header and the passing leaders from Game Statistics (step 5). The headshot slots are placeholders:
Accessing Headshots and Team LogosTo access team logos and player headshots, use the Images API.
4. Add Play-by-Play depth
The Game Play-by-Play feed is the live timeline: a detailed, sequential account of every play and event in the game, with possession and ball location and all team and player statistics earned on each play. It nests periods[] > pbp[], where each item is a drive (with events[] of plays) or a standalone event such as a TV timeout. Drives carry start and end reasons, play counts, duration, first downs, yardage, and the scoring_drive and inside_20 flags. Because every play carries its own statistics, per-quarter and per-half player totals are built here by summing the plays within a period, while Game Statistics carries whole-game totals.
- Request the feed no sooner than 10 minutes before the scheduled start (status
scheduled), based on your needs - Once the game is
inprogress, query as needed; the feed refreshes on a 3-second TTL while the game is in progress - After the game has ended, the Daily Change Log captures later data changes (step 7)
Plays are entered in layers. The initial play result (play type, yardage, down and distance, and the primary ball carrier, passer, or target) typically lands 5 to 10 seconds behind the broadcast. Role detail such as tacklers, assists, quarterback hits, and pass deflections follows as an update to the same play shortly afterward, and complex plays (piles, penalties, reviews) can take longer to settle. Treat each play-by-play event as updatable in place, keyed by its id, rather than append-only.
The opening drive of Super Bowl LX, trimmed to its first two plays, each with its situations (possession and location reduced to the alias and yard line) and its primary statistic; the full payload adds the formation and personnel flags on each play, the return, defense, and first_down attributions, and a details[] breakdown of every play. A.Borregales' kickoff travels 65 yards from the NE 35 for a touchback, Seattle takes over at its 35, and K.Walker's 10-yard rush to the SEA 45 opens a drive that runs 8 plays and 51 yards over 3:02 and ends in the field goal shown in step 3. Each play carries its own description, situations, and statistics, which is what suits the feed to in-depth game analysis and stat tracking; the updated_at timestamps show both plays revised after the game, another reason to upsert by id:
GET https://api.sportradar.com/nfl/official/trial/v7/en/games/7391a8d0-6675-4305-92fc-dc65bb4dcd38/pbp.json
x-api-key: YOUR_API_KEY{
"id": "7391a8d0-6675-4305-92fc-dc65bb4dcd38",
"status": "closed",
"clock": "00:00",
"quarter": 4,
"title": "Super Bowl LX",
"periods": [
{
"period_type": "quarter",
"id": "e75874a1-40e8-45cf-900f-a756630ef3ae",
"number": 1,
"sequence": 1,
"pbp": [
{
"type": "drive",
"id": "4dc78a01-69a5-4982-af33-9fcf33fc6dd5",
"sequence": 1,
"start_reason": "Kickoff",
"end_reason": "Field Goal",
"play_count": 8,
"duration": "3:02",
"first_downs": 3,
"gain": 51,
"penalty_yards": 0,
"inside_20": true,
"scoring_drive": true,
"created_at": "2026-02-08T23:40:35+00:00",
"updated_at": "2026-02-08T23:45:52+00:00",
"team_sequence": 1,
"start_clock": "15:00",
"end_clock": "11:58",
"first_drive_yardline": 65,
"last_drive_yardline": 14,
"farthest_drive_yardline": 14,
"net_yards": 51,
"pat_points_attempted": 0,
"events": [
{
"type": "play",
"id": "ffb8a4a0-0541-11f1-9f1d-d1fc4599995e",
"sequence": 1770594034780.0,
"clock": "15:00",
"home_points": 0,
"away_points": 0,
"play_type": "kickoff",
"wall_clock": "2026-02-08T23:40:24+00:00",
"description": "A.Borregales kicks 65 yards from NE 35 to the SEA End Zone. Touchback.",
"created_at": "2026-02-08T23:40:34+00:00",
"updated_at": "2026-02-09T15:31:40+00:00",
"official": true,
"start_situation": {
"clock": "15:00",
"down": 0,
"yfd": 0,
"possession": {
"alias": "NE"
},
"location": {
"alias": "NE",
"yardline": 35
}
},
"end_situation": {
"clock": "15:00",
"down": 1,
"yfd": 10,
"possession": {
"alias": "SEA"
},
"location": {
"alias": "SEA",
"yardline": 35
}
},
"statistics": [
{
"stat_type": "kick",
"attempt": 1,
"yards": 65,
"net_yards": 30,
"touchback": 1,
"onside_attempt": 0,
"onside_success": 0,
"squib_kick": 0,
"player": {
"id": "80dce1ba-c997-47e6-a37e-e92fefcbdc1b",
"name": "Andy Borregales",
"jersey": "36",
"position": "K",
"sr_id": "sr:player:2158118"
},
"team": {
"id": "97354895-8c77-4fd4-a860-32e62ea7382a",
"alias": "NE"
}
}
]
},
{
"type": "play",
"id": "8e7a6980-0547-11f1-9f1d-d1fc4599995e",
"sequence": 1770594084043.0,
"clock": "15:00",
"home_points": 0,
"away_points": 0,
"play_type": "rush",
"wall_clock": "2026-02-08T23:41:08+00:00",
"description": "K.Walker rushed left end for 10 yards. Pushed out of bounds by C.Davis at SEA 45.",
"created_at": "2026-02-08T23:41:24+00:00",
"updated_at": "2026-06-05T19:55:04+00:00",
"official": true,
"start_situation": {
"clock": "15:00",
"down": 1,
"yfd": 10,
"possession": {
"alias": "SEA"
},
"location": {
"alias": "SEA",
"yardline": 35
}
},
"end_situation": {
"clock": "14:29",
"down": 1,
"yfd": 10,
"possession": {
"alias": "SEA"
},
"location": {
"alias": "SEA",
"yardline": 45
}
},
"statistics": [
{
"stat_type": "rush",
"attempt": 1,
"yards": 10,
"firstdown": 1,
"inside_20": 0,
"goaltogo": 0,
"broken_tackles": 0,
"kneel_down": 0,
"scramble": 0,
"yards_after_contact": 2,
"player": {
"id": "22ee9bac-a64c-4d44-94fc-51d775465b3b",
"name": "Kenneth Walker III",
"jersey": "09",
"position": "RB",
"sr_id": "sr:player:1692489"
},
"team": {
"id": "3d08af9e-c767-4f88-a7dc-b920c6d2b4a8",
"alias": "SEA"
}
}
]
}
]
}
]
}
]
}A drive log renders straight from a drive and its events. This one is the game's first touchdown drive, 5 plays and 37 yards after a fumble recovery with ten seconds left in the third quarter, opening with S.Darnold's 11-yard completion to A.Barner:
Every play's situations carry location as a team alias plus a yard line; plot one drive's values and they read straight onto the field:
The conversion runs off which half of the field the alias names: with Seattle in possession, NE 22 is 22 yards from the end zone (the opponent's side, so the yard line is the distance), while SEA 9 is 91 yards out (their own side, so subtract the yard line from 100).
Fantasy and analytics products read the per-play statistics directly: the 65-yard kickoff and its touchback under the kick statistic, the drive's duration of 3:02 and gain of 51 yards, or K.Walker's 2 yards_after_contact on the opening rush. This detail is what informs decisions in fantasy leagues and explains game dynamics and player performance.
5. Show live leaders from Game Statistics
The Game Statistics feed carries comprehensive game-level statistics: team and player performance metrics for each team, organized by category, updating as plays resolve. Each team's summary sits alongside the category blocks (rushing, passing, receiving, defense, and the rest), and the per-player lines within a category hold the detailed metrics, such as attempts, average yards per attempt, touchdowns, and total yards for rushing; in defense, total tackles are tackles plus assists, which the combined field also carries. The game header also carries the 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 the Boxscore and Play-by-Play feeds carry it the same way.
- Request the feed no sooner than 10 minutes before the scheduled start (status
scheduled), based on your needs - Once the game is
inprogress, query as needed; the feed refreshes on a 3-second TTL while the game is in progress - After the game has ended, the Daily Change Log captures later data changes (step 7)
The home side of Super Bowl LX, trimmed to the Patriots' summary block: 26:49 of possession, an average gain of 4.9 yards, 3 turnovers (one of them a lost fumble), 67 plays including 18 rushes, 331 total yards, and 3 penalties for 25 yards. These figures show the effectiveness of a team's offensive strategy and player performance during the game:
GET https://api.sportradar.com/nfl/official/trial/v7/en/games/7391a8d0-6675-4305-92fc-dc65bb4dcd38/statistics.json
x-api-key: YOUR_API_KEY{
"id": "7391a8d0-6675-4305-92fc-dc65bb4dcd38",
"status": "closed",
"scheduled": "2026-02-08T23:30:00+00:00",
"attendance": 70823,
"entry_mode": "LDE",
"clock": "00:00",
"quarter": 4,
"sr_id": "sr:match:67426020",
"neutral_site": true,
"game_type": "playoff",
"conference_game": false,
"title": "Super Bowl LX",
"duration": "3:42",
"parent_id": "f6c2b12d-966c-41a5-98a7-054620fba38b",
"statistics": {
"home": {
"id": "97354895-8c77-4fd4-a860-32e62ea7382a",
"name": "Patriots",
"market": "New England",
"alias": "NE",
"sr_id": "sr:competitor:4424",
"summary": {
"possession_time": "26:49",
"avg_gain": 4.9,
"safeties": 0,
"turnovers": 3,
"play_count": 67,
"rush_plays": 18,
"total_yards": 331,
"fumbles": 1,
"lost_fumbles": 1,
"penalties": 3,
"penalty_yards": 25,
"return_yards": 4
}
}
}
}Key team statistics render side by side from both teams' blocks (passing and rushing yards, turnovers, first downs, and time of possession), which conveys the effectiveness of team strategies and player performances at a glance:
For play-related statistics that sit outside the box score, such as attempted field goals, out-of-bounds fumbles, and passes inside the 20-yard line, supplement Game Statistics (or Push Statistics) with the Game Play-by-Play feed.
Play-by-Play versus Game StatisticsCompare the data points returned by the Game Play-by-Play feed with those from the Game Statistics or Push Statistics feed to understand the specific information each provides.
6. Stream plays and statistics over Push
The Push Events feed delivers live play-by-play data with a single API call, and the Push Statistics feed streams the same live stat data as Game Statistics the same way; both optimize real-time updates and reduce the number of calls required. The push feeds are available to Realtime customers. To combine them with the REST feeds:
- Open a connection with a single call to the push feed to receive real-time updates.
- Push feeds deliver JSON payloads through a push service, minimizing the number of calls required.
- Supplement with the RESTful Game Play-by-Play and Game Statistics feeds to obtain detailed statistics and comprehensive game data when needed.
Push Events:
GET https://api.sportradar.com/nfl/official/trial/stream/en/events/subscribe
x-api-key: YOUR_API_KEYPush Statistics:
GET https://api.sportradar.com/nfl/official/trial/stream/en/statistics/subscribe
x-api-key: YOUR_API_KEY- Add the
matchparameter with the specific gameidto follow one game. The parameter is optional: without it, the feed returns data for all games currently in progress. - Push Events lacks the detailed boxscore information and broader statistics found in the Play-by-Play feed, and certain statistics are only available through the RESTful API, so do not use a push feed exclusively; keep Game Play-by-Play or Game Statistics alongside it for comprehensive coverage.
- After a disconnection it is not possible to resume where you left off. For continuous coverage, open multiple push connections and keep the RESTful feeds as the fallback to retrieve any missed timeline information during live games.
Play-by-Play versus Push EventsCompare the data points returned by the Game Play-by-Play feed with those from the Push Events feed to understand the specific information each provides.
In a live sports tracking app, the Push Events feed carries the real-time notifications of major events like touchdowns and penalties, while a user-requested feature that shows a detailed timeline of each drive, including minor plays and player statistics, reads the Game Play-by-Play feed for the game details the push notifications leave out. The app delivers both quick updates and in-depth game analysis.
Open Simultaneous Push ConnectionsOpening multiple connections to the push events feed boosts your application's reliability and flexibility. It enables simultaneous monitoring of various games or data types and ensures continuous data flow, even if one connection fails. This method also enhances scalability and data management, vital for applications needing real-time updates.
7. Wind down at complete and closed
complete and closedAt complete the game is over and the score is correct while the remaining statistics enter post-game verification, which typically takes about one hour; at closed all 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 4 hours once seven days pass.
Adjustments can still land after closed. The Daily Change Log tracks them without depleting your API call limits: game results and statistics revisions for recent games, player updates such as name or number changes, team modifications, and schedule adjustments. For this scenario, refetch the game feeds for any game the log lists and refresh the player and team records it names; set a regular schedule to pull the log every 10 minutes or less, depending on your use case. The Monitoring Data Changes page is the home for the feed's mechanics and update frequency, including the scenario table for applications that offer live game updates.
Common Use Cases
- Score ticker: Boxscore only, on a short cadence
- Gamecast: Boxscore for state plus Play-by-Play for the drive and play stream
- Live player stats: Game Statistics alongside the Boxscore, or Push Statistics with Game Statistics as the backup
- Fantasy and analytics: per-play statistics from Play-by-Play, such as kick distances, drive durations, and yards after contact
- Broadcast and editorial: the scoring-play breakdown of the key plays that influenced the game's outcome (plays under pressure, quarterback decision-making, defensive responses) to enrich the narrative of a game's pivotal moments
- Coaching and team evaluation: Game Statistics for rushing effectiveness, turnover margins, and penalty impacts on outcomes, informing player rotations, game strategy, training focus, and preparation for upcoming opponents
- Post-game recap: one
closedpull of the game feeds
Best Practices
- Branch on
statusat every poll:halftimeis a normal mid-game status, asuspendedgame returns toinprogresswhen play resumes, apostponedgame reappears as a newscheduledgame, and onlyclosed(orcancelled) ends the loop - Start game-feed requests no earlier than 10 minutes before the scheduled start, and read live status from the game feeds rather than the schedule feeds
- Poll the Boxscore as your heartbeat and fetch Play-by-Play on a slower cadence or on score change
- Ingest play-by-play idempotently by event
idandsequence; plays land in layers and can be corrected while a game is live and again afterclosed - Keep the REST feeds as the fallback for every push connection; a dropped stream cannot be resumed
- Treat
complete-state stats as provisional, re-ingest atclosed, and follow the Daily Change Log afterward - The Update Frequencies page carries the TTL tiers and cadence guidance for every game feed
Updated about 5 hours ago
