Skip to main content
Error codes and handling are consistent across all 25+ sports APIs and all three API versions (V1, V2, V3).

Error Response Format

{
  "success": false,
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable error description"
  }
}

HTTP Status Codes

StatusDescription
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
Last modified on April 12, 2026