Skip to main content
Rate limits are shared across all 25+ sports APIs. Your daily quota applies to your combined usage of Football, Basketball, Tennis, and every other sport.

Plan Limits

PlanDaily RequestsPrice
Free100$0
Pro7,500$15/mo
Ultra75,000$29/mo
Mega150,000$59/mo
All daily quotas reset at midnight UTC (00:00 UTC). The reset timestamp is included in every response via the X-RateLimit-Reset header.
Need more? Contact us for custom enterprise plans with higher limits, dedicated servers, and SLA guarantees.

Rate Limit Headers

Every API response includes rate limit headers:
HeaderDescription
X-RateLimit-LimitYour daily request limit
X-RateLimit-RemainingRequests remaining today
X-RateLimit-ResetISO 8601 timestamp when quota resets

Example Response Headers

HTTP/1.1 200 OK
X-RateLimit-Limit: 7500
X-RateLimit-Remaining: 7255
X-RateLimit-Reset: 2026-04-13T00:00:00.000Z
Content-Type: application/json

Checking Your Usage

Use the /status endpoint on any sport’s API:
curl -H "x-api-key: YOUR_API_KEY" \
  "https://v2.football.sportsapipro.com/status"
{
  "success": true,
  "api": "SportsAPI Pro - Football V2 (Enhanced)",
  "version": "v2",
  "account": {
    "email": "you@example.com",
    "name": "Your Name",
    "plan": "Pro",
    "member_since": "2025-01-15T10:30:00Z"
  },
  "usage": {
    "daily_limit": 7500,
    "remaining": 7255,
    "requests_today": 245,
    "reset_at": "2026-04-13T00:00:00.000Z"
  }
}

Rate Limit Exceeded

When you exceed your daily quota, the API returns 429 Too Many Requests:
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Daily quota exceeded. Resets at midnight UTC."
  }
}

Best Practices

Every API response includes a ttl field (seconds). Respect this value — the data won’t change before the TTL expires.
Data TypeTypical TTL
Live scores5s
Player stats60s
Standings300s
Countries list300s
const response = await fetch(url, { headers });
const data = await response.json();

// Cache for the recommended duration
const cacheDuration = data.ttl || 300; // seconds
cache.set(url, data, cacheDuration);
Check rate limit headers in every response:
function checkRateLimit(response) {
  const remaining = parseInt(response.headers.get('X-RateLimit-Remaining'));
  const limit = parseInt(response.headers.get('X-RateLimit-Limit'));
  const usagePercent = ((limit - remaining) / limit) * 100;
  
  if (usagePercent > 80) {
    console.warn(`Warning: ${usagePercent.toFixed(1)}% of daily quota used`);
  }
}
For 429 errors, wait and retry:
async function fetchWithRetry(url, options, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url, options);
    if (response.status !== 429) return response;
    
    const waitTime = Math.pow(2, i) * 1000;
    await new Promise(r => setTimeout(r, waitTime));
  }
  throw new Error('Rate limit exceeded — max retries reached');
}
During peak usage, prioritize live score updates over less time-sensitive data like standings or historical stats. Different sports have different update frequencies — NBA games have more scoring events than football matches.

What Counts as a Request?

  • Each API call counts as 1 request, regardless of sport
  • V2 image endpoint calls (/images/...) count as requests. V1 image endpoints are free and do not count
  • /status endpoint calls count as requests
  • WebSocket connections count initial connection as 1 request; subsequent messages do not count

Upgrading Your Plan

View Plans

Compare plan features and pricing

Contact Sales

Discuss custom enterprise solutions
Last modified on April 12, 2026