Retrieving Rankings and Standings
This integration scenario explains how to retrieve tennis rankings and standings: the ATP and WTA world rankings, the season-to-date race, doubles rankings, and group standings for round-robin and team events.
This scenario is commonly used to:
- Display world-ranking leaderboards and movement
- Build player cards with current and career-high rankings
- Track the race to the season finals
- Show group tables for round-robin and team competitions
Overview
Tennis leaderboards come in two shapes. Rankings are tour-wide player tables published by the ATP and WTA: the official world rankings, their doubles equivalents, and the year-to-date race. Standings are per-season group tables for competitions with round-robin play, such as the United Cup, tour finals groups, and team cups. Rankings live in dedicated global feeds; standings hang off a season_id.
When Rankings UpdateWorld rankings publish weekly on Mondays, with occasional corrections in between. The race rankings move with results through the week. Standings update as each round-robin match completes.
Relevant Feeds
| Feed | Purpose |
|---|---|
| Rankings | Official ATP and WTA singles world rankings |
| Race Rankings | Season-to-date race standings |
| Doubles Competitor Rankings | Official doubles rankings |
| Doubles Race Rankings | Doubles season race |
| Season Standings | Group tables for a round-robin season |
| Competitor Profile | A player's current and career-high rankings, with context |
High-Level Workflow
Integration Steps
1. Pull the World Rankings
Rankings returns both tours in one call: an ATP list and a WTA list, 500 rows each, with points and week-over-week movement:
GET https://api.sportradar.com/tennis/{access_level}/v3/{language_code}/rankings.{format}{
"generated_at": "2026-07-27T20:10:40+00:00",
"rankings": [
{
"type_id": 1,
"name": "ATP",
"year": 2026,
"week": 31,
"gender": "men",
"competitor_rankings": [
{
"rank": 1,
"movement": 0,
"points": 13450,
"competitions_played": 18,
"competitor": {
"id": "sr:competitor:225050",
"name": "Sinner, Jannik",
"country": "Italy",
"country_code": "ITA",
"abbreviation": "SIN"
}
},
{
"rank": 2,
"movement": 0,
"points": 8480,
"competitions_played": 20,
"competitor": {
"id": "sr:competitor:57163",
"name": "Zverev, Alexander",
"country": "Germany",
"country_code": "DEU",
"abbreviation": "ZVE"
}
},
{
"rank": 3,
"movement": 0,
"points": 8160,
"competitions_played": 17,
"competitor": {
"id": "sr:competitor:407573",
"name": "Alcaraz, Carlos",
"country": "Spain",
"country_code": "ESP",
"abbreviation": "ALC"
}
}
]
}
]
}<?xml version="1.0" ?>
<rankings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.sportradar.com/sportsapi/tennis/v3" generated_at="2026-07-27T21:49:10+00:00" xsi:schemaLocation="http://schemas.sportradar.com/sportsapi/tennis/v3 https://schemas.sportradar.com/sportsapi/tennis/v3/schemas/rankings.xsd">
<ranking type_id="1" name="ATP" year="2026" week="31" gender="men">
<competitor_rankings>
<competitor_ranking rank="1" movement="0" points="13450" competitions_played="18">
<competitor id="sr:competitor:225050" name="Sinner, Jannik" country="Italy" country_code="ITA" abbreviation="SIN"/>
</competitor_ranking>
<competitor_ranking rank="2" movement="0" points="8480" competitions_played="20">
<competitor id="sr:competitor:57163" name="Zverev, Alexander" country="Germany" country_code="DEU" abbreviation="ZVE"/>
</competitor_ranking>
<competitor_ranking rank="3" movement="0" points="8160" competitions_played="17">
<competitor id="sr:competitor:407573" name="Alcaraz, Carlos" country="Spain" country_code="ESP" abbreviation="ALC"/>
<!-- ... omitted for brevity -->
</competitor_ranking>
</competitor_rankings>
</ranking>
</rankings>2. Add the Race
Race Rankings mirrors the same row shape for the season-to-date race, the table that decides qualification for the tour finals:
GET https://api.sportradar.com/tennis/{access_level}/v3/{language_code}/race_rankings.{format}{
"generated_at": "2026-07-27T21:11:03+00:00",
"rankings": [
{
"type_id": 4,
"name": "ATP",
"year": 2026,
"week": 30,
"gender": "men",
"competitor_rankings": [
{
"rank": 1,
"movement": 0,
"points": 7950,
"competitor": {
"id": "sr:competitor:225050",
"name": "Sinner, Jannik",
"country": "Italy",
"country_code": "ITA",
"abbreviation": "SIN"
}
},
{
"rank": 2,
"movement": 0,
"points": 6540,
"competitor": {
"id": "sr:competitor:57163",
"name": "Zverev, Alexander",
"country": "Germany",
"country_code": "DEU",
"abbreviation": "ZVE"
}
}
]
}
]
}3. Cover Doubles
The doubles feeds follow the same shape, ranking individual players on their doubles results. Doubles teams themselves are separate competitors with their own IDs; see ID Handling for how team and player IDs relate:
GET https://api.sportradar.com/tennis/{access_level}/v3/{language_code}/double_competitors_rankings.{format}{
"generated_at": "2026-07-27T21:50:25+00:00",
"rankings": [
{
"type_id": 2,
"name": "ATP",
"year": 2026,
"week": 31,
"gender": "men",
"competitor_rankings": [
{
"rank": 1,
"movement": 0,
"points": 9960,
"competitions_played": 20,
"competitor": {
"id": "sr:competitor:14898",
"name": "Heliovaara, Harri",
"country": "Finland",
"country_code": "FIN",
"abbreviation": "HEL"
}
},
{
"rank": 1,
"movement": 0,
"points": 9960,
"competitions_played": 20,
"competitor": {
"id": "sr:competitor:637970",
"name": "Patten, Henry",
"country": "Great Britain",
"country_code": "GBR",
"abbreviation": "PAT"
}
}
]
}
]
}4. Enrich Player Cards from the Profile
Competitor Profile carries a player's current rankings alongside career-high marks and biographical context, ideal for a player header without joining feeds:
GET https://api.sportradar.com/tennis/{access_level}/v3/{language_code}/competitors/{competitor_id}/profile.{format}{
"generated_at": "2026-07-27T21:52:48+00:00",
"competitor": {
"id": "sr:competitor:225050",
"name": "Sinner, Jannik",
"country": "Italy",
"country_code": "ITA",
"abbreviation": "SIN",
"gender": "male"
},
"info": {
"pro_year": 2018,
"handedness": "right",
"highest_singles_ranking": 1,
"highest_doubles_ranking": 124,
"weight": 77,
"height": 191,
"date_of_birth": "2001-08-16",
"highest_singles_ranking_date": "06.2024",
"highest_doubles_ranking_date": "09.2021"
},
"competitor_rankings": [
{
"rank": 1,
"movement": 0,
"points": 13450,
"competitor_id": "sr:competitor:225050",
"name": "ATP",
"type": "singles",
"race_ranking": false
},
{
"rank": 1,
"movement": 0,
"points": 7950,
"competitor_id": "sr:competitor:225050",
"name": "ATP",
"type": "singles",
"race_ranking": true
}
]
}5. Pull Standings for Round-Robin Play
For competitions with group phases, Season Standings returns one table per group with wins, losses, and qualification markers. The optional current_outcome appears on rows in a qualification position:
GET https://api.sportradar.com/tennis/{access_level}/v3/{language_code}/seasons/{season_id}/standings.{format}{
"generated_at": "2026-07-27T21:50:17+00:00",
"standings": [
{
"type": "total",
"groups": [
{
"id": "sr:league:100441",
"group_name": "A",
"standings": [
{
"rank": 1,
"played": 2,
"win": 2,
"loss": 0,
"competitor": {
"id": "sr:competitor:14657",
"name": "USA",
"country": "USA",
"country_code": "USA",
"abbreviation": "USA"
},
"current_outcome": "Playoffs",
"sets_won": 0,
"sets_lost": 0
},
{
"rank": 2,
"played": 2,
"win": 1,
"loss": 1,
"competitor": {
"id": "sr:competitor:14441",
"name": "Argentina",
"country": "Argentina",
"country_code": "ARG",
"abbreviation": "ARG"
},
"sets_won": 0,
"sets_lost": 0
},
{
"rank": 3,
"played": 2,
"win": 0,
"loss": 2,
"competitor": {
"id": "sr:competitor:14437",
"name": "Spain",
"country": "Spain",
"country_code": "ESP",
"abbreviation": "SPA"
},
"sets_won": 0,
"sets_lost": 0
}
]
}
]
}
]
}<?xml version="1.0" ?>
<season_standings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.sportradar.com/sportsapi/tennis/v3" generated_at="2026-07-27T21:53:19+00:00" xsi:schemaLocation="http://schemas.sportradar.com/sportsapi/tennis/v3 https://schemas.sportradar.com/sportsapi/tennis/v3/schemas/season_standings.xsd">
<season_standing type="total" round="1">
<groups>
<group id="sr:league:100441" name="United Cup 2026, Group A" live="false" group_name="A">
<stage order="1" type="league" phase="regular season" start_date="2026-01-01" end_date="2026-01-07" year="2026"/>
<standings>
<standing rank="1" played="2" win="2" loss="0" current_outcome="Playoffs" sets_won="0" sets_lost="0">
<competitor id="sr:competitor:14657" name="USA" country="USA" country_code="USA" abbreviation="USA"/>
</standing>
<standing rank="2" played="2" win="1" loss="1" sets_won="0" sets_lost="0">
<competitor id="sr:competitor:14441" name="Argentina" country="Argentina" country_code="ARG" abbreviation="ARG"/>
</standing>
<standing rank="3" played="2" win="0" loss="2" sets_won="0" sets_lost="0">
<!-- ... omitted for brevity -->
</standing>
</standings>
</group>
</groups>
</season_standing>
</season_standings>An empty standings array simply means the season has no group play or its groups have not started. Knockout seasons build from brackets instead.
Common Use Cases
- Rankings page: Rankings weekly, with
movementdriving up/down indicators. - Race tracker: Race Rankings through the season, highlighting the qualification cutoff line.
- Player card: Competitor Profile for the header, Rankings position for context.
- Group tables: Season Standings for team cups and finals groups, refreshed on match days.
Best Practices
- Refresh rankings on Mondays after publication, with a daily safety pull; the feeds serve 500 rows, so cache rather than re-pull per page view.
- Use
movementfrom the feed instead of computing deltas against your last pull; corrections would skew local math. - Treat
current_outcomeas optional: it appears only on rows in a qualification or elimination position. - For head-to-head displays alongside rankings, Competitor vs Competitor returns the pair's meeting history in one call.
Updated 1 day ago
