Tracking Live Matches
This integration scenario explains how to track live tennis matches: finding what is in play, following the score point by point, reading serve and game state, layering in live statistics, and winding down cleanly when a match closes.
This scenario is commonly used to:
- Power live scoreboards and match trackers
- Drive point-by-point commentary and visualizations
- Feed in-play statistics widgets
- Trigger notifications for set points, tiebreaks, and match points
Overview
Three live feeds cover everything in play at once: Live Summaries (scores and game state for every live match), Live Timelines (the point-by-point event stream for every live match), and Live Timelines Delta (just the last few minutes of change). For a featured match, the match-scoped Sport Event Summary and Sport Event Timeline serve the same data one match at a time. The companion Probabilities API adds live win probabilities.
Live data is tier-dependent: check each match's coverage object before wiring point-by-point logic. See Data Coverage and Tiers.
Matches move through their lifecycle as described in Match Status Workflow; the statuses drive when to poll what.
Relevant Feeds
| Feed | Purpose |
|---|---|
| Live Summaries | Every match in play: score, set scores, and game state |
| Live Timelines | Point-by-point event streams for every live match |
| Live Timelines Delta | Recent timeline changes only, for cheap frequent polling |
| Sport Event Summary | One match: live score, game state, and statistics |
| Sport Event Timeline | One match: the full point-by-point timeline |
| Live Probabilities | Win probabilities for covered live matches (Probabilities API) |
High-Level Workflow
Integration Steps
1. Find What Is Live
Live Summaries lists every match currently in play or recently changed, with full context. Matches about to start and rain-interrupted matches appear alongside live ones, so the feed is also your in-play watchlist:
GET https://api.sportradar.com/tennis/{access_level}/v3/{language_code}/schedules/live/summaries.{format}{
"generated_at": "2026-07-27T21:52:00+00:00",
"summaries": [
{
"sport_event": {
"id": "sr:sport_event:73163852",
"start_time": "2026-07-27T21:00:00+00:00",
"start_time_confirmed": true,
"sport_event_context": {
"sport": {
"id": "sr:sport:5",
"name": "Tennis"
},
"category": {
"id": "sr:category:3",
"name": "ATP"
},
"competition": {
"id": "sr:competition:2971",
"name": "ATP Washington, USA Men Singles",
"parent_id": "sr:competition:2969",
"type": "singles",
"gender": "men",
"level": "atp_500"
},
"season": {
"id": "sr:season:134781",
"name": "ATP Washington, USA Men Singles 2026",
"start_date": "2026-07-25",
"end_date": "2026-08-02",
"year": "2026",
"competition_id": "sr:competition:2971"
},
"stage": {
"order": 2,
"type": "cup",
"phase": "stage_1_playoff",
"start_date": "2026-07-27",
"end_date": "2026-08-02",
"year": "2026"
},
"round": {
"name": "round_of_32"
},
"groups": [
{
"id": "sr:cup:186985",
"name": "2026 Washington, USA"
}
],
"mode": {
"best_of": 3
}
},
"coverage": {
"type": "sport_event",
"sport_event_properties": {
"enhanced_stats": false,
"scores": "live",
"detailed_serve_outcomes": true,
"play_by_play": true
}
},
"competitors": [
{
"id": "sr:competitor:15733",
"name": "Nishikori, Kei",
"country": "Japan",
"country_code": "JPN",
"abbreviation": "NIS",
"qualifier": "home",
"bracket_number": 19
},
{
"id": "sr:competitor:721347",
"name": "Shang, Juncheng",
"country": "China",
"country_code": "CHN",
"abbreviation": "SHA",
"qualifier": "away",
"bracket_number": 20
}
],
"venue": {
"id": "sr:venue:1957",
"name": "John Harris Court",
"city_name": "Washington, D.C.",
"city_id": "sr:city:911",
"country_name": "USA",
"country_code": "USA",
"timezone": "America/New_York"
},
"channels": [
{
"name": "C+ DEPORTES - Hispasat 1B/1C/1D (30.0 W) - CPD2 - 5494"
},
{
"name": "SPORT1 DE - Astra 1C-1H / 2C (19.2E)"
},
{
"name": "Sport2 HU - Thor 2/3 (1.0W)"
},
{
"name": "NOVA Sport 1 HD CZ - Thor 2/3 (1.0W)"
},
{
"name": "Supertennis HD - Hot Bird 1/2/3/4/6 (13.0E)"
},
{
"name": "ORF Sport Plus - Astra 1C-1H / 2C (19.2E)"
},
{
"name": "EUROSPORT 1 FR - Astra 1C-1H / 2C (19.2E)"
},
{
"name": "Sport TV2 HD - Hispasat 1B/1C/1D (30.0 W) - NOS PT"
},
{
"name": "Sport TV4 HD - Hispasat 1B/1C/1D (30.0 W) - NOS PT"
},
{
"name": "C More Live - Thor 2/3 (1.0W) - Telenor - 5063"
},
{
"name": "C More Tennis HD - Thor 2/3 (1.0W) - Telenor - 234"
},
{
"name": "Sport1+ HD - Astra 1C-1H / 2C (19.2E)"
},
{
"name": "Sky Sport HD 1 (D) - Astra 1C-1H / 2C (19.2E)"
},
{
"name": "Eurosport Danmark - Astra 4A & SES 5 (4.9E)"
},
{
"name": "Sport Klub 1 SRB - (16.0E)"
},
{
"name": "Sky Sport HD 2 (D) - Astra 1C-1H / 2C (19.2E)"
},
{
"name": "Tennis Channel US"
},
{
"name": "ATP Tennis TV"
}
],
"estimated": true
},
"sport_event_status": {
"status": "live",
"match_status": "1st_set",
"home_score": 0,
"away_score": 0,
"period_scores": [
{
"home_score": 5,
"away_score": 5,
"type": "set",
"number": 1
}
],
"game_state": {
"home_score": 40,
"away_score": 40,
"serving": "away",
"last_point_result": "server_winner",
"tie_break": false
}
},
"statistics": {
"totals": {
"competitors": [
{
"id": "sr:competitor:15733",
"name": "Nishikori, Kei",
"abbreviation": "NIS",
"qualifier": "home",
"statistics": {
"aces": 0,
"breakpoints_won": 0,
"double_faults": 0,
"first_serve_points_won": 15,
"first_serve_successful": 20,
"games_won": 5,
"max_games_in_a_row": 1,
"max_points_in_a_row": 4,
"points_won": 34,
"points_won_from_last_10": 5,
"second_serve_points_won": 5,
"second_serve_successful": 6,
"service_games_won": 5,
"service_points_lost": 6,
"service_points_won": 20,
"tiebreaks_won": 0,
"total_breakpoints": 3
}
},
{
"id": "sr:competitor:721347",
"name": "Shang, Juncheng",
"abbreviation": "SHA",
"qualifier": "away",
"statistics": {
"aces": 2,
"breakpoints_won": 0,
"double_faults": 1,
"first_serve_points_won": 17,
"first_serve_successful": 26,
"games_won": 5,
"max_games_in_a_row": 1,
"max_points_in_a_row": 4,
"points_won": 33,
"points_won_from_last_10": 5,
"second_serve_points_won": 10,
"second_serve_successful": 14,
"service_games_won": 5,
"service_points_lost": 14,
"service_points_won": 27,
"tiebreaks_won": 0,
"total_breakpoints": 0
}
}
]
}
}
},
{
"sport_event": {
"id": "sr:sport_event:73148798",
"start_time": "2026-07-27T15:00:00+00:00",
"start_time_confirmed": true,
"sport_event_context": {
"sport": {
"id": "sr:sport:5",
"name": "Tennis"
},
"category": {
"id": "sr:category:6",
"name": "WTA"
},
"competition": {
"id": "sr:competition:4483",
"name": "WTA Memphis, USA Women Singles",
"parent_id": "sr:competition:4481",
"type": "singles",
"gender": "women",
"level": "wta_250"
},
"season": {
"id": "sr:season:140230",
"name": "WTA Memphis, USA Women Singles 2026",
"start_date": "2026-07-25",
"end_date": "2026-08-02",
"year": "2026",
"competition_id": "sr:competition:4483"
},
"stage": {
"order": 2,
"type": "cup",
"phase": "playoffs",
"start_date": "2026-07-27",
"end_date": "2026-08-02",
"year": "2026"
},
"round": {
"name": "round_of_32"
},
"groups": [
{
"id": "sr:cup:194664",
"name": "2026 Memphis, USA"
}
],
"mode": {
"best_of": 3
}
},
"coverage": {
"type": "sport_event",
"sport_event_properties": {
"enhanced_stats": false,
"scores": "live",
"detailed_serve_outcomes": true,
"play_by_play": true
}
},
"competitors": [
{
"id": "sr:competitor:343160",
"name": "Volynets, Katie",
"country": "USA",
"country_code": "USA",
"abbreviation": "VOL",
"qualifier": "home",
"bracket_number": 23
},
{
"id": "sr:competitor:48455",
"name": "Golubic, Viktorija",
"country": "Switzerland",
"country_code": "CHE",
"abbreviation": "GOL",
"qualifier": "away",
"seed": 3,
"bracket_number": 24
}
],
"venue": {
"id": "sr:venue:28425",
"name": "Court 2",
"city_name": "Memphis, TN",
"city_id": "sr:city:866",
"country_name": "USA",
"country_code": "USA",
"timezone": "America/Chicago"
},
"channels": [
{
"name": "Tennis Channel US"
}
],
"estimated": false
},
"sport_event_status": {
"status": "interrupted",
"match_status": "interrupted",
"home_score": 1,
"away_score": 1,
"period_scores": [
{
"home_score": 7,
"away_score": 5,
"type": "set",
"number": 1
},
{
"home_score": 2,
"away_score": 6,
"type": "set",
"number": 2
},
{
"home_score": 2,
"away_score": 4,
"type": "set",
"number": 3
}
]
},
"statistics": {
"totals": {
"competitors": [
{
"id": "sr:competitor:343160",
"name": "Volynets, Katie",
"abbreviation": "VOL",
"qualifier": "home",
"statistics": {
"aces": 2,
"breakpoints_won": 5,
"double_faults": 4,
"first_serve_points_won": 35,
"first_serve_successful": 66,
"games_won": 11,
"max_games_in_a_row": 4,
"max_points_in_a_row": 9,
"points_won": 94,
"second_serve_points_won": 15,
"second_serve_successful": 30,
"service_games_won": 6,
"service_points_lost": 50,
"service_points_won": 50,
"tiebreaks_won": 0,
"total_breakpoints": 15
}
},
{
"id": "sr:competitor:48455",
"name": "Golubic, Viktorija",
"abbreviation": "GOL",
"qualifier": "away",
"statistics": {
"aces": 0,
"breakpoints_won": 7,
"double_faults": 6,
"first_serve_points_won": 43,
"first_serve_successful": 70,
"games_won": 15,
"max_games_in_a_row": 6,
"max_points_in_a_row": 8,
"points_won": 108,
"second_serve_points_won": 15,
"second_serve_successful": 26,
"service_games_won": 8,
"service_points_lost": 44,
"service_points_won": 58,
"tiebreaks_won": 0,
"total_breakpoints": 16
}
}
]
}
}
}
]
}An empty summaries array is the normal quiet state when nothing is live.
2. Read the Score and Game State
For a featured match, poll its Sport Event Summary. During play, sport_event_status carries the sets in period_scores and the in-game situation in game_state, and covered matches include live statistics per player:
GET https://api.sportradar.com/tennis/{access_level}/v3/{language_code}/sport_events/{sport_event_id}/summary.{format}{
"generated_at": "2026-07-27T21:52:09+00:00",
"sport_event": {
"id": "sr:sport_event:73163852",
"start_time": "2026-07-27T21:00:00+00:00"
},
"sport_event_status": {
"status": "live",
"match_status": "1st_set",
"home_score": 0,
"away_score": 0,
"period_scores": [
{
"home_score": 5,
"away_score": 5,
"type": "set",
"number": 1
}
],
"game_state": {
"home_score": 50,
"away_score": 40,
"serving": "away",
"advantage": "home",
"last_point_result": "receiver_winner",
"tie_break": false
}
},
"statistics": {
"totals": {
"competitors": [
{
"id": "sr:competitor:15733",
"name": "Nishikori, Kei",
"abbreviation": "NIS",
"qualifier": "home",
"statistics": {
"aces": 0,
"breakpoints_won": 0,
"double_faults": 0,
"first_serve_points_won": 15,
"first_serve_successful": 20,
"games_won": 5,
"max_games_in_a_row": 1,
"max_points_in_a_row": 4,
"points_won": 34,
"points_won_from_last_10": 5,
"second_serve_points_won": 5,
"second_serve_successful": 6,
"service_games_won": 5,
"service_points_lost": 6,
"service_points_won": 20,
"tiebreaks_won": 0,
"total_breakpoints": 3
}
},
{
"id": "sr:competitor:721347",
"name": "Shang, Juncheng",
"abbreviation": "SHA",
"qualifier": "away",
"statistics": {
"aces": 2,
"breakpoints_won": 0,
"double_faults": 1,
"first_serve_points_won": 17,
"first_serve_successful": 26,
"games_won": 5,
"max_games_in_a_row": 1,
"max_points_in_a_row": 4,
"points_won": 33,
"points_won_from_last_10": 5,
"second_serve_points_won": 10,
"second_serve_successful": 14,
"service_games_won": 5,
"service_points_lost": 14,
"service_points_won": 27,
"tiebreaks_won": 0,
"total_breakpoints": 0
}
}
]
}
}
}<?xml version="1.0" ?>
<sport_event_summary xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.sportradar.com/sportsapi/tennis/v3" generated_at="2026-07-27T21:52:13+00:00" xsi:schemaLocation="http://schemas.sportradar.com/sportsapi/tennis/v3 https://schemas.sportradar.com/sportsapi/tennis/v3/schemas/sport_event_summary.xsd">
<sport_event id="sr:sport_event:73163852" start_time="2026-07-27T21:00:00+00:00" start_time_confirmed="true" estimated="true">
<sport_event_context>
<sport id="sr:sport:5" name="Tennis"/>
<category id="sr:category:3" name="ATP"/>
<competition id="sr:competition:2971" name="ATP Washington, USA Men Singles" parent_id="sr:competition:2969" type="singles" gender="men" level="atp_500"/>
<season id="sr:season:134781" name="ATP Washington, USA Men Singles 2026" start_date="2026-07-25" end_date="2026-08-02" year="2026" competition_id="sr:competition:2971"/>
<stage order="2" type="cup" phase="stage_1_playoff" start_date="2026-07-27" end_date="2026-08-02" year="2026"/>
<round name="round_of_32"/>
<groups>
<group id="sr:cup:186985" name="2026 Washington, USA"/>
</groups>
<mode best_of="3"/>
<!-- ... omitted for brevity -->
</sport_event_context>
</sport_event>
</sport_event_summary>Read game_state as a unit: the point score (0, 15, 30, 40, 50), serving, advantage at deuce, tie_break, and last_point_result for how the previous point ended.
3. Follow the Points
Live Timelines streams the event-by-event record for every live match; the match-scoped Sport Event Timeline serves one match's full history. Events are compact and typed: match_started, first_serve, point, period_score (a game concluding), period_start (a new set), and match_ended:
GET https://api.sportradar.com/tennis/{access_level}/v3/{language_code}/sport_events/{sport_event_id}/timeline.{format}{
"generated_at": "2026-07-27T21:52:12+00:00",
"sport_event": {
"id": "sr:sport_event:73163852",
"start_time": "2026-07-27T21:00:00+00:00"
},
"timeline": [
{
"id": 4730503,
"type": "point",
"time": "2026-07-27T21:50:35+00:00",
"competitor": "home",
"home_score": 50,
"away_score": 40,
"server": "away",
"result": "receiver_won",
"first_serve_fault": true
},
{
"id": 4730504,
"type": "point",
"time": "2026-07-27T21:51:26+00:00",
"competitor": "away",
"home_score": 40,
"away_score": 40,
"server": "away",
"result": "server_won",
"first_serve_fault": true
},
{
"id": 4730505,
"type": "point",
"time": "2026-07-27T21:52:03+00:00",
"competitor": "home",
"home_score": 50,
"away_score": 40,
"server": "away",
"result": "receiver_won"
}
]
}Parse defensively: handle event types you do not recognize by skipping them, and upsert events by id in case an event is revised.
4. Poll Cheaply with the Delta
Live Timelines Delta returns only the last few minutes of timeline change, making very frequent polling affordable. Between changes an entry's envelope can be present but empty; treat that as "no news", not an error:
GET https://api.sportradar.com/tennis/{access_level}/v3/{language_code}/schedules/live/timelines_delta.{format}{
"generated_at": "2026-07-27T21:52:08+00:00",
"sport_event_timeline_deltas": [
{
"sport_event_timeline": {
"id": "sr:sport_event:73163852",
"start_time": "2026-07-27T21:00:00+00:00",
"sport_event_status": {
"status": "live",
"match_status": "1st_set",
"home_score": 0,
"away_score": 0,
"period_scores": [
{
"home_score": 5,
"away_score": 5,
"type": "set",
"number": 1
}
],
"game_state": {
"home_score": 40,
"away_score": 40,
"serving": "away",
"last_point_result": "server_winner",
"tie_break": false
}
},
"timeline": [
{
"id": 2421107894,
"type": "point",
"time": "2026-07-27T21:52:05+00:00",
"competitor": "home"
}
]
}
}
]
}5. Layer In Win Probabilities
The Probabilities API's Live Probabilities feed lists covered live matches with a 2way market. In play, entries carry both the settled pre-match market and a live market updated with the score:
GET https://api.sportradar.com/tennis-probabilities/{access_level}/v3/{language_code}/schedules/live/probabilities.{format}{
"generated_at": "2026-07-27T21:53:55+00:00",
"sport_event_probabilities": [
{
"sport_event": {
"id": "sr:sport_event:73148798",
"start_time": "2026-07-27T15:00:00+00:00"
},
"sport_event_status": {
"status": "interrupted",
"match_status": "interrupted",
"home_score": 1,
"away_score": 1
},
"markets": [
{
"name": "2way",
"outcomes": [
{
"name": "home_team_winner",
"probability": 63.1
},
{
"name": "away_team_winner",
"probability": 36.9
}
],
"last_updated": "2026-07-27T14:50:18+00:00"
},
{
"name": "2way",
"outcomes": [
{
"name": "home_team_winner",
"probability": 14.4
},
{
"name": "away_team_winner",
"probability": 85.6
}
],
"last_updated": "2026-07-27T18:04:13+00:00",
"home_score": 1,
"away_score": 1,
"removed": true
}
]
}
]
}6. Wind Down at Match End
When status reaches ended, keep polling the match summary until it settles at closed, then pull the final Sport Event Summary and Sport Event Timeline once for your archive. Post-match corrections can still land shortly after; re-pull the next day if you store statistics. See Match Status Workflow for the ended-to-closed window and special outcomes such as retirements.
Common Use Cases
- Live scoreboard: Live Summaries on a 1 to 3 second cadence; render set scores plus game state.
- Featured match tracker: the match's Sport Event Summary plus Timeline, with the delta feed for the point stream.
- Win-probability graphic: Live Probabilities alongside the score.
- Match-point alerts: watch
game_stateforadvantagewith a set-deciding score, or point events in the timeline.
Best Practices
- Drive everything off status: ramp polling up at
live, keep polling throughinterrupted, and stop atclosed. - The three live feeds serve every live match in one response: prefer them over per-match polling when you track more than one court.
- Respect coverage: a match without
play_by_playcoverage will not produce timeline points; fall back to score-only rendering. - Recover from gaps with the match-scoped timeline: it carries the full history, so a missed delta window costs nothing.
Updated 1 day ago
