Skip to main content

API Key Authentication

Odds-API.io uses API key authentication to secure access to the API. Your API key identifies your account and tracks your usage.

Getting Your API Key

  1. Sign up for a trial at odds-api.io
  2. Check your email for the API key
  3. Copy and securely store your API key
Keep your API key secure! Never share it publicly, commit it to version control, or expose it in client-side code.

Using Your API Key

Include your API key as a query parameter in all authenticated requests:
https://api.odds-api.io/v3/events?apiKey=YOUR_API_KEY&sport=football
curl "https://api.odds-api.io/v3/events?apiKey=YOUR_API_KEY&sport=football"

Security Best Practices

Use Environment Variables

Store your API key in environment variables instead of hardcoding it:
ODDS_API_KEY=your_api_key_here

Server-Side Only

Never expose your API key in client-side JavaScript code. Always make API calls from your backend server.
Bad Practice:
// ❌ DON'T DO THIS - API key exposed in browser
const apiKey = 'a7f3k9m2p5q8r1t4w6x9z2b5c8';
fetch(`https://api.odds-api.io/v3/events?apiKey=${apiKey}`);
Good Practice:
// ✅ Use a backend proxy
// Frontend
const response = await fetch('/api/odds/events');

// Backend (Node.js/Express)
app.get('/api/odds/events', async (req, res) => {
  const apiKey = process.env.ODDS_API_KEY;
  const response = await fetch(
    `https://api.odds-api.io/v3/events?apiKey=${apiKey}&sport=football`
  );
  const data = await response.json();
  res.json(data);
});

Rotate Keys Regularly

For enhanced security:
  • Rotate your API keys periodically
  • Generate separate keys for development and production
  • Immediately revoke compromised keys

Rate Limiting

API requests are rate-limited based on your subscription plan:
PlanRequests per HourAdditional Packages Available
Starter5,000+10K/20K/30K per hour
Growth5,000+10K/20K/30K per hour
Pro5,000+10K/20K/30K per hour
Additional Request Packages:
  • +10K requests/hour: £139/month
  • +20K requests/hour: £229/month
  • +30K requests/hour: £309/month
  • Custom volumes available on request

Monitoring Rate Limits

The API returns rate limit information in response headers with every request:
x-ratelimit-limit: 99999999
x-ratelimit-remaining: 99999862
x-ratelimit-reset: 2025-10-03T18:07:41Z
  • x-ratelimit-limit: Total requests allowed in the current window
  • x-ratelimit-remaining: Requests remaining in the current window
  • x-ratelimit-reset: ISO 8601 timestamp when the rate limit resets
When you exceed the rate limit, you’ll receive a 429 Too Many Requests response:
{
  "error": "Rate limit exceeded. Please try again later."
}

Best Practices for Rate Limiting

  1. Monitor response headers to track your usage and remaining requests
  2. Implement exponential backoff when you receive 429 errors
  3. Cache responses when appropriate to reduce API calls
  4. Use the multi-odds endpoint to fetch odds for multiple events in a single request
async function fetchWithRetry(url, maxRetries = 3) {
  for (let i = 0; i < maxRetries; i++) {
    const response = await fetch(url);

    // Log rate limit info
    console.log('Rate limit:', response.headers.get('x-ratelimit-remaining'),
                '/', response.headers.get('x-ratelimit-limit'));
    console.log('Resets at:', response.headers.get('x-ratelimit-reset'));

    if (response.status === 429) {
      const resetTime = new Date(response.headers.get('x-ratelimit-reset'));
      const waitTime = Math.max(resetTime - Date.now(), Math.pow(2, i) * 1000);

      console.log(`Rate limited. Waiting ${waitTime}ms...`);
      await new Promise(resolve => setTimeout(resolve, waitTime));
      continue;
    }

    return response.json();
  }

  throw new Error('Max retries exceeded');
}

Error Responses

The API uses standard HTTP status codes:
Status CodeDescription
200Success
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing API key
403Forbidden - API key doesn’t have access
404Not Found - Resource doesn’t exist
429Too Many Requests - Rate limit exceeded
500Internal Server Error
All errors return a JSON response with an error message:
{
  "error": "Invalid API key provided"
}

Next Steps

I