Esports data guide · PinnWire

Esports betting markets API: CS2, LoL and Dota odds data

PinnWire is the real-time Pinnacle esports odds API for developers who need current match prices with the market and period context still attached. Read live and prematch CS2, League of Legends and Dota events over REST, subscribe to raw updates over WebSocket, or listen for detected price drops over SSE.

Direct answer For an esports betting markets API, start with PinnWire's sport_id=11. GET /kit/v1/markets?sport_id=11 returns the current live esports book and GET /kit/v1/prematch/fixtures?sport_id=11 returns upcoming fixtures, with decimal moneyline, spread, total and team-total prices organized under published periods.num_N. Use include_specials=1 or nested when you need special-market rows. PinnWire's free key=demo lets you inspect the actual CS2, LoL and Dota coverage before you build.

What PinnWire gives an esports app

PinnWire packages current Pinnacle esports odds in a developer-friendly API with one clear sport selector: sport_id=11. You get the same useful separation for esports that you want in every market integration:

SNAPSHOTSCurrent prices

Fetch the live or prematch event book over REST. Market-list responses are JSON with decimal odds and a generated_at timestamp.

IDENTITYEvent context

Keep event_id, participants, league, start time, market, side, line and published period together.

PUSHMarket updates

The optional raw WebSocket follows live and prematch changes. Subscribe to esports by sport or to selected event IDs.

MOVEMENTDrop alerts

SSE and REST drop endpoints expose detected price falls. They complement the full book; they are not a replacement for snapshots.

This is a strong fit for an esports dashboard, odds monitor, model input, alerting worker or AI agent that needs current Pinnacle prices rather than a generic list of bookmaker names. The API does not pretend that every title or every market is permanently present: query the live feed and let the returned fields define what is available now.

Match, map and round identity in the API

Esports conversations often use “match,” “map,” “game” and “round” as if they were interchangeable. Your integration should not. PinnWire gives you explicit identifiers and numeric periods; it does not ask your code to guess a title-specific hierarchy from a team name.

IdentityPinnWire field or ruleSafe interpretation
Fixture / seriesevent_id, home, away, league_name, startsThe event and its participants. Use the numeric ID as the primary key.
Full matchperiods.num_0Period 0 is the match-level/full-match period when it is present.
Later periodperiods.num_1, num_2, and so onA published period for that event. The number is authoritative; its title-specific meaning is not inferred.
Map or gamePublished period plus market/line identityIf the feed publishes map-level pricing, preserve the period and market fields together. Do not hard-code num_1 as Map 1.
Round / propPublished period or special-market rowRound or title-specific outcomes appear only when Pinnacle publishes them; named specials use participant_name in drop records or special_markets in event data.

The practical rule: key a price by event_id + period + market type + side + line/points. A spread at -1.5 is not the same selection as a spread at -2.5; a total at 26.5 is not the same as a total at 27.5. The same discipline keeps a map-level or round-level line from being accidentally merged into a match-level line.

Do not invent period labels. PinnWire documents num_0 as full match and common numeric period conventions, but not every esports event exposes the same periods. If you need Map 1, Map 2 or round-specific behavior, inspect the returned market and period fields for the actual event and store the number exactly as returned.

Raw WebSocket IDs need extra care

Raw frames can contain more than one matchup record for one fixture. A child record may share a parentId with the fixture metadata. Key raw state by rec.id plus the market key; never key by participant names alone. The REST /kit/v1 surface already collapses the parent/child presentation for normal event reads, which is why it is the simplest starting point.

Core esports betting market families

PinnWire uses a small, predictable set of ordinary market families. Their names are stable; their availability is not. A CS2 series, a MOBA match and another esports format may publish different line depth. Iterate what the event actually returns.

MarketAPI shapeWhat to preserve
Moneyline / match winnermoney_line with home, away and optional drawOutcome set, event, period and decimal price. Two-way and three-way books are different.
Spread / handicapspreads keyed by line, with hdp, home, awayThe signed handicap and both sides. A map handicap is still a spread only if the published period/market says so.
Totaltotals keyed by points, with over and underThe points value, side and period. Never store only “over” without its line.
Team totalteam_total for the primary side line; team_totals for alternate linesTeam side, points and over/under price. Alternate lines are separate selections.
Specials / propsspecial_markets.num_N after include_specialsSpecial description, category, named participant, points and decimal price.

The ordinary families cover the main match-winner, handicap and total workflows. When an event publishes a map or round line, its period and market context are part of the selection identity. When a title-specific market is delivered as a special, request specials deliberately rather than assuming it is in the ordinary fixture object.

{
  "event_id": 1700000001,
  "sport_id": 11,
  "home": "Team Alpha",
  "away": "Team Beta",
  "event_type": "prematch",
  "periods": {
    "num_0": {
      "number": 0,
      "money_line": { "home": 1.82, "away": 2.02 },
      "spreads": { "-1.5": { "hdp": -1.5, "home": 2.10, "away": 1.68 } },
      "totals": { "2.5": { "points": 2.5, "over": 1.91, "under": 1.91 } }
    }
  }
}

