Games
Head to Head
Get head-to-head statistics, direct H2H matches, and recent form between two teams
GET
/
games
/
h2h
Head-to-Head
curl --request GET \
--url https://api.sportsapipro.com/v1/basketball/games/h2h \
--header 'x-api-key: <api-key>'import requests
url = "https://api.sportsapipro.com/v1/basketball/games/h2h"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.sportsapipro.com/v1/basketball/games/h2h', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sportsapipro.com/v1/basketball/games/h2h",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.sportsapipro.com/v1/basketball/games/h2h"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.sportsapipro.com/v1/basketball/games/h2h")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sportsapipro.com/v1/basketball/games/h2h")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_bodyEndpoint
GET https://api.sportsapipro.com/v1/football/games/h2h
Description
Returns comprehensive head-to-head data for a specific match, including:- Direct H2H matches (
h2hGames) - All historical meetings between the two teams - Recent form (
homeCompetitor.recentGames/awayCompetitor.recentGames) - Each team’s recent matches against any opponent - Betting odds - Available bookmakers and odds for the match
- Metadata - Competition, country, and sport information
Response Data Structure
Understanding the data structure is crucial for correctly displaying H2H information.
Key Data Locations
| Data Type | Location | Description |
|---|---|---|
| Direct H2H Matches | game.h2hGames[] | All matches where these two teams faced each other (past + scheduled) |
| Home Team Recent Form | game.homeCompetitor.recentGames[] | Home team’s recent matches vs any opponent |
| Away Team Recent Form | game.awayCompetitor.recentGames[] | Away team’s recent matches vs any opponent |
| Bookmakers & Odds | bookmakers[] | Available betting options |
| Competition Info | competitions[] | Competition metadata |
| Country Info | countries[] | Country metadata |
Common Mistake: Do NOT filter
recentGames to find H2H matches. Use h2hGames directly - it contains all direct meetings between the two teams.Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
gameId | number | Yes | The game identifier from game.id in fixtures/results |
matchupId | string | Yes | Matchup identifier from game.matchupId in fixtures/results |
timezoneName | string | No | Timezone for date/time values (auto-resolved, or specify e.g., America/New_York) |
All
startTime fields use ISO 8601 format with a dynamic timezone offset based on the resolved or specified timezone.matchupId Format
ThematchupId uses hyphens to separate IDs:
homeCompetitorId-awayCompetitorId(e.g.,"131-132")homeCompetitorId-awayCompetitorId-competitionId(e.g.,"131-132-7")
Team order does NOT matter. The API returns the same data for
14-106 and 106-14.matchupId exactly as returned from fixtures/results endpoints.
Request Examples
curl -X GET "https://api.sportsapipro.com/v1/football/games/h2h?gameId=4477087&matchupId=224-245-23" \
-H "x-api-key: YOUR_API_KEY"
const response = await fetch(
"https://api.sportsapipro.com/v1/football/games/h2h?gameId=4477087&matchupId=224-245-23",
{
headers: { "x-api-key": "YOUR_API_KEY" }
}
);
const data = await response.json();
// Access direct H2H matches
const h2hMatches = data.game.h2hGames;
// Access recent form
const homeForm = data.game.homeCompetitor.recentGames;
const awayForm = data.game.awayCompetitor.recentGames;
import requests
response = requests.get(
"https://api.sportsapipro.com/v1/football/games/h2h",
params={"gameId": 4477087, "matchupId": "224-245-23"},
headers={"x-api-key": "YOUR_API_KEY"}
)
data = response.json()
# Access direct H2H matches
h2h_matches = data["game"]["h2hGames"]
# Access recent form
home_form = data["game"]["homeCompetitor"]["recentGames"]
away_form = data["game"]["awayCompetitor"]["recentGames"]
Response Structure
{
"game": {
"id": 4477087,
"sportId": 1,
"competitionId": 23,
"seasonNum": 11,
"stageNum": 1,
"groupNum": 0,
"roundName": "Round",
"stageName": "Semi Finals",
"competitionDisplayName": "Supercoppa Italiana - Semi Finals",
"startTime": "2025-12-19T19:00:00+00:00",
"statusGroup": 4,
"statusText": "After Penalties",
"shortStatusText": "AP",
"gameTimeAndStatusDisplayType": 1,
"justEnded": false,
"gameTime": 120,
"gameTimeDisplay": "120'",
"hasLineups": true,
"hasMissingPlayers": false,
"hasFieldPositions": true,
"lineupsStatus": 2,
"lineupsStatusText": "Confirmed",
"hasTVNetworks": true,
"winDescription": "Bologna won after penalties",
"homeCompetitor": { /* Competitor Object */ },
"awayCompetitor": { /* Competitor Object */ },
"h2hGames": [ /* Array of H2H Game Objects */ ],
"isHomeAwayInverted": false,
"hasStats": true,
"hasStandings": true,
"hasBrackets": true,
"hasPreviousMeetings": true,
"hasRecentMatches": true,
"winner": 1,
"homeAwayTeamOrder": 1,
"hasNews": true,
"hasPointByPoint": false,
"hasVideo": true
},
"bookmakers": [ /* Array of Bookmaker Objects */ ],
"sports": [ /* Array of Sport Objects */ ],
"countries": [ /* Array of Country Objects */ ],
"competitions": [ /* Array of Competition Objects */ ]
}
Complete Response Fields Reference
Root Level Fields
| Field | Type | Description |
|---|---|---|
game | Object | Main game object containing all game details |
bookmakers | Array | List of available bookmakers with odds |
sports | Array | Sports information |
countries | Array | Country information |
competitions | Array | Competition information |
Game Object Fields
| Field | Type | Description |
|---|---|---|
id | Number | Unique game identifier |
sportId | Number | Sport type ID (1 = Football) |
competitionId | Number | Competition ID |
seasonNum | Number | Season number |
stageNum | Number | Stage number |
groupNum | Number | Group number |
roundName | String | Round name (e.g., “Round”) |
stageName | String | Stage name (e.g., “Semi Finals”) |
competitionDisplayName | String | Full competition name for display |
startTime | String | Game start time (ISO 8601 format with timezone offset based on auto-resolved or specified timezone) |
statusGroup | Number | Status group code (1 = Not Started, 2 = Scheduled, 3 = Live / In Progress, 4 = Ended, 5 = Cancelled, 6 = Postponed, 8 = Abandoned) |
statusText | String | Human-readable status (e.g., “After Penalties”) |
shortStatusText | String | Short status text (e.g., “AP”) |
gameTimeAndStatusDisplayType | Number | Display type indicator |
justEnded | Boolean | Whether game just ended |
gameTime | Number | Game time in minutes |
gameTimeDisplay | String | Formatted game time for display |
hasLineups | Boolean | Whether lineups are available |
hasMissingPlayers | Boolean | Whether there are missing players |
hasFieldPositions | Boolean | Whether field positions are available |
lineupsStatus | Number | Lineups status code |
lineupsStatusText | String | Lineups status text |
hasTVNetworks | Boolean | Whether TV networks are available |
winDescription | String | Description of the winner |
homeCompetitor | Object | Home team/competitor details |
awayCompetitor | Object | Away team/competitor details |
h2hGames | Array | Head-to-head historical games between the two teams |
isHomeAwayInverted | Boolean | Whether home/away is inverted |
hasStats | Boolean | Whether stats are available |
hasStandings | Boolean | Whether standings are available |
hasBrackets | Boolean | Whether brackets are available |
hasPreviousMeetings | Boolean | Whether previous meetings are available |
hasRecentMatches | Boolean | Whether recent matches are available |
winner | Number | Winner indicator (0 = draw/scheduled, 1 = home, 2 = away) |
homeAwayTeamOrder | Number | Team order indicator |
hasNews | Boolean | Whether news is available |
hasPointByPoint | Boolean | Whether point-by-point data is available |
hasVideo | Boolean | Whether video is available |
Competitor Object Fields
Used for bothhomeCompetitor and awayCompetitor.
| Field | Type | Description |
|---|---|---|
id | Number | Competitor ID |
countryId | Number | Country ID |
sportId | Number | Sport ID |
name | String | Competitor name |
symbolicName | String | Short symbolic name (e.g., “BOL”) |
nameForURL | String | URL-friendly name |
type | Number | Competitor type |
popularityRank | Number | Popularity ranking |
imageVersion | Number | Image version number |
score | Number | Current score |
isWinner | Boolean | Whether competitor is winner |
outcome | Number | Outcome code |
color | String | Primary color (hex) |
awayColor | String | Away color (hex) |
hasSquad | Boolean | Whether squad info available |
hasTransfers | Boolean | Whether transfer info available |
competitorNum | Number | Competitor number |
hideOnSearch | Boolean | Hide on search flag |
hideOnCatalog | Boolean | Hide on catalog flag |
mainCompetitionId | Number | Main competition ID |
recentGames | Array | Array of recent games (against any opponent) |
Recent Games / H2H Games Object Fields
Used for bothh2hGames[] and recentGames[] arrays.
| Field | Type | Description |
|---|---|---|
id | Number | Game ID |
sportId | Number | Sport ID |
competitionId | Number | Competition ID |
seasonNum | Number | Season number |
stageNum | Number | Stage number |
roundNum | Number | Round number |
roundName | String | Round name |
competitionDisplayName | String | Competition display name |
startTime | String | Start time (ISO 8601 with timezone offset) |
statusGroup | Number | Status group (1 = Not Started, 2 = Scheduled, 3 = Live / In Progress, 4 = Ended, 5 = Cancelled, 6 = Postponed, 8 = Abandoned) |
statusText | String | Status text |
shortStatusText | String | Short status |
gameTimeAndStatusDisplayType | Number | Display type |
odds | Object | Odds information |
homeCompetitor | Object | Home competitor (nested) |
awayCompetitor | Object | Away competitor (nested) |
outcome | Number | Game outcome |
extraData | Array | Extra data (scores, etc.) |
winner | Number | Winner indicator (1 = home, 2 = away, -1 = draw, 0 = scheduled) |
scores | Array | Score array [homeScore, awayScore] |
homeAwayTeamOrder | Number | Team order |
hasPointByPoint | Boolean | Point-by-point available |
hasVideo | Boolean | Video available |
Odds Object Fields
| Field | Type | Description |
|---|---|---|
lineId | Number | Odds line ID |
gameId | Number | Game ID |
bookmakerId | Number | Bookmaker ID |
lineTypeId | Number | Line type ID |
lineType | Object | Line type details |
link | String | Bookmaker link |
bookmaker | Object | Bookmaker details |
options | Array | Betting options |
outcomeOptionNum | Number | Outcome option number |
isConcluded | Boolean | Whether odds concluded |
Odds Option Fields
| Field | Type | Description |
|---|---|---|
num | Number | Option number |
name | String | Option name (1, X, 2) |
rate | Object | Odds rates |
bookmakerId | Number | Bookmaker ID |
originalRate | Object | Original odds rates |
link | String | Betting link |
trend | Number | Trend indicator |
isWon | Boolean | Whether this option won |
Rate Object Fields
| Field | Type | Description |
|---|---|---|
decimal | Number | Decimal odds format |
fractional | String | Fractional odds format |
american | String | American odds format |
Bookmaker Object Fields
| Field | Type | Description |
|---|---|---|
id | Number | Bookmaker ID |
name | String | Bookmaker name |
link | String | Bookmaker link |
nameForURL | String | URL-friendly name |
actionButton | Object | Action button details |
color | String | Brand color (hex) |
imageVersion | Number | Image version |
promotionText | String | Promotion text |
Competition Object Fields
| Field | Type | Description |
|---|---|---|
id | Number | Competition ID |
countryId | Number | Country ID |
sportId | Number | Sport ID |
name | String | Competition name |
longName | String | Long competition name |
hasStandings | Boolean | Has standings |
hasBrackets | Boolean | Has brackets |
hasStats | Boolean | Has statistics |
nameForURL | String | URL-friendly name |
popularityRank | Number | Popularity rank |
imageVersion | Number | Image version |
currentStageType | Number | Current stage type |
color | String | Competition color |
competitorsType | Number | Competitors type |
currentPhaseNum | Number | Current phase |
currentSeasonNum | Number | Current season |
currentStageNum | Number | Current stage |
isInternational | Boolean | Is international |
hasHistory | Boolean | Has history |
Complete Workflow Example
Step 1: Fetch Fixtures to Get Game and Matchup IDs
const fixturesResponse = await fetch(
"https://api.sportsapipro.com/v1/football/games/fixtures?competitions=9",
{ headers: { "x-api-key": "YOUR_API_KEY" } }
);
const fixtures = await fixturesResponse.json();
// Each game contains the IDs you need
const game = fixtures.games[0];
console.log({
gameId: game.id, // e.g., 4609057
matchupId: game.matchupId, // e.g., "14-106-9"
homeTeamId: game.homeCompetitor.id, // e.g., 14
awayTeamId: game.awayCompetitor.id // e.g., 106
});
Step 2: Call H2H Endpoint
const h2hResponse = await fetch(
`https://api.sportsapipro.com/v1/football/games/h2h?gameId=${game.id}&matchupId=${game.matchupId}`,
{ headers: { "x-api-key": "YOUR_API_KEY" } }
);
const h2hData = await h2hResponse.json();
Step 3: Access Direct H2H Matches
// Direct H2H matches are in h2hGames array
const directH2HMatches = h2hData.game.h2hGames;
console.log(`Found ${directH2HMatches.length} direct H2H matches`);
// Filter for completed matches only (statusGroup 4 = ended)
const completedH2H = directH2HMatches.filter(match => match.statusGroup === 4);
console.log(`${completedH2H.length} completed matches`);
Step 4: Access Recent Form for Each Team
// Recent matches for each team (against any opponent)
const homeTeamForm = h2hData.game.homeCompetitor.recentGames;
const awayTeamForm = h2hData.game.awayCompetitor.recentGames;
console.log(`Home team has ${homeTeamForm.length} recent matches`);
console.log(`Away team has ${awayTeamForm.length} recent matches`);
Common Use Cases
1. Calculate H2H Win/Draw/Loss Record
function calculateH2HRecord(h2hGames, homeTeamId, awayTeamId) {
// Filter for completed matches only
const completedMatches = h2hGames.filter(match =>
match.statusGroup === 4 && match.scores?.length >= 2
);
let homeWins = 0, awayWins = 0, draws = 0;
completedMatches.forEach(match => {
if (match.winner === 1) {
// Home team of THIS match won
if (match.homeCompetitor.id === homeTeamId) homeWins++;
else awayWins++;
} else if (match.winner === 2) {
// Away team of THIS match won
if (match.awayCompetitor.id === homeTeamId) homeWins++;
else awayWins++;
} else {
draws++;
}
});
return { homeWins, awayWins, draws, total: completedMatches.length };
}
// Usage
const record = calculateH2HRecord(
h2hData.game.h2hGames,
h2hData.game.homeCompetitor.id,
h2hData.game.awayCompetitor.id
);
console.log(`${record.homeWins} - ${record.draws} - ${record.awayWins}`);
2. Calculate Team Form (W/D/L String)
function calculateForm(recentGames, teamId, matchCount = 5) {
return recentGames.slice(0, matchCount).map(game => {
const isHome = game.homeCompetitor?.id === teamId;
const teamScore = isHome ? game.homeCompetitor?.score : game.awayCompetitor?.score;
const oppScore = isHome ? game.awayCompetitor?.score : game.homeCompetitor?.score;
if (teamScore > oppScore) return 'W';
if (teamScore === oppScore) return 'D';
return 'L';
});
}
// Usage
const homeForm = calculateForm(
h2hData.game.homeCompetitor.recentGames,
h2hData.game.homeCompetitor.id
);
console.log(`Form: ${homeForm.join('')}`); // e.g., "WWDLW"
3. Separate Scheduled vs Completed H2H Matches
const h2hGames = h2hData.game.h2hGames;
// Upcoming matches between these teams (statusGroup 1 = Scheduled)
const upcomingH2H = h2hGames.filter(match => match.statusGroup === 1);
// Live matches between these teams (statusGroup 2 or 3 = In progress)
const liveH2H = h2hGames.filter(match => match.statusGroup === 2 || match.statusGroup === 3);
// Completed matches between these teams (statusGroup 4 = Ended)
const completedH2H = h2hGames.filter(match => match.statusGroup === 4);
console.log(`${upcomingH2H.length} upcoming, ${liveH2H.length} live, ${completedH2H.length} completed`);
4. Calculate Goals Scored in H2H
function calculateH2HGoals(h2hGames, teamId) {
const completedMatches = h2hGames.filter(m => m.statusGroup === 4 && m.scores);
let goalsFor = 0, goalsAgainst = 0;
completedMatches.forEach(match => {
const isHome = match.homeCompetitor.id === teamId;
goalsFor += isHome ? (match.scores[0] || 0) : (match.scores[1] || 0);
goalsAgainst += isHome ? (match.scores[1] || 0) : (match.scores[0] || 0);
});
return { goalsFor, goalsAgainst, matches: completedMatches.length };
}
5. Get Most Recent N H2H Games
function getRecentH2H(h2hGames, count = 10) {
// Filter completed games, sort by startTime descending
return h2hGames
.filter(match => match.statusGroup === 4)
.sort((a, b) => new Date(b.startTime) - new Date(a.startTime))
.slice(0, count);
}
// Get last 10 H2H meetings
const recentH2H = getRecentH2H(h2hData.game.h2hGames, 10);
6. Filter H2H by Competition
function getH2HByCompetition(h2hGames, competitionId) {
return h2hGames.filter(match => match.competitionId === competitionId);
}
// Get only Serie A H2H matches
const serieAH2H = getH2HByCompetition(h2hData.game.h2hGames, 9);
Empty Response Scenarios
| Scenario | Cause | What to Display |
|---|---|---|
Empty h2hGames | Teams have never played each other | ”No previous meetings” |
Empty recentGames | New team or limited data | ”No recent match history” |
Only scheduled in h2hGames | No completed H2H yet | Show upcoming match, “First meeting” |
const h2hGames = h2hData.game.h2hGames || [];
const completedH2H = h2hGames.filter(m => m.statusGroup === 4);
if (h2hGames.length === 0) {
showMessage("These teams have never met");
} else if (completedH2H.length === 0) {
showMessage("First competitive meeting between these teams");
} else {
displayH2HHistory(completedH2H);
}
Rate Limiting & Caching
Each fixture requires a separate H2H call. Cache results to avoid hitting rate limits.
const h2hCache = new Map();
const CACHE_TTL = 60 * 60 * 1000; // 1 hour
async function getCachedH2H(gameId, matchupId, apiKey) {
const cacheKey = `${gameId}-${matchupId}`;
if (h2hCache.has(cacheKey)) {
const { data, timestamp } = h2hCache.get(cacheKey);
if (Date.now() - timestamp < CACHE_TTL) return data;
}
const response = await fetch(
`https://api.sportsapipro.com/v1/football/games/h2h?gameId=${gameId}&matchupId=${matchupId}`,
{ headers: { "x-api-key": apiKey } }
);
const data = await response.json();
h2hCache.set(cacheKey, { data, timestamp: Date.now() });
return data;
}
Common Issues & Solutions
| Issue | Cause | Solution |
|---|---|---|
400 Bad Request | Missing parameters | Include both gameId and matchupId |
401 Unauthorized | Invalid API key | Check x-api-key header |
404 Not Found | Invalid game ID | Verify gameId from fixtures |
Empty h2hGames | No historical meetings | Display “First meeting” message |
| Wrong scores | Using recentGames for H2H | Use h2hGames for direct meetings |
| Only 10 matches shown | Default pagination | All matches returned; handle in frontend |
Common Mistakes to Avoid:
- Don’t filter recentGames for H2H - Use
h2hGamesdirectly - Don’t assume all h2hGames are completed - Check
statusGroup === 4 - Don’t construct matchupId manually - Use value from fixtures
- Don’t ignore winner values -
0means scheduled,-1means draw
Complete Implementation Example
class H2HService {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.sportsapipro.com/v1/football';
}
async getH2H(gameId, matchupId) {
const response = await fetch(
`${this.baseUrl}/games/h2h?gameId=${gameId}&matchupId=${matchupId}`,
{ headers: { 'x-api-key': this.apiKey } }
);
return response.json();
}
analyzeH2H(h2hData) {
const homeTeam = h2hData.game.homeCompetitor;
const awayTeam = h2hData.game.awayCompetitor;
const h2hGames = h2hData.game.h2hGames || [];
// Completed H2H matches
const completedH2H = h2hGames.filter(m => m.statusGroup === 4);
// Upcoming H2H matches
const upcomingH2H = h2hGames.filter(m => m.statusGroup === 2);
// Calculate H2H record
const record = this.calculateRecord(completedH2H, homeTeam.id);
// Calculate goals
const homeGoals = this.calculateGoals(completedH2H, homeTeam.id);
const awayGoals = this.calculateGoals(completedH2H, awayTeam.id);
// Calculate form for each team
const homeForm = this.calculateForm(homeTeam.recentGames, homeTeam.id);
const awayForm = this.calculateForm(awayTeam.recentGames, awayTeam.id);
return {
homeTeam: homeTeam.name,
awayTeam: awayTeam.name,
h2hRecord: record,
totalMeetings: completedH2H.length,
upcomingMeetings: upcomingH2H.length,
homeGoals,
awayGoals,
homeForm,
awayForm,
recentH2H: completedH2H.slice(0, 5),
allH2H: h2hGames
};
}
calculateRecord(matches, homeTeamId) {
let homeWins = 0, awayWins = 0, draws = 0;
matches.forEach(match => {
if (match.winner === 1) {
match.homeCompetitor.id === homeTeamId ? homeWins++ : awayWins++;
} else if (match.winner === 2) {
match.awayCompetitor.id === homeTeamId ? homeWins++ : awayWins++;
} else {
draws++;
}
});
return { homeWins, awayWins, draws };
}
calculateGoals(matches, teamId) {
let goalsFor = 0, goalsAgainst = 0;
matches.forEach(match => {
if (!match.scores) return;
const isHome = match.homeCompetitor.id === teamId;
goalsFor += isHome ? match.scores[0] : match.scores[1];
goalsAgainst += isHome ? match.scores[1] : match.scores[0];
});
return { goalsFor, goalsAgainst };
}
calculateForm(recentGames, teamId) {
return recentGames.slice(0, 5).map(game => {
const isHome = game.homeCompetitor?.id === teamId;
const teamScore = isHome ? game.homeCompetitor?.score : game.awayCompetitor?.score;
const oppScore = isHome ? game.awayCompetitor?.score : game.homeCompetitor?.score;
if (teamScore > oppScore) return 'W';
if (teamScore === oppScore) return 'D';
return 'L';
}).join('');
}
}
// Usage
const h2hService = new H2HService('YOUR_API_KEY');
const h2hData = await h2hService.getH2H(4477087, '224-245-23');
const analysis = h2hService.analyzeH2H(h2hData);
console.log(analysis);
// {
// homeTeam: "Bologna",
// awayTeam: "Inter Milan",
// h2hRecord: { homeWins: 5, awayWins: 12, draws: 3 },
// totalMeetings: 20,
// upcomingMeetings: 1,
// homeGoals: { goalsFor: 18, goalsAgainst: 34 },
// awayGoals: { goalsFor: 34, goalsAgainst: 18 },
// homeForm: "LWDWW",
// awayForm: "WWWLW",
// recentH2H: [...],
// allH2H: [...]
// }
Authorizations
Your SportsAPI Pro API key
Query Parameters
First team ID
Example:
678
Second team ID
Example:
679
Number of historical games to return
Example:
10
Response
200
Head-to-head history retrieved successfully
Last modified on June 29, 2026
Was this page helpful?
⌘I
Head-to-Head
curl --request GET \
--url https://api.sportsapipro.com/v1/basketball/games/h2h \
--header 'x-api-key: <api-key>'import requests
url = "https://api.sportsapipro.com/v1/basketball/games/h2h"
headers = {"x-api-key": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'x-api-key': '<api-key>'}};
fetch('https://api.sportsapipro.com/v1/basketball/games/h2h', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.sportsapipro.com/v1/basketball/games/h2h",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.sportsapipro.com/v1/basketball/games/h2h"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-api-key", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.sportsapipro.com/v1/basketball/games/h2h")
.header("x-api-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.sportsapipro.com/v1/basketball/games/h2h")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-api-key"] = '<api-key>'
response = http.request(request)
puts response.read_body