Authentication

Authenticate every request with an API key in the Authorization Bearer header.

Every request to the API is authenticated with an API key — an opaque token you create in your dashboard. Keys are validated on each request; there are no sessions, cookies, or OAuth flows.

Passing your key

Pass the key in the Authorization: Bearer header — the primary scheme:

curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://api.esportsodds.gg/v1/cs2/matches"

For callers that can't set a header, the apiKey query parameter is a supported fallback (the same convention the-odds-api.com uses):

curl "https://api.esportsodds.gg/v1/cs2/matches?apiKey=YOUR_API_KEY"

If both are present, the header wins. Either applies to every REST endpoint; the WebSocket channel instead uses a short-lived connection ticket minted from POST /v1/{game}/ws-token, so the raw key never appears in a socket URL.

Keep your key server-side. If you're building a browser or mobile client, proxy requests through your own backend rather than shipping the raw key to the client — the same way this site's public demo mints a short-lived connection token server-side instead of exposing its key.

Key format

Keys look like eo_live_ followed by 48 hex characters:

eo_live_4f3c1a08b27e59d6a41f0c8b3e7d2591ac6b04f8e1d37a52

The prefix is stable, so a secret scanner or a log filter can match on eo_live_[0-9a-f]{48}. A key is shown once, at creation — afterwards the dashboard displays only its prefix and last four characters, because the raw value is never stored (see below).

Rotating a key from the dashboard issues a replacement and leaves the old one working for a 24-hour grace period, so you can roll it through your deployments without downtime. After that window the old key 401s.

Calling from a browser

Requests from a browser are subject to CORS. The API allows a small, fixed set of origins — this documentation site among them, which is what makes the Send button on each endpoint's reference page work. Your own site's origin is not on that list, so a browser app should call the API through your own backend rather than directly. That's the right pattern anyway: it's the only way to keep your key off the client.

Where a browser does reach the API, Access-Control-Expose-Headers names every X-RateLimit-*/X-Quota-* header plus Retry-After, so a cross-origin fetch can read your remaining allowance rather than guessing at it.

How keys are stored

Only a SHA-256 hash of your key is stored — never the raw value. If you lose a key, rotate it from the dashboard; a compromised database never yields usable keys.

Missing or invalid keys

SituationResponse
No key provided (neither header nor apiKey)401 Unauthorized
Unknown or revoked key401 Unauthorized

The 401 body is deliberately identical for "no such key" and "revoked key" — the response never reveals which case occurred. See Errors for the body shape.

Usage & billing

Each authenticated request records a usage event against your key. Pricing is a single $99/mo plan (20,000 requests/month, no free tier) — see pricing. The monthly quota is enforced: past 20,000 requests in a calendar month the API responds 429 until the month resets (see Rate limits). Your current usage is visible in the dashboard and in the X-Quota-* headers on every response.

On this page