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.

On this page