Monitoring Data Changes
The Daily Change Log lists the IDs and last_modified timestamps of everything modified on a given league day: schedule adjustments, game results and statistics, player updates (such as name or number changes), team modifications, and standings, plus any games removed from coverage. A request for one date returns that day's entries grouped by entity type, and the IDs point at the feeds to refetch. It turns "re-pull everything nightly" into "refetch only what changed", which keeps your call volume low, and it is the recovery tool after downtime.
This scenario is commonly used to:
- Keep a local store of players, results, schedules, and standings synchronized with targeted refetches
- Catch post-game corrections and statistical revisions to games that have already closed
- Detect roster, transaction, injury, and profile edits without polling every profile
- Recover cleanly after an outage by walking the missed days
Relevant Feeds
| Feed | Scope | Use |
|---|---|---|
| Daily Change Log | {year}/{month}/{day} | What changed that league day |
| Daily Transactions | {year}/{month}/{day} | The player-movement detail behind roster changes |
| Season Schedule | year + season type | The deleted_games reconciliation list |
High-Level Workflow
Integration Steps
1. Pull the league day
The date trio addresses one league-defined day, midnight to midnight US Eastern time, expressed in UTC in the response's start_time and end_time: 04:00:00Z to 03:59:59Z while daylight saving time is in effect (as below) and 05:00:00Z to 04:59:59Z in standard time. Entries populate live as changes are made, so a request during the day returns what has changed so far.
GET https://api.sportradar.com/nfl/official/trial/v7/en/league/2026/09/02/changes.json
x-api-key: YOUR_API_KEY{
"league": {
"id": "3c6d318a-6164-4290-9bbc-bf9bb21cc4b8",
"name": "National Football League",
"alias": "NFL"
},
"start_time": "2026-09-02T04:00:00Z",
"end_time": "2026-09-03T03:59:59Z",
"players": [
{
"id": "008e8d70-42a7-11f1-8ff8-33ecf41a6316",
"full_name": "Wesley Bailey",
"last_modified": "2026-09-02T04:21:47+00:00",
"sr_id": "sr:player:2001729"
},
{
"id": "00ba8fa0-93ee-4e40-823a-d03a2639fce1",
"full_name": "Jack Heflin",
"last_modified": "2026-09-02T16:25:02+00:00",
"sr_id": "sr:player:2197662"
}
],
"results": [
{
"id": "0b647d69-be2b-4687-9d30-57914a08ede5",
"season_id": "c0650ee0-17f9-11f1-92c4-398db1c54270",
"last_modified": "2026-09-03T02:21:40+00:00",
"sr_id": "sr:match:71548164"
},
{
"id": "0b9cc807-288a-4a08-b2c9-c439ad936ed7",
"season_id": "c0650ee0-17f9-11f1-92c4-398db1c54270",
"last_modified": "2026-09-03T02:31:07+00:00",
"sr_id": "sr:match:71548174"
}
]
}<?xml version="1.0" ?>
<!-- Generation started @ 2026-09-03 03:36:00 +0000 -->
<league xmlns="http://feed.elasticstats.com/schema/football/changelog-v7.0.xsd" id="3c6d318a-6164-4290-9bbc-bf9bb21cc4b8" name="National Football League" alias="NFL">
<changelog start_time="2026-09-02T04:00:00Z" end_time="2026-09-03T03:59:59Z">
<profiles>
<players>
<player id="008e8d70-42a7-11f1-8ff8-33ecf41a6316" full_name="Wesley Bailey" last_modified="2026-09-02T04:21:47+00:00" sr_id="sr:player:2001729"/>
<player id="00ba8fa0-93ee-4e40-823a-d03a2639fce1" full_name="Jack Heflin" last_modified="2026-09-02T16:25:02+00:00" sr_id="sr:player:2197662"/>
<!-- ... omitted for brevity -->
</players>
</profiles>
<games>
<results>
<game id="0b647d69-be2b-4687-9d30-57914a08ede5" season_id="c0650ee0-17f9-11f1-92c4-398db1c54270" last_modified="2026-09-03T02:21:40+00:00" sr_id="sr:match:71548164"/>
<game id="0b9cc807-288a-4a08-b2c9-c439ad936ed7" season_id="c0650ee0-17f9-11f1-92c4-398db1c54270" last_modified="2026-09-03T02:31:07+00:00" sr_id="sr:match:71548174"/>
<!-- ... omitted for brevity -->
</results>
</games>
</changelog>
</league>
<!-- Generation ended @ 2026-09-03 03:36:00 +0000 -->The response is reduced here to two entries per section. Each entry carries the GUID, the last_modified timestamp, and the sr_id shared with other Sportradar products; game entries add the season_id that tells you which season's feeds to refetch. The sections:
players: players whose profile data changed, such as a name or number edit, a roster move, an injury update, or a status changeschedule: games whose scheduling data changedresults: games whose result or statistical data changed; an ID here means some data associated with the game was modified, which is not necessarily the final score- Team and standings changes are covered the same way and appear as their own sections when they occur
In XML, the profile entries sit under profiles and the game entries under games. Sections appear only when that day changed them, so parse by the sections present rather than expecting a fixed set. The full response for the day above, shortly after the preseason ended, lists 156 players and 12 games under results (revisions to games that had already closed) and no schedule section.
2. Refetch what the log lists
Each section maps to a refetch target. Use the listed IDs, and skip entries whose last_modified you already hold.
| Section | Refetch |
|---|---|
players | Player Profile per listed ID, plus the owning Team Roster when the change is a roster move |
schedule | The affected week's Weekly Schedule, or the Season Schedule on bulk days |
results | Game Statistics, Game Play-by-Play, Game Boxscore, and Game Roster per listed game ID, depending on what you store |
| team entries | Team Profile or Team Roster per listed team ID |
| standings | Postgame Standings once per affected season |
The same four moves apply to every scenario: identify the change types from the sections present (each entry lists a game, player, or team ID); use the IDs to decide the refetch (a game ID under results signals a change in game-related data, while a player or team ID signals a change to that entity, such as a profile update or a roster edit); pull the detailed data from the relevant feed; then compare the newly retrieved data against what you stored to verify the change and update your records.
Which scenario watches which section, and what it refetches:
| Scenario | Watch | Refetch | Worth noting |
|---|---|---|---|
| Tracking Live Games | results | Game Play-by-Play for new plays added or corrections to existing play records; Game Statistics for player statistics and team performance metrics after post-game corrections; Game Boxscore for adjustments to game summary data, including final scores or statistical errors being rectified | The game feeds move to a longer cache once a game is closed, so the change log is how you capture data changes after a game has ended |
| Tracking Standings | results | Postgame Standings | Standings changes after games conclude are rare (a corrected game statistic, a review of play outcomes, a late-reported result), and a results entry means game-related details changed, not necessarily the final score. On September 24, 2023 the log listed game 2273ef3a-6eff-4028-824a-9e7224a323c8 (Seattle Seahawks and Carolina Panthers) under results; Game Statistics showed revised penalty and turnover figures, the kind of change that can reach standings, playoff qualification, and division rankings |
| Retrieving Rosters and Players | players, team entries, results | Team Roster for trades, contract signings, and releases; Game Roster for post-game corrections to player participation (a game ID under results); Daily Transactions for adjustments or corrections to transaction data; Weekly Injuries for corrections to injury data; Weekly Depth Charts for depth chart adjustments | Roster adjustments, transactions, and corrections to player injury details all surface here |
| Retrieving Seasonal Statistics | results | Game Statistics first (its values feed seasonal totals), then Seasonal Statistics for the team ID taken from that game, and Player Profile for the players involved | A corrected game statistic changes seasonal totals; League Leaders, Player Profile, and Seasonal Statistics update within minutes of a game moving to closed, and later corrections reach them through the change log |
| Pulling Schedules | schedule, deleted_games | Weekly Schedule or Season Schedule | Reconcile deleted_games on every pull (step 3) |
| Retrieving Historical Data | any past date | Seasonal Statistics for the season listed | Past dates stay queryable, so statistical updates to past seasons are caught the same way |
When a players section appears, the Daily Transactions feed for the same league day carries the movement detail behind the roster changes: every transaction added or edited that day, with its effective_date, transaction_type, transaction_code, the status before and after, and the teams involved. One player from the league day of 2026-08-26:
GET https://api.sportradar.com/nfl/official/trial/v7/en/league/2026/08/26/transactions.json
x-api-key: YOUR_API_KEY{
"league": {
"id": "3c6d318a-6164-4290-9bbc-bf9bb21cc4b8",
"name": "National Football League",
"alias": "NFL"
},
"start_time": "2026-08-26T04:00:00Z",
"end_time": "2026-08-27T03:59:59Z",
"players": [
{
"id": "22b01678-952c-4923-b1a9-1249aa1e0791",
"name": "Kobe King",
"first_name": "Kobe",
"last_name": "King",
"position": "LB",
"sr_id": "sr:player:2152164",
"transactions": [
{
"id": "040aff10-a193-11f1-ace0-dfb38b033194",
"desc": "The New York Jets waived LB Kobe King due to injury.",
"effective_date": "2026-08-26",
"last_modified": "2026-08-26T21:14:03+00:00",
"transaction_type": "Waived-Injury",
"transaction_code": "WAI",
"transaction_year": 2026,
"status_before": "IR",
"status_after": "UFA",
"from_team": {
"id": "5fee86ae-74ab-4bdd-8416-42a9dd9964f3",
"name": "Jets",
"market": "New York",
"alias": "NYJ",
"sr_id": "sr:competitor:4427"
}
}
]
}
]
}<?xml version="1.0" ?>
<!-- Generation started @ 2026-09-01 09:09:28 +0000 -->
<league xmlns="http://feed.elasticstats.com/schema/football/transactions-v7.0.xsd">
<transactions start_time="2026-08-26T04:00:00Z" end_time="2026-08-27T03:59:59Z">
<player id="22b01678-952c-4923-b1a9-1249aa1e0791" name="Kobe King" first_name="Kobe" last_name="King" position="LB" sr_id="sr:player:2152164">
<transaction id="040aff10-a193-11f1-ace0-dfb38b033194" desc="The New York Jets waived LB Kobe King due to injury." effective_date="2026-08-26" last_modified="2026-08-26T21:14:03+00:00" transaction_type="Waived-Injury" transaction_code="WAI" transaction_year="2026" status_before="IR" status_after="UFA">
<from_team id="5fee86ae-74ab-4bdd-8416-42a9dd9964f3" name="Jets" market="New York" alias="NYJ" sr_id="sr:competitor:4427"/>
</transaction>
</player>
<!-- ... omitted for brevity -->
</transactions>
</league>
<!-- Generation ended @ 2026-09-01 09:09:28 +0000 -->3. Prune deletions
When a game is removed from coverage (for example, a duplicate or an erroneously created game), it is not silently dropped from the API. Removed games surface in three places:
- The change log carries a
deleted_gamesnode beside its other sections on days when a deletion occurs, listing each removed game's ID - Season Schedule and Weekly Schedule responses carry the same reconciliation list in a top-level
deleted_gamesarray - The game itself keeps serving from the game-level feeds (Boxscore, Play-by-Play, Roster, Statistics) with a
deleted: trueflag
A schedule response with deletions lists the affected game IDs alongside the weeks (reduced here to the schedule header):
{
"id": "89049eb0-09b4-11f0-8353-5d9d7165e3e8",
"year": 2025,
"type": "PST",
"name": "PST",
"deleted_games": [
{
"id": "791e392f-1cc7-485c-bb95-026ac2cc31d1"
},
{
"id": "03ec8add-64a4-463d-a9ee-22af5b21f6a5"
}
]
}The deleted game itself keeps serving from game-level feeds with the flag set (reduced to the game header):
{
"id": "791e392f-1cc7-485c-bb95-026ac2cc31d1",
"status": "scheduled",
"scheduled": "2026-03-24T10:00:00+00:00",
"game_type": "regular",
"deleted": true
}To keep your system consistent, store the deleted game IDs so downstream processing (statistics, standings, displays) suppresses them rather than treating a previously ingested game as still active, reconcile the deleted_games array against your stored games on each schedule pull, and include the affected weeks in your reconciliation pass. Pulling Schedules covers the schedule feeds themselves.
4. Recover from downtime
Past dates stay queryable, so an outage is repaired by walking the missed league days in order and applying each day's refetches before moving on. The cache follows the age of the date requested (15 minutes for the current day, 1 hour for the current month, 4 hours for the current year, 12 hours for past years), so a backfill of older days can run at any pace while the current day stays on its normal cadence. The same walk catches statistical updates to past seasons for a historical store.
Best Practices
- Pull every 10 minutes or less, depending on your use case, and once more after the league day closes so the day's full entry set is applied
- Pair the change log with Daily Transactions when a
playerssection appears: the transaction records carry the movement detail - Store
last_modifiedper entity and make refetches idempotent - Treat a
resultsentry as "something about this game changed": refetch the game feeds and compare before assuming the score moved - Keep polling through quiet stretches: standings and statistical adjustments after games conclude are infrequent, and the log is where they first appear
- Expect the league's weekly statistics review to land late on Wednesday or early on Thursday during the season:
resultsentries for the previous week's games appear then, and their Game Statistics are the feeds to refetch - The change log is a pointer feed: it tells you what to refetch, not what changed inside the entity
- Cache and data-update timing for the change log and every refetch target is on Update Frequencies
Updated 6 days ago