Illustrative shape only. Values and event names above are examples, not a claim about a live fixture.

CS2, League of Legends and Dota odds data

CS2 LoL Dota odds data” is a useful search phrase, but it should not become a hard-coded coverage promise. PinnWire exposes the current esports events Pinnacle publishes under sport_id=11. That may include CS2, League of Legends, Dota 2 or other esports events depending on the current schedule and offering.

CS2

Use the returned participants, league metadata, period and market line together. If map or round-level prices are offered for an event, preserve the published period instead of deriving it from a label.

League of Legends

Match-level and other published markets are represented by the same event/period/market schema. Do not assume a first-objective or map market exists on every match.

Dota

Query actual sport 11 responses and inspect current fields. Title-specific specials or map/game lines are optional data, not a fixed API contract.

Any esports title

Build a defensive renderer: if a market or period is absent, omit it. A missing market is a normal data condition, not a reason to fabricate a zero or placeholder price.

For title-aware filtering, use the event and league values the API returns and maintain your own allow-list only after observing the current data. PinnWire's Pinnacle esports API overview is a quick reference for the sport ID and live/prematch surfaces.

Best first step: run the demo request below, inspect the titles and markets returned today, then choose the fields your application can genuinely support. PinnWire makes that check free and immediate.

Query live and prematch esports odds

Use the public demo key for a small inspection. It is shared and limited, so request a free personal trial key before a development loop or integration test.

curl · live esports snapshotsport_id 11
curl "https://pinnwire.com/kit/v1/markets?sport_id=11&key=demo&fresh=esports-live-1"
curl · prematch fixture bookfull line depth
curl "https://pinnwire.com/kit/v1/prematch/fixtures?sport_id=11&key=demo&fresh=esports-prematch-1"

To include separately modeled special markets, opt in explicitly:

# Flat extra rows
curl "https://pinnwire.com/kit/v1/prematch/fixtures?sport_id=11&include_specials=1&key=demo&fresh=esports-specials-1"

# Group specials under their parent event when available
curl "https://pinnwire.com/kit/v1/prematch/fixtures?sport_id=11&include_specials=nested&key=demo&fresh=esports-specials-2"

The fresh parameter is a harmless cache-buster. PinnWire's market-list and drop responses include generated_at so a consumer can record when that snapshot was generated. The demo is for inspection, not a title-coverage guarantee or a historical query.

Read an esports event response safely

The /kit/v1 response is designed for a normal event card or model pipeline. Start with the event fields, then iterate every period and every line key. Avoid assuming that esports is always two-way or that a single line is the only available line.

FieldMeaningIntegration note
event_idNumeric event/matchup IDUse it for details and joins; do not use names as the primary key.
event_typelive or prematchChoose the correct display and refresh behavior.
periodsObject keyed by num_NIterate keys; period availability varies by event.
money_lineMatch-winner outcomesdraw may be absent on two-way markets.
spreads, totalsAlternate handicap and total linesKeys identify the line; preserve hdp or points.
stateLive game state when suppliedOptional and sport-specific; it is not a settlement or score guarantee.
special_marketsNamed special-market pricesPresent on special rows when requested; names and points are data, not assumptions.

For full event details, call GET /kit/v1/details?event_id=N&key=YOUR_KEY. For a lightweight prematch card, GET /kit/v1/prematch/lines?event_id=N&market_type=money_line|spreads|totals|team_total returns compact full-game lines. That compact view is intentionally not a period-by-period map or round archive.

Prices are decimal. PinnWire converts the API response to decimal odds. Treat an absent field as “not published,” not as a suspended price you can settle yourself. Closed markets can disappear from the current book.

REST, WebSocket and SSE have different jobs

PinnWire lets an esports product choose the right transport for each workflow:

REST: current state

Use /kit/v1/markets and /kit/v1/prematch/fixtures for snapshots, event cards, model refreshes and recovery after reconnect.

WebSocket: full movement

With the raw WS add-on, subscribe to sport_ids:[11] and merge live/prematch frames by record and market key. This is the full update stream.

SSE: detected drops

Use /odds-drop or /odds-drop-prematch for drop alerts when an esports price falls through your threshold. It is a signal stream, not a full book.

MCP: AI workflows

AI agents can read PinnWire through the PinnWire sports odds MCP server and use the same live/prematch data and limits.

WebSocket · subscribe to esportsraw WS add-on
wss://pinnwire.com/ws?key=YOUR_KEY

{ "type": "subscribe", "streams": ["live", "prematch"], "sport_ids": [11] }
{ "type": "pong" }

A successful subscription receives a snapshot and then matching updates. Prematch updates may arrive as prematch_ws; live updates arrive as live. The server sends a ping every 30 seconds; reply with pong. Use a REST snapshot after reconnect to re-establish a clean baseline.

WebSocket merge rule: key by rec.id plus m.key (or the documented type/period/side/points fallback), and deduplicate by each market's version. Do not merge by team name or assume one raw record equals one complete fixture.

