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_4f3c1a08b27e59d6a41f0c8b3e7d2591ac6b04f8e1d37a52The 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
| Situation | Response |
|---|---|
No key provided (neither header nor apiKey) | 401 Unauthorized |
| Unknown or revoked key | 401 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.