How do I get a tennis head-to-head record in Python?
Every meeting between two players with the score and sets, plus wins by surface and in finals.
Code verified October 10, 2026. One call to get_head_to_head, 3 credits.
The call
Both ids come from search_players.
import requests
import pandas as pd
API_KEY = "YOUR_API_KEY"
resp = requests.post(
"https://mcp.acesapi.com/v1/get_head_to_head",
headers={"x-api-key": API_KEY},
json={
"player_id": "3623",
"opponent_id": "3782",
},
timeout=60,
)
resp.raise_for_status()
data = resp.json()["data"]
names = {p["player_id"]: p["name"] for p in data["players"]}
print(data["summary"]["wins"], names)
print(pd.DataFrame(data["summary"]["by_surface"]).T)
matches = pd.DataFrame(data["matches"])
matches["winner"] = matches["winner_id"].map(names)
print(matches[["match_date", "tournament", "surface", "round", "winner", "score"]].head(8))
Replace YOUR_API_KEY with a key from your dashboard. Python needs requests and pandas (pip install requests pandas). JavaScript runs on Node 18 or newer, or in the browser.
What comes back
The data object of the response, trimmed to the first rows. Every field is real output from the run above.
{
"tour": "ATP",
"players": [
{
"player_id": "3623",
"name": "Jannik Sinner"
},
{
"player_id": "3782",
"name": "Carlos Alcaraz"
}
],
"summary": {
"matches": 17,
"wins": {
"3623": 7,
"3782": 10
},
"sets_won": {
"3623": 25,
"3782": 26
},
"by_surface": {
"clay": {
"3623": 2,
"3782": 3
},
"hard": {
"3623": 3,
"3782": 7
},
"grass": {
"3623": 2,
"3782": 0
}
},
"in_finals": {
"3623": 4,
"3782": 5
},
"walkovers": 0
},
"matches": [
{
"match_id": "173907",
"tournament": "Rolex Monte-Carlo Masters",
"season": 2026,
"surface": "clay",
"round": "Final",
"player1": "Carlos Alcaraz",
"player2": "Jannik Sinner",
"winner_id": "3623",
"score": "7-6(5) 6-3",
"sets": [
{
"set_no": 1,
"games1": 6,
"games2": 7,
"tiebreak1": 5,
"tiebreak2": 7,
"winner": 2
},
{
"set_no": 2,
"games1": 3,
"games2": 6,
"tiebreak1": null,
"tiebreak2": null,
"winner": 2
}
]
},
{
"match_id": "167710",
"tournament": "Nitto ATP Finals",
"season": 2025,
"surface": "hard",
"round": "Final",
"player1": "Carlos Alcaraz",
"player2": "Jannik Sinner",
"winner_id": "3623",
"score": "7-6(4) 7-5",
"sets": [
{
"set_no": 1,
"games1": 6,
"games2": 7,
"tiebreak1": 4,
"tiebreak2": 7,
"winner": 2
},
{
"set_no": 2,
"games1": 5,
"games2": 7,
"tiebreak1": null,
"tiebreak2": null,
"winner": 2
}
]
},
"...15 more"
]
}What to do next
- get_match (2 credits). One match in full: sets, tiebreak points, seeds, ratings and what the score says.
- get_surface_splits (3 credits). Each player's own record on the surface they meet on.
More guides
Start with 500 free credits every month
No card. REST or MCP.