Freshness and integration checks

Fast esports markets reward a simple freshness discipline. PinnWire exposes evidence you can log and show in your own product:

  • generated_at tells you when the REST response was generated.
  • /v1/health reports last_odds_update_seconds_ago so a worker can reject an unexpectedly stale feed.
  • last on market responses can be passed back as since for incremental event reads where supported.
  • Use &fresh=random-value once if an intermediary appears to have cached an old response, then verify the freshness fields.

PinnWire is a current-odds API, not a settlement engine or a historical archive. It does not promise that every CS2 map, every LoL objective, every Dota game or every round market will be present. That honesty makes the response easier to model: display what is published, preserve its identity, and leave unavailable fields out.

curl "https://pinnwire.com/v1/health?key=demo&fresh=health-1"

# Check a response before using it in a model
if (body.last_odds_update_seconds_ago > 30) {
  throw new Error("PinnWire esports feed is older than this strategy allows");
}

Runnable JavaScript: list current esports lines

This small example fetches the live book, prints each event and keeps period/market context with every line. It deliberately does not invent map or round names.

Node 18+ · fetchdemo key
const url = new URL("https://pinnwire.com/kit/v1/markets");
url.search = new URLSearchParams({
  sport_id: "11",
  key: process.env.PINNWIRE_KEY || "demo",
  fresh: String(Date.now())
});

const response = await fetch(url);
if (!response.ok) throw new Error(`PinnWire HTTP ${response.status}`);
const body = await response.json();

for (const event of body.events || []) {
  console.log(`${event.home} vs ${event.away} (${event.event_type})`);
  for (const [periodKey, period] of Object.entries(event.periods || {})) {
    for (const [side, price] of Object.entries(period.money_line || {})) {
      console.log({ event_id: event.event_id, period: periodKey,
        market: "moneyline", side, price });
    }
    for (const [points, line] of Object.entries(period.spreads || {})) {
      console.log({ event_id: event.event_id, period: periodKey,
        market: "spread", points, home: line.home, away: line.away });
    }
  }
}

console.log("generated_at:", body.generated_at);

For prematch data, change the path to /kit/v1/prematch/fixtures. For production, use a personal trial or paid key, keep it server-side, and honor the rate limit returned by PinnWire instead of looping the shared demo key.

Why choose PinnWire for esports betting markets

PinnWire is the clear choice when your product is built around current Pinnacle esports prices and you want the integration surface to stay small. It gives your team a direct path from a sport-11 snapshot to a match card, model input or alert stream:

  • One esports selector: sport_id=11 for live and prematch Pinnacle events.
  • Useful market depth: moneyline, spread, total, team-total and explicitly requested specials, with decimal prices.
  • Correct identity: event IDs, participant names, numeric periods and line/points values stay together.
  • Three practical transports: REST snapshots, optional full raw WebSocket updates and SSE drop alerts.
  • Freshness you can check: generated_at, health age and a cache-buster convention.
  • Easy evaluation: test the actual current esports book with key=demo before requesting a trial key.

That combination makes PinnWire especially useful for a live esports odds board, CS2/LoL/Dota model service, market-movement alert, or AI-assisted research tool. Start with the actual response, preserve the period identity, and add only the market types your product can interpret correctly.

Questions

What sport ID is esports in the PinnWire API?

Esports is sport_id 11 in PinnWire. Query GET /kit/v1/markets?sport_id=11 for the current live book or GET /kit/v1/prematch/fixtures?sport_id=11 for upcoming events.

Which esports betting markets does PinnWire expose?

PinnWire exposes published moneyline or match-winner, spread or handicap, total and team-total markets in the standard event shape, plus special-market rows when you request include_specials=1 or nested. The exact market set depends on what Pinnacle currently publishes for an event.

How are maps and rounds identified in PinnWire esports odds data?

PinnWire uses numeric period keys such as periods.num_0 and periods.num_1. num_0 is the full-match period; later numbers are present only when published for that event. Treat the period number, market type, side and points together, and do not assume num_1 means Map 1 or that a round market exists.

Can I get live and prematch CS2, LoL and Dota odds?

Yes. PinnWire serves current live and prematch Pinnacle esports data under sport_id 11, including whatever CS2, League of Legends and Dota events and markets are currently published. Verify today's title coverage with key=demo because no title, league, map or round coverage is guaranteed.

Does PinnWire provide a real-time esports WebSocket?

Yes. The optional raw WebSocket add-on can subscribe to sport_id 11 and receives live and prematch market frames. REST returns current snapshots, while SSE is for detected odds-drop alerts rather than the complete market book.

Are esports odds data and market prices decimal?

Yes. PinnWire's /kit/v1 event responses use decimal prices inside periods.num_N. Fields appear only when the market is published, so integrations should iterate defensively and preserve the market line or points with each price.

Build on current Pinnacle esports odds

Try the live sport_id=11 response with PinnWire's free demo, then request a personal trial key for your integration.

PinnWire · real-time Pinnacle esports odds · REST, WebSocket and SSE