Quickstart
From an API key to live matches, odds, and a WebSocket stream in four steps.
This walks the full path a typical integration takes: authenticate, list what's live, pull the
market odds for a match, then (optionally) stream updates instead of polling. Every call is a plain
GET (or one POST for the WebSocket ticket) over HTTPS, and every response is the same
{ "data": ..., "meta": ... } envelope with snake_case fields.
1. Authenticate
Every request carries your key as a Bearer token. Create a key in the dashboard, then:
export EO_KEY="eo_live_..."
curl -H "Authorization: Bearer $EO_KEY" "https://api.esportsodds.gg/v1/cs2/matches?limit=1"See Authentication for the header, the deprecated ?apiKey= fallback, and
how keys are stored.
2. List live matches
curl -H "Authorization: Bearer $EO_KEY" \
"https://api.esportsodds.gg/v1/cs2/matches?status=live"{
"data": [
{
"id": "018f...e2a1",
"status": "live",
"format": "bo3",
"team_a_id": "018f...aa10",
"team_b_id": "018f...bb20",
"team_a_name": "Natus Vincere",
"team_b_name": "FaZe Clan",
"tournament_name": "IEM Katowice 2026",
"score_a": 1,
"score_b": 0,
"scheduled_at": "2026-07-01T18:00:00Z"
}
],
"meta": { "count": 1, "next_cursor": null }
}Narrow with status, tournament, team, and date_from/date_to; page with limit + cursor
(pass meta.next_cursor back as ?cursor=). Keep a match id for the next step.
3. Get the market odds
curl -H "Authorization: Bearer $EO_KEY" \
"https://api.esportsodds.gg/v1/cs2/odds?match=018f...e2a1"{
"data": [
{ "source": "eo_market", "outcome_key": "home", "label": "Natus Vincere", "price": 1.86, "book_count": 4, "match_id": "018f...e2a1", "captured_at": "2026-07-01T18:05:00Z" },
{ "source": "eo_market", "outcome_key": "away", "label": "FaZe Clan", "price": 1.98, "book_count": 4, "match_id": "018f...e2a1", "captured_at": "2026-07-01T18:05:00Z" }
],
"meta": { "count": 2, "next_cursor": null }
}Each line carries an explicit source: eo_market is the de-vigged multi-book line (with
book_count); eo_model is our modeled line once it clears validation. Add ?source=eo_market to
request just one. Contributing books are never named — see the methodology.
4. Stream updates instead of polling
For a live match, open the WebSocket channel and let updates come to you rather than re-polling steps 2–3 on a timer. It's a two-step ticket handshake so your key never appears in a socket URL:
curl -X POST -H "Authorization: Bearer $EO_KEY" \
"https://api.esportsodds.gg/v1/cs2/ws-token"
# → { "data": { "token": "eyJ...", "expires_at": "..." } }Open the socket, subscribe to the match, and you'll get a full snapshot followed by incremental
update frames. Every frame is a { type, match_id, seq, data } envelope:
const ws = new WebSocket(`wss://api.esportsodds.gg/v1/ws?token=${token}`)
ws.addEventListener('open', () => {
ws.send(JSON.stringify({ type: 'subscribe', data: { match_ids: ['018f...e2a1'] } }))
})
ws.addEventListener('message', (e) => {
const frame = JSON.parse(e.data)
if (frame.type === 'snapshot') setState(frame.match_id, frame.data) // full baseline
if (frame.type === 'update') applyUpdate(frame.match_id, frame.data) // a delta
})The full message types, sequence/reconnect semantics, and connection metering are covered in Live data & WebSocket.
Next steps
- Authentication · Rate limits · Errors
- The full interactive endpoint reference — with a "try it" panel per endpoint — is in the sidebar under API reference.