Head-to-head endpoints

Rivalry records with surface, Grand Slam and finals splits, and multi-player matrices.

GET/tennis/h2h

Head-to-Head Rivalry Record

Calculates symmetric Head-to-Head match records, win-loss tallies, and surface splits.

ParameterInTypeDescription
player1_id*querystringFirst player ID
player2_id*querystringSecond player ID
surfacequerystringFilter by surface (Hard, Clay, Grass, Carpet)
levelquerystringFilter by tournament tier (G, M, A, F, D, C)
year_fromqueryintegerStart year
year_toqueryintegerEnd year
bash
curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.citoapi.com/api/v1/tennis/h2h?player1_id=atp_206173&player2_id=atp_207989"

Real response (HTTP 200), captured from the production API; long arrays cut to two items.

json
{
  "success": true,
  "player1": {
    "id": "atp_206173",
    "name": "Jannik Sinner",
    "ioc": "ITA",
    "current_rank": 1,
    "career_high_rank": 1,
    "wins": 7
  },
  "player2": {
    "id": "atp_207989",
    "name": "Carlos Alcaraz",
    "ioc": "ESP",
    "current_rank": 3,
    "career_high_rank": 1,
    "wins": 11
  },
  "summary": {
    "total_matches": 18,
    "player1_wins": 7,
    "player2_wins": 11,
    "player1_lead": -4,
    "finals_matches": 9,
    "player1_finals_wins": 4,
    "player2_finals_wins": 5,
    "grand_slam_matches": 6,
    "player1_grand_slam_wins": 2,
    "player2_grand_slam_wins": 4
  },
  "surface_breakdown": {
    "hard": {
      "player1_wins": 3,
      "player2_wins": 7,
      "total": 10
    },
    "clay": {
      "player1_wins": 2,
      "player2_wins": 4,
      "total": 6
    },
    "grass": {
      "player1_wins": 2,
      "player2_wins": 0,
      "total": 2
    },
    "carpet": {
      "player1_wins": 0,
      "player2_wins": 0,
      "total": 0
    }
  },
  "level_breakdown": {
    "grand_slam": {
      "player1_wins": 2,
      "player2_wins": 4,
      "total": 6
    },
    "masters_1000": {
      "player1_wins": 2,
      "player2_wins": 5,
      "total": 7
    },
    "tour_finals": {
      "player1_wins": 1,
      "player2_wins": 0,
      "total": 1
    },
    "atp_500_250": {
      "player1_wins": 2,
      "player2_wins": 1,
      "total": 3
    },
    "olympics_davis_cup": {
      "player1_wins": 0,
      "player2_wins": 0,
      "total": 0
    }
  },
  "format_breakdown": {
    "best_of_3": {
      "player1_wins": 5,
      "player2_wins": 7,
      "total": 12
    },
    "best_of_5": {
      "player1_wins": 2,
      "player2_wins": 4,
      "total": 6
    }
  },
  "tiebreak_record": {
    "player1_tiebreaks_won": 7,
    "player2_tiebreaks_won": 9,
    "total_tiebreaks": 16
  },
  "deciding_sets": {
    "player1_deciding_set_wins": 2,
    "player2_deciding_set_wins": 6,
    "total_deciding_sets": 8
  },
  "matches": [
    {
      "id": "atp_2026_0410_373",
      "date": "2026-04-05",
      "tournament_name": "Monte Carlo Masters",
      "surface": "Clay",
      "level": "M",
      "round": "F",
      "winner_id": "atp_206173",
      "winner_name": "Jannik Sinner",
      "score": "7-6(5) 6-3",
      "name": "Monte Carlo Masters",
      "starts_at": "2026-04-05T00:00:00+00:00"
    },
    {
      "id": "atp_2025_0605_385",
      "date": "2025-11-09",
      "tournament_name": "Tour Finals",
      "surface": "Hard",
      "level": "F",
      "round": "F",
      "winner_id": "atp_206173",
      "winner_name": "Jannik Sinner",
      "score": "7-6(4) 7-5",
      "name": "Tour Finals",
      "starts_at": "2025-11-09T00:00:00+00:00"
    }
  ]
}
GET/tennis/h2h/matrix

Multi-Player H2H Grid

Generates comparison grid matrix for a group of players.

ParameterInTypeDescription
player_ids*querystring[]Player IDs, either repeated (player_ids=a&player_ids=b) or comma-separated (player_ids=a,b), matching /players/batch
bash
curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.citoapi.com/api/v1/tennis/h2h/matrix?player_ids=atp_206173,atp_207989"

Real response (HTTP 200), captured from the production API; long arrays cut to two items.

