Skip to content

Multi-bookmaker

A single connection can stream odds from any number of bookmakers. The SDK doesn’t merge them — every bookmaker’s view of a match is a separate SportEvent with its own id. This is intentional: you almost always want to compare them, not blend them.

When two bookmakers both report Lakers vs Celtics, your snapshot holds two distinct entries:

const events = [...client.snapshot().sportEvents.values()]
// Both Lakers vs Celtics, but one per bookmaker:
events
.filter(ev => ev.name === 'Los Angeles Lakers vs Boston Celtics')
.forEach(ev => console.log(`${ev.bookmaker}: ${ev.id}`))
// → ps3838: vmid:ps3838:1610547234
// → winamax: vmid:winamax:WIN-789012

Each carries its own markets, selections, prices, and update cadence.

event.bookmaker is a computed property derived from the id (vmid:<bookmaker>:<external_id>). You don’t need to parse the id yourself — read the field.

client.on('odds:changed', ({ bookmaker, sportEventId, quote }) => {
if (bookmaker === 'ps3838') {
// top-of-book quote from a sharp bookmaker
}
})
const ps3838Events = [...client.snapshot().sportEvents.values()]
.filter(ev => ev.bookmaker === 'ps3838')

Bookmaker is a TypeScript string-literal union — your editor autocompletes the valid values: 'ps3838' | 'winamax' | 'betclic' | …. See Bookmakers for the full list of currently supported sources.

Pairing same-match entries across bookmakers

Section titled “Pairing same-match entries across bookmakers”

The SDK does not match the same match across bookmakers — id, team names, and start dates can differ slightly between sources. If you want a unified “Lakers vs Celtics across the market” view, you build that mapping yourself, typically by:

  1. Indexing events by (competition, startDate.toISODate(), normalisedTeamPair).
  2. Joining entries that fall in the same bucket.

For competitions where the SDK guarantees stable competition codes (e.g. comp:basketball.nba), the pair (competition, startDate, normalisedTeamPair) is usually enough.

Three reasons:

  • Lossless — keeping the original entries means you never lose bookmaker-specific fields like matchUrl or order book depth.
  • Latency — merging would buffer updates from the slower source until the faster one catches up. We’d rather you see each tick when it happens.
  • Mapping is opinionated — what counts as “the same match” depends on your use case (arbitrage tolerates some looseness; settlement does not).

If we ever expose a unified view, it will be opt-in and additive — you’ll keep the per-bookmaker entries.