Error codes and handling are consistent across all 25+ sports APIs and all three API versions (V1, V2, V3).
{
"success" : false ,
"error" : {
"code" : "ERROR_CODE" ,
"message" : "Human-readable error description"
}
}
HTTP Status Codes
Status Description 200Success 400Bad Request — invalid parameters 401Unauthorized — invalid or missing API key 403Forbidden — access denied or account suspended 404Not Found — resource doesn’t exist 429Too Many Requests — daily rate limit exceeded 500Internal Server Error 503Service Unavailable — temporary outage
Common Errors
401 — Missing or Invalid API Key
{
"success" : false ,
"error" : {
"code" : "UNAUTHORIZED" ,
"message" : "Valid x-api-key header or Bearer token required"
}
}
Fix: Include the x-api-key header in every request:
curl -H "x-api-key: YOUR_API_KEY" \
"https://v2.football.sportsapipro.com/api/live"
429 — Rate Limit Exceeded
{
"success" : false ,
"error" : {
"code" : "RATE_LIMIT_EXCEEDED" ,
"message" : "Daily quota exceeded. Resets at midnight UTC."
}
}
Fix: Wait until reset, implement caching, or upgrade your plan. See Rate Limits .
404 — Resource Not Found
Returned when a match ID, team ID, or tournament ID doesn’t exist for that sport.
Fix: Verify the ID is correct and belongs to the sport you’re querying. Use /api/search to find valid IDs.
Error Handling Examples
const SPORTS = {
football: 'https://v2.football.sportsapipro.com' ,
basketball: 'https://v2.basketball.sportsapipro.com' ,
tennis: 'https://v2.tennis.sportsapipro.com' ,
baseball: 'https://v2.baseball.sportsapipro.com' ,
};
async function fetchSport ( sport , endpoint ) {
const response = await fetch ( ` ${ SPORTS [ sport ] }${ endpoint } ` , {
headers: { 'x-api-key' : process . env . SPORTSAPI_KEY }
});
if ( ! response . ok ) {
const data = await response . json (). catch (() => ({}));
const code = data ?. error ?. code || response . status ;
const msg = data ?. error ?. message || response . statusText ;
if ( response . status === 429 ) {
const reset = response . headers . get ( 'X-RateLimit-Reset' );
throw new Error ( `Rate limited. Resets at ${ reset } ` );
}
throw new Error ( ` ${ sport } API error ${ code } : ${ msg } ` );
}
return response . json ();
}
// Multi-sport with graceful degradation
async function fetchAllSports () {
const results = {};
for ( const sport of Object . keys ( SPORTS )) {
try {
results [ sport ] = await fetchSport ( sport , '/api/live' );
} catch ( err ) {
console . error ( ` ${ sport } : ${ err . message } ` );
results [ sport ] = null ;
}
}
return results ;
}
Retry Strategy
For transient errors (5xx), implement exponential backoff:
async function fetchWithRetry ( url , options , maxRetries = 3 ) {
for ( let attempt = 0 ; attempt < maxRetries ; attempt ++ ) {
try {
const response = await fetch ( url , options );
if ( response . status >= 500 ) throw new Error ( `Server error ${ response . status } ` );
return response ;
} catch ( error ) {
if ( attempt === maxRetries - 1 ) throw error ;
const delay = Math . pow ( 2 , attempt ) * 1000 ;
await new Promise ( r => setTimeout ( r , delay ));
}
}
}
Getting Help
Contact Support Get help from our team