json
{
  "success": true,
  "players": [
    {
      "id": "atp_206173",
      "name": "Jannik Sinner",
      "ioc": "ITA",
      "current_rank": null,
      "career_high_rank": null,
      "wins": 0
    },
    {
      "id": "atp_207989",
      "name": "Carlos Alcaraz",
      "ioc": "ESP",
      "current_rank": null,
      "career_high_rank": null,
      "wins": 0
    }
  ],
  "matrix": {
    "atp_206173": {
      "atp_206173": "-",
      "atp_207989": "7-11"
    },
    "atp_207989": {
      "atp_206173": "11-7",
      "atp_207989": "-"
    }
  }
}
GET/tennis/h2h/{player1_id}/{player2_id}

Head-to-Head (path form)

Path-parameter variant of /h2h for clients expecting /h2h/{a}/{b}.

ParameterInTypeDescription
player1_id*pathstring
player2_id*pathstring
surfacequerystringHard, Clay, Grass, Carpet
levelquerystringTier code: G, M, A, F, D, C
year_fromqueryinteger
year_toqueryinteger
bash
curl -H "x-api-key: YOUR_API_KEY" \
  "https://api.citoapi.com/api/v1/tennis/h2h/atp_206173/atp_207989"

Real response (HTTP 200), captured from the production API; long arrays cut to two items.

json
{
  "success": true,
  "player1": {
    "id": "atp_206173",
    "name": "Jannik Sinner",
    "ioc": "ITA",
    "current_rank": 1,
    "career_high_rank": 1,
    "wins": 7
  },
  "player2": {
    "id": "atp_207989",
    "name": "Carlos Alcaraz",
    "ioc": "ESP",
    "current_rank": 3,
    "career_high_rank": 1,
    "wins": 11
  },
  "summary": {
    "total_matches": 18,
    "player1_wins": 7,
    "player2_wins": 11,
    "player1_lead": -4,
    "finals_matches": 9,
    "player1_finals_wins": 4,
    "player2_finals_wins": 5,
    "grand_slam_matches": 6,
    "player1_grand_slam_wins": 2,
    "player2_grand_slam_wins": 4
  },
  "surface_breakdown": {
    "hard": {
      "player1_wins": 3,
      "player2_wins": 7,
      "total": 10
    },
    "clay": {
      "player1_wins": 2,
      "player2_wins": 4,
      "total": 6
    },
    "grass": {
      "player1_wins": 2,
      "player2_wins": 0,
      "total": 2
    },
    "carpet": {
      "player1_wins": 0,
      "player2_wins": 0,
      "total": 0
    }
  },
  "level_breakdown": {
    "grand_slam": {
      "player1_wins": 2,
      "player2_wins": 4,
      "total": 6
    },
    "masters_1000": {
      "player1_wins": 2,
      "player2_wins": 5,
      "total": 7
    },
    "tour_finals": {
      "player1_wins": 1,
      "player2_wins": 0,
      "total": 1
    },
    "atp_500_250": {
      "player1_wins": 2,
      "player2_wins": 1,
      "total": 3
    },
    "olympics_davis_cup": {
      "player1_wins": 0,
      "player2_wins": 0,
      "total": 0
    },
    "other": {
      "player1_wins": 0,
      "player2_wins": 1,
      "total": 1
    }
  },
  "format_breakdown": {
    "best_of_3": {
      "player1_wins": 5,
      "player2_wins": 7,
      "total": 12
    },
    "best_of_5": {
      "player1_wins": 2,
      "player2_wins": 4,
      "total": 6
    }
  },
  "tiebreak_record": {
    "player1_tiebreaks_won": 7,
    "player2_tiebreaks_won": 9,
    "total_tiebreaks": 16
  },
  "deciding_sets": {
    "player1_deciding_set_wins": 2,
    "player2_deciding_set_wins": 6,
    "total_deciding_sets": 8
  },
  "matches": [
    {
      "id": "atp_2026_0410_373",
      "date": "2026-04-05",
      "tournament_name": "Monte Carlo Masters",
      "surface": "Clay",
      "level": "M",
      "round": "F",
      "winner_id": "atp_206173",
      "winner_name": "Jannik Sinner",
      "score": "7-6(5) 6-3",
      "name": "Monte Carlo Masters",
      "starts_at": "2026-04-05T00:00:00+00:00"
    },
    {
      "id": "atp_2025_0605_385",
      "date": "2025-11-09",
      "tournament_name": "Tour Finals",
      "surface": "Hard",
      "level": "F",
      "round": "F",
      "winner_id": "atp_206173",
      "winner_name": "Jannik Sinner",
      "score": "7-6(4) 7-5",
      "name": "Tour Finals",
      "starts_at": "2025-11-09T00:00:00+00:00"
    }
  ]
}