Skip to main content

Troubleshooting Guide

This guide addresses common issues you may encounter when using SportsAPI Pro.

Empty or Missing Data

”Match statistics are empty”

Symptom: /api/match/{matchId}/statistics returns empty or minimal data Cause: Statistics are only populated during and after a match. Pre-match requests return empty objects. Additionally, stat types with zero values are omitted to reduce response size. Solution: Always check if the data exists before accessing:
Statistics are populated live during matches and finalized post-match. Pre-match requests will return empty data — this is expected behavior.

”Top players endpoint returns empty”

Symptom: /api/tournaments/{tournamentId}/seasons/{seasonId}/top-players returns empty data Cause: The tournament/season combination doesn’t have player ranking data available. This occurs for leagues outside the Premium and Full coverage tiers, or for cup competitions. Solution:
  1. Use /top-players only for major league competitions
  2. Verify you have the correct tournamentId and seasonId:
Tournaments with guaranteed top player data:
  • Premier League (ID: 17)
  • La Liga (ID: 8)
  • Bundesliga (ID: 35)
  • Serie A (ID: 23)
  • Ligue 1 (ID: 34)
  • Portugal Primeira Liga (ID: 238)
  • Eredivisie (ID: 37)
  • Champions League (ID: 7)
  • Europa League (ID: 679)

“Lineups missing detailed metrics”

Symptom: /api/match/{matchId}/lineups returns fewer stats than expected (e.g., no xG, limited passing data) Cause: Standard coverage leagues only include basic statistics. Detailed metrics like xG, tackles, and interceptions are only available for Premium tier competitions. Solution: For detailed metrics, query matches from Premium Coverage competitions:

Data Coverage Questions

”Why do some leagues have less data?”

Data completeness varies by competition tier due to data coverage levels:
Cup vs League Competitions: The /api/tournament/{id}/season/{seasonId}/top-players endpoint returns player rankings only for league competitions (seasonal cumulative stats). Cup competitions like Champions League, FA Cup, Copa del Rey may return empty results — use /api/match/{matchId}/lineups for match-level stats instead.
See our API Reference Overview for a complete breakdown of available endpoints and sports coverage, and Football Coverage for the full list of football competitions and how to pull it from the API.

”Sport X returns 404 — is it missing?”

A 404 on a sport almost always means the sport is not on the version you called, or the route name does not exist on that version. Not every version carries every sport. Working calls for the two most commonly reported ones:
Route names cannot be guessed. /schedule, /fixtures and /upcoming do not exist on V1 — its per-sport routes are live, all, current, competitions, countries, news and game/{id}. V3 windows are today, live, tomorrow, yesterday, all (there is no /matches/{date}). A 404 body always lists the valid alternatives for that version, so read it rather than trying variations.
GET https://api.sportsapipro.com/v6/football/reference/sports is the authoritative, quota-free list of which sport slugs exist on which version — call it once and drive your code from the result instead of hardcoding guesses.

”How do I know what data is available for a tournament?”

Use the tournament detail and seasons endpoints to explore what’s available:

“404 on /api/tournament/{id}/matches/{year}”

Symptom: Requests like /api/tournament/242/matches/2024 or /api/tournament/17/matches/24-25 return 404. Cause: There is no /matches/{year} shortcut. Season-scoped endpoints require a numeric seasonId resolved from /api/tournaments/{id}/seasons — never the human-readable year string. This trips up calendar-year leagues (MLS, Brazilian Série A) most often because "2024" looks like a valid path segment. Solution: Resolve the season first, then call the season-scoped endpoint:
See the Season IDs guide for full split-year vs calendar-year worked examples and a historical-match recipe.

”Cricket /rounds returns 404”

Symptom: GET /api/tournament/:id/season/:sid/rounds on cricket returns 404 — Upstream returned status 404. Cause: Cricket tournaments don’t use a round/matchday structure upstream — roundInfo on cricket events is empty, so there is no rounds list to return. Solution: Use these endpoints instead:
  • /api/tournament/:id/season/:sid/events/last/:page — paginated match list
  • /api/tournament/:id/season/:sid/standings — points table
  • /api/tournament/:id/season/:sid/knockout — playoff bracket
  • /api/match/:matchId/innings (or /scores) — full per-match scorecard

Authentication Issues

”401 Unauthorized”

Cause: Missing or invalid API key. Solution:
  1. Verify your API key is correct (check for typos)
  2. Ensure you’re using the x-api-key header (not Authorization)
  3. Check your API key hasn’t expired

”403 Forbidden”

Cause: Your subscription doesn’t include access to this endpoint or you’ve exceeded your daily limit. Solution:
  1. Check your plan’s included endpoints
  2. Verify your daily request quota
  3. Upgrade your plan if needed

”403 with Cloudflare error 1010 (browser_signature_banned)”

Cause: The request was refused by our edge protection before it reached the API, based on the User-Agent your HTTP client sent. This is not related to your plan, your API key or your quota — no request is metered, which is why the Live Demo keeps working and your remaining quota is untouched. The most common trigger is Python’s built-in urllib, which sends the default identifier Python-urllib/3.x when no User-Agent header is set. We are removing that specific Cloudflare rule because it blocks a harmless default client while doing no real bot protection — a User-Agent string is trivially spoofed, and our real security controls are API-key validation and per-key rate limits. Recommended solution: use a standard Python HTTP library and identify your client honestly. We recommend requests or httpx over urllib because they handle HTTPS, encoding, retries and timeouts more reliably.
If you must use urllib: set a truthful User-Agent instead of relying on the default.
requests, httpx and aiohttp all work with the API. Direct Python calls are supported on every plan, including Free. We do not require a browser-like User-Agent; a truthful application name is preferred.

Rate Limiting

”429 Too Many Requests”

Cause: You’ve exceeded the rate limit for your plan. Solution:
  1. Implement exponential backoff
  2. Cache responses where possible
  3. Use efficient polling patterns
See our Rate Limits documentation for plan-specific limits and optimization strategies.

Server Errors

Occasional 502, 503 or 504 on V2/V3/V6 endpoints

Cause: the upstream data layer occasionally answers slowly. Requests that exceed our upstream timeout are returned to you as 504 upstream_timeout, or as 503 / 502 when the upstream itself sheds the request. These are transient and affect a small fraction of calls; a repeat of the same request is normally served from cache within a second. They are not related to your API key, plan or quota — the request was authenticated and, because it never returned data, is not something you need to work around at the account level. Solution: retry once (or twice) with a short backoff, and treat any 5xx as retryable:
Use a client timeout of at least 30 seconds. A first request for a rarely-used resource is built on demand upstream and can take 10-20 seconds; the same request afterwards is fast.
Image delivery was given a much larger cache in September 2026 — a repeat request for the same team or competition logo now serves in about 2 ms. Fetch each logo once, store the bytes or the URL, and your import will neither be slowed by nor contribute to upstream load.

Schedule response has partial: true

Right after a server restart, /api/schedule/{date} can briefly return partial: true with a tournamentsPending count while caches warm up. This clears on its own within about 90 seconds; retry the request to get the full list.

Schedule for a future date returns 504 the first time

An uncached /api/schedule/{date} combines about 50 competitions and can time out (504) on the first call. Retry once after a few seconds; the second call normally returns the full list quickly.

404 on /statistics or /point-by-point for a specific match

This is a real answer, not a fault: the upstream feed has no statistics or point-level data recorded for that match. Lower-tier and qualifying matches frequently have no stats at all. A transient failure looks different — it returns 5xx, and a repeat succeeds. A 404 that repeats is permanent for that match.

Still Need Help?

Email Support

Contact our support team for personalized assistance
Last modified on September 25, 2026