Bracket Building
Use this guide to build and track tournament brackets also known as draws.
Introduction
A tennis bracket, or draw, is the tournament layout used to track how players advance through rounds, showing matchups and progression toward the final. All tennis seasons and competitions in the API are structured into brackets, so understanding how brackets work is important both for interpreting the sport itself and for integrating API data.
Understanding Competitions and Seasons
- A Competition in tennis refers to a professional tournament or tour event, such as the Australian Open, Wimbledon, or ATP 1000 – Indian Wells. Each competition has a unique competition_id.
- A Season represents a specific edition of a competition, usually aligned with a calendar year or event date (e.g., Wimbledon 2025). Each season has a unique
season_id
and includes all matches, players, and results for that instance of the competition.
Different seasons can also include unique round types. For example, a qualification_round_1 marks the opening stage where players compete for entry into the main draw, while a semifinal indicates one of the last four competitors playing for a spot in the championship.
👉 See our FAQ for a full list of round types.
Major Tournaments
Major tournaments with the most extensive coverage include the Grand Slams (Australian Open, French Open, Wimbledon, US Open), as well as the ATP Tour and WTA Tour events. These competitions feature the highest levels of play and provide the richest data, including live scores, detailed statistics, and full bracket structures.
When Bracket Data Updates
For Tier 1 tournaments, draws are added to the API within three hours of official publication, with continuous fixture checks afterward. Brackets update once matches are resulted and closed.
Ensure to Check Update FrequenciesThe Update Frequencies page outlines how often data is refreshed and provides recommended call intervals for each REST endpoint. Use it to optimize your polling strategy before, during, and after matches while avoiding unnecessary requests.
Prerequisite: Confirm Season Availability and Coverage
Understanding which seasons are available—and what level of data coverage is provided—is essential for making reliable and accurate API calls.
- Use the Seasons feed to view all available seasons for each competition in the API.
- Reference the Coverage Matrix to determine the depth of coverage by competition tier.
You can also use the following feeds to see coverage information ahead of matches, including whether serve outcomes, extended stats, and play-by-play data are available, as well as whether scores are delivered live or only after the match:
Building Tournament Brackets
You can use the Season Links to compile full advancement brackets for relevant seasons/tournaments. Links between all matches and rounds are available even when competitors are not yet known.
-
Call the Seasons feed to retrieve
season
IDs for the tournaments you want to track. For example,sr:season:123561
represents the US Open Men’s Singles 2025 season. -
Call the Season Links feed, using your
season
IDs.curl --request GET \ --url https://api.sportradar.com/tennis/trial/v3/en/seasons/sr:season:123561/info.json \ --header 'accept: application/json' \ --header 'x-api-key: {your_api_key}'
Your response returns a list of
sport_event
IDs, each tied to acup_round
and linked to the next round throughlinked_cup_rounds
.Season Links Qualification Round 1 Response Snippet
<?xml version="1.0" encoding="UTF-8"?> <season_stages_groups_cup_rounds xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" generated_at="2025-08-27T14:49:03+00:00" xmlns="http://schemas.sportradar.com/sportsapi/tennis/v3" xsi:schemaLocation="http://schemas.sportradar.com/sportsapi/tennis/v3 https://schemas.sportradar.com/sportsapi/tennis/v3/schemas/season_stages_groups_cup_rounds.xsd"> <stages> <stage order="1" type="cup" phase="qualification" start_date="2025-08-18" end_date="2025-08-22" year="2025"> <groups> <group id="sr:cup:172351" group_name="2025 US Open, New York, USA, Qualifying"> <cup_rounds> <cup_round id="sr:cup_round:2424541" name="qualification_round_1" order="1" state="winner" winner_id="sr:competitor:445419"> <sport_events> <sport_event id="sr:sport_event:63017887" start_time="2025-08-18T18:30:00+00:00" start_time_confirmed="true" order="1"/> </sport_events> <linked_cup_rounds> <cup_round id="sr:cup_round:2426645" type="parent" name="qualification_round_2" order="1" state="winner" winner_id="sr:competitor:445419"/> </linked_cup_rounds> </cup_round> <cup_round id="sr:cup_round:2424543" name="qualification_round_1" order="2" state="winner" winner_id="sr:competitor:116616"> <sport_events> <sport_event id="sr:sport_event:63017885" start_time="2025-08-18T19:20:00+00:00" start_time_confirmed="true" order="1"/> </sport_events> <linked_cup_rounds> <cup_round id="sr:cup_round:2426645" type="parent" name="qualification_round_2" order="1" state="winner" winner_id="sr:competitor:445419"/> </linked_cup_rounds> </cup_round> <cup_round id="sr:cup_round:2424545" name="qualification_round_1" order="3" state="winner" winner_id="sr:competitor:48632"> <sport_events> <sport_event id="sr:sport_event:63017883" start_time="2025-08-18T17:55:00+00:00" start_time_confirmed="true" order="1"/> </sport_events> <linked_cup_rounds> <cup_round id="sr:cup_round:2426647" type="parent" name="qualification_round_2" order="2" state="winner" winner_id="sr:competitor:46391"/> </linked_cup_rounds> </cup_round> <cup_round id="sr:cup_round:2424547" name="qualification_round_1" order="4" state="winner" winner_id="sr:competitor:46391"> <sport_events>
{ "generated_at": "2025-08-27T14:42:51+00:00", "stages": [ { "order": 1, "type": "cup", "phase": "qualification", "start_date": "2025-08-18", "end_date": "2025-08-22", "year": "2025", "groups": [ { "id": "sr:cup:172351", "group_name": "2025 US Open, New York, USA, Qualifying", "cup_rounds": [ { "id": "sr:cup_round:2424541", "sport_events": [ { "id": "sr:sport_event:63017887", "start_time": "2025-08-18T18:30:00+00:00", "start_time_confirmed": true, "order": 1 } ], "linked_cup_rounds": [ { "id": "sr:cup_round:2426645", "type": "parent", "name": "qualification_round_2", "order": 1, "state": "winner", "winner_id": "sr:competitor:445419" } ], "name": "qualification_round_1", "order": 1, "state": "winner", "winner_id": "sr:competitor:445419" }, { "id": "sr:cup_round:2424543", "sport_events": [ { "id": "sr:sport_event:63017885", "start_time": "2025-08-18T19:20:00+00:00", "start_time_confirmed": true, "order": 1 } ], "linked_cup_rounds": [ { "id": "sr:cup_round:2426645", "type": "parent", "name": "qualification_round_2", "order": 1, "state": "winner", "winner_id": "sr:competitor:445419" } ], "name": "qualification_round_1", "order": 2, "state": "winner", "winner_id": "sr:competitor:116616" }, { "id": "sr:cup_round:2424545", "sport_events": [ { "id": "sr:sport_event:63017883", "start_time": "2025-08-18T17:55:00+00:00", "start_time_confirmed": true, "order": 1 } ], "linked_cup_rounds": [ { "id": "sr:cup_round:2426647", "type": "parent", "name": "qualification_round_2", "order": 2, "state": "winner", "winner_id": "sr:competitor:46391" } ], "name": "qualification_round_1", "order": 3, "state": "winner", "winner_id": "sr:competitor:48632" }, { "id": "sr:cup_round:2424547", "sport_events": [ { "id": "sr:sport_event:63017881", "start_time": "2025-08-18T18:50:00+00:00", "start_time_confirmed": true, "order": 1 } ], "linked_cup_rounds": [ { "id": "sr:cup_round:2426647", "type": "parent", "name": "qualification_round_2", "order": 2, "state": "winner", "winner_id": "sr:competitor:46391" } ], "name": "qualification_round_1", "order": 4, "state": "winner", "winner_id": "sr:competitor:46391" },
-
Structure your bracket by mapping each
sport_event.id
(match) to itscup_round
, then use thelinked_cup_rounds
to connect winners to the next round.You can render a bracket similar to the below using the data.
Bracket winners are populated once matches are marked as
closed
. -
Re-pull the bracket whenever a match status changes to
closed
to keep your bracket updated with winners, competitors, and match times.Note: To access competitor details and specific match or round times and statuses, use the
sport_event.id
with the Sport Event Summary or Sport Event Timeline endpoints.<sport_event id="sr:sport_event:63017887" start_time="2025-08-18T18:30: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:2591" name="US Open Men Singles" parent_id="sr:competition:2589" type="singles" gender="men" level="grand_slam"/> <season id="sr:season:123561" name="US Open Men Singles 2025" start_date="2025-08-18" end_date="2025-09-08" year="2025" competition_id="sr:competition:2591"/> <stage order="1" type="cup" phase="qualification" start_date="2025-08-18" end_date="2025-08-22" year="2025"/> <round number="1" name="qualification_round_1"/> <groups> <group id="sr:cup:172351" name="2025 US Open, New York, USA, Qualifying"/> </groups> <mode best_of="3"/> </sport_event_context> <coverage type="sport_event"> <sport_event_properties enhanced_stats="false" scores="live" detailed_serve_outcomes="true" play_by_play="true"/> </coverage> <competitors> <competitor id="sr:competitor:445419" name="Cazaux, Arthur" country="France" country_code="FRA" abbreviation="CAZ" qualifier="home" seed="1" bracket_number="1"/> <competitor id="sr:competitor:801386" name="Lajal, Mark" country="Estonia" country_code="EST" abbreviation="LAJ" qualifier="away" bracket_number="2"/> </competitors> <sport_event_status status="closed" match_status="ended" home_score="2" away_score="0" winner_id="sr:competitor:445419"> <period_scores> <period_score home_score="6" away_score="4" type="set" number="1"/> <period_score home_score="6" away_score="1" type="set" number="2"/> </period_scores> </sport_event_status>
Map Stage and Round Back to Season LinksYou can also use the
stage
andround
objects in the Sport Event Summary or Sport Event Timeline endpoints to map a match’sorder
,type
,phase
, andround
(e.g.,<round number="1" name="qualification_round_1"/>
) back to the Season Links endpoint, ensuring consistent alignment between stages and season structures.Byes and Missing MatchesIn tennis tournaments, early rounds sometimes include byes, meaning a player automatically advances without playing a match. In these cases, a bracket slot may appear in the Season Links feed without a linked
sport_event
. Treat the slot as a bye/auto-advance, and use thewinner_id
(when present) to place the competitor in the next round. Don’t expect a match record for that slot—none exists.Byes and Missing Matches Season Links Snippet
<cup_round id="sr:cup_round:2413674" name="round_of_128" order="3" state="winner" winner_id="sr:competitor:257721"> <sport_events> <sport_event id="sr:sport_event:62641487" start_time="2025-08-08T02:25:00+00:00" start_time_confirmed="true" order="1" /> </sport_events> <linked_cup_rounds> <cup_round id="sr:cup_round:2413800" type="parent" name="round_of_64" order="2" state="winner" winner_id="sr:competitor:418213" /> </linked_cup_rounds> </cup_round> <cup_round id="sr:cup_round:2413676" name="round_of_128" order="4" state="winner" winner_id="sr:competitor:418213"> <linked_cup_rounds> <cup_round id="sr:cup_round:2413800" type="parent" name="round_of_64" order="2" state="winner" winner_id="sr:competitor:418213" /> </linked_cup_rounds> </cup_round> <cup_round id="sr:cup_round:2413678" name="round_of_128" order="5" state="winner" winner_id="sr:competitor:300540"> <linked_cup_rounds> <cup_round id="sr:cup_round:2413802" type="parent" name="round_of_64" order="3" state="winner" winner_id="sr:competitor:15894" /> </linked_cup_rounds> </cup_round> <cup_round id="sr:cup_round:2413680" name="round_of_128" order="6" state="winner" winner_id="sr:competitor:15894"> <sport_events> <sport_event id="sr:sport_event:62686091" start_time="2025-08-07T20:45:00+00:00" start_time_confirmed="true" order="1" /> </sport_events> <linked_cup_rounds> <cup_round id="sr:cup_round:2413802" type="parent" name="round_of_64" order="3" state="winner" winner_id="sr:competitor:15894" /> </linked_cup_rounds> </cup_round>
{ "id": "sr:cup_round:2413674", "sport_events": [ { "id": "sr:sport_event:62641487", "start_time": "2025-08-08T02:25:00+00:00", "start_time_confirmed": true, "order": 1 } ], "linked_cup_rounds": [ { "id": "sr:cup_round:2413800", "type": "parent", "name": "round_of_64", "order": 2, "state": "winner", "winner_id": "sr:competitor:418213" } ], "name": "round_of_128", "order": 3, "state": "winner", "winner_id": "sr:competitor:257721" }, { "id": "sr:cup_round:2413676", "linked_cup_rounds": [ { "id": "sr:cup_round:2413800", "type": "parent", "name": "round_of_64", "order": 2, "state": "winner", "winner_id": "sr:competitor:418213" } ], "name": "round_of_128", "order": 4, "state": "winner", "winner_id": "sr:competitor:418213" }, { "id": "sr:cup_round:2413678", "linked_cup_rounds": [ { "id": "sr:cup_round:2413802", "type": "parent", "name": "round_of_64", "order": 3, "state": "winner", "winner_id": "sr:competitor:15894" } ], "name": "round_of_128", "order": 5, "state": "winner", "winner_id": "sr:competitor:300540" }, { "id": "sr:cup_round:2413680", "sport_events": [ { "id": "sr:sport_event:62686091", "start_time": "2025-08-07T20:45:00+00:00", "start_time_confirmed": true, "order": 1 } ], "linked_cup_rounds": [ { "id": "sr:cup_round:2413802", "type": "parent", "name": "round_of_64", "order": 3, "state": "winner", "winner_id": "sr:competitor:15894" } ], "name": "round_of_128", "order": 6, "state": "winner", "winner_id": "sr:competitor:15894" },
Bracket Example
You can use our data to build interactive draws just like the one on the US Open site. The draw shows the full bracket, matchups, and progression through each round, giving your users a clear, engaging way to follow the tournament.
Competitor Placeholder Values
When populating your bracket with competitor information, you may encounter virtual competitors (virtual="true"
). These serve as placeholders for players or teams in matchups that have not yet been determined.
<competitors>
<competitor id="sr:competitor:837876" name="R16P7" abbreviation="R16" virtual="true" qualifier="home"/>
<competitor id="sr:competitor:837878" name="R16P8" abbreviation="R16" virtual="true" qualifier="away"/></competitors>
"competitors": [
{
"id": "sr:competitor:837876",
"name": "R16P7",
"abbreviation": "R16",
"virtual": true,
"qualifier": "home"
},
{
"id": "sr:competitor:837878",
"name": "R16P8",
"abbreviation": "R16",
"virtual": true,
"qualifier": "away"
}
],
These placeholder values are automatically replaced with the actual competitors once the winners are determined.
Monitoring Post-Match Updates
Learn how to track daily changes to the Tennis API without depleting your call limits.
Updated 2 days ago