Introduction
The BetVision product overlays contextual information, such as sports and betting information, inside the Genius Live Player. The goal of this document is to outline the following:
How the user can select a curated betting opportunity inside the video player and have the application betslip be populated with the selection or trigger placing a bet.
How Genius Sports can receive a curated list of live betting outcomes and their prices.
What native events the video player has to be able to listen to on mobile devices.
DMA enforcement and how this influences the user experience.
How the visuals inside the video player can be styled.
Integrating Prices
Providing prices and markets for the overlays
In order to push prices from the bookmaker to Genius Sports so that prices and markets in overlays can be repriced, added and removed in seconds, we supply the OddsFeed Platform Ingestion API with this https://swaggerui.api.geniussports.com/?url=https://explorer.api.geniussports.com/OddsFeed-Ingestion%2Fv1%2FProduction%2Fswagger-latest.yaml.
As a new customer you need to receive
an API key to push prices to the OddsFeed Platform Ingestion API
a sourceId for your prices
Please confirm that Genius Sports is able to match all the markets (with sourceMarketId), that you wish to push to the OddsFeed Platform Ingestion API.
Integrating Player
For integrating the Genius Live player please follow the Genius Live Player Integration Guide Documentation.
Handling Events
What is the Genius Sports message bus and how to integrate with it
The geniussportsmessagebus
is a messaging bus used to communicate information from our video player to other components of an integrating application, typically not controlled by Genius Sports, with the necessary information to react to a specific event.
To listen to events from the messagebus, clients should bind an event listener to the window
object, as shown below:
window.addEventListener('geniussportsmessagebus', (event) => { if (typedEvent.detail.type = 'an-event-type') { ... } else if (typedEvent.detail.type === 'another-event-type') { .... }
The event type that is dispatched onto the window object is a CustomEvent (MDN docs).
Video player event 'player_ready'
The existing video player integration relies on the 'player_ready'
event that the video player dispatches. This event is used to obtain a video streaming URL with an authentication token. All communication to and from the video player utilizes events.
More details: https://dap-docs.betstream.betgenius.com/ - How to integrate it.
Betslip interaction based on 'multibet-event'
The existing video player integration relies on an event named 'player_ready'
. Similarly, to facilitate interaction with the betslip, an event named 'multibet-event'
needs to be consumed.
window.addEventListener('geniussportsmessagebus', (event) => { if (typedEvent.detail.type = 'multibet-event') { ... } else if (typedEvent.detail.type === 'player_ready') { .... }
The ‘multibet-event' supports ‘addToBetslip’, ‘removeFromBetslip’, ‘placeBet’ and the 'openBetslip’ commands inside the body.
These commands are accessible in the body of the events raised by the video player.
if (typedEvent.detail.type = 'multibet-event') { switch(typedEvent.detail.body.command) { case "addToBetslip": ... break; case 'removeFromBetslip': ... break; case "placeBet": ... break; case "openBetslip": ... break; } } else ...
The data contained in the betslip command to "addToBetslip" | "removeFromBetslip"
is structured as follows:
interface BetslipEvent { command: "addToBetslip" | "removeFromBetslip", sportsbookFixtureId: string, marketId: string, sportsbookMarketId: string, sportsbookMarketContext: string, sportsbookSelectionId: string, decimalPrice: string, stake?: number //optional }
The following is an example of the structure of these events:
{ "command": "addToBetslip", "sportsbookFixtureId": "56789", "marketId": "100120022", "sportsbookMarketId": "1234567", "sportsbookMarketContext": "ABCDE", "sportsbookSelectionId": "2132365", "decimalPrice": "1.66", "stake": undefined }
The data contained in the betslip command to "placeBet"
is structured as follows:
interface BetslipEvent { command: "placeBet" , markets: [ { sportsbookFixtureId: string, marketId: string, sportsbookMarketId: string, sportsbookMarketContext: string, sportsbookSelectionId: string, decimalPrice: string, stake?: number //optional }, ] }
The following is an example of the structure of these events:
{ "command": "placeBet", "markets": [ { "sportsbookFixtureId": "56789", "marketId": "100120022", "sportsbookMarketId": "1234567", "sportsbookMarketId: "", "sportsbookMarketContext": "ABCDE", "sportsbookSelectionId": "2132365", "decimalPrice": "1.66", "stake": undefined }, { "sportsbookFixtureId": "56789", "marketId": "100120023", "sportsbookMarketId": "1234567", "sportsbookMarketContext": "ABCDE", "sportsbookSelectionId": "2132365", "decimalPrice": "1.32", "stake": undefined } ] }
sportsbookFixtureId
- customer fixture IDmarketId
- Genius Sports market IDsportsbookMarketId
- customer market IDsportsbookMarketContext
- customer market context. This field will be populated only if the customer provided it in UpdategramResponsesportsbookSelectionId
- customer selection IDdecimalPrice
- the price that was displayed in the Multibet Widget when the player pressed the "Add to betslip" button. This value should NOT be used for bet acceptance.An optional
stake
value which is can be one of the following values: a number, null, or undefined.
The data contained in the betslip command to "openBetslip"
is structured as follows:
interface BetslipEvent { command: "openBetslip" }
The following is an example of the structure of these events:
{ "command": "openBetslip" }
Tilting the native device and full screen
The video player is hosted inside a “webview” on the native device, which is controlled by the customer. Due to this the video player cannot receive certain native mobile device events, like device rotation.
To enable the end user switching from a traditional betting page layout to overlaid full screen streaming the hosting mobile application has to raise an event through the hosting “webview” into the Genius Live Video player. This requires development work from the bookmaker
Sample code how to allow fullscreen mode and traditional betting view based on user device tilt actions can be found in this repository:
Restrictions
Geographic Restrictions
Geo location for DMA’s
After consulting with several customers, we have determined that customers often don't have easy access to the viewer DMA since the user identity component of the application is frequently outsourced to third-party providers. Genius Sports will perform region detection and blocking on the edge. If a user is not in a DMA where they can view a fixture, the video player will never dispatch the 'player_ready'
event, and the player will not be visible. We would like to understand the preferred workflow from customers. If desired, Genius Sports can emit additional information about the user DMA to the hosting application.
Knowing in which DMA’s a fixture is viewable
An example DMA map where different fixtures are denoted by different colors. Viewers in the red and blue areas cannot watch the same fixture at the same time
We have made some additive changes to our Video API to indicate which DMA’s a fixture is available in. Notice the "dmas" : []
field
{ "data": [ { "id": 1300290721, "name": "Team A v Team B", "phase": "PRE_MATCH", "bookingStatus": "BOOKED", "startAt": "2021-07-29T13:00:00Z", "competitionId": "9530", "competitionName": "Test Comp", "sportId": 10, "sportName": "Football", "liveStreams": [ { "id": "c8ed9f88", "permissions": [ { "device": "MOBILE", "maxPlayerSizePercentage": 100, "region": "US_CA" }, { "device": "TABLET", "maxPlayerSizePercentage": 100, "region": "US_CA" } ], "dmas": [ { "dma": "753" }, { "dma": "771" }, { "dma": "800" }, { "dma": "802" }, { "dma": "804" }, { "dma": "807" }, { "dma": "811" }, { "dma": "813" }, { "dma": "825" }, { "dma": "828" }, { "dma": "855" }, { "dma": "862" }, { "dma": "866" }, { "dma": "868" } ], "deliveries": { "hls": [ { "id": "AKAMAI" } ], "dash": [] } } ] } ] }
Permitted Devices & Connectivity
CBS, FOX, NBC, ESPN/ABC and Amazon Games: Accessible on mobile phones and tablets, via wireless networks (e.g. 4G LTE, 5G) and WiFi.
NFL Network Games: Accessible solely on mobile phones via wireless networks and Wi-Fi.
Permitted Users
Limited to Active Bettors (as defined below) currently logged-in to the bookmaker account, and physically located in a state where betting on such account is legal and regulated.
“Active Bettor” means any registered user with an active betting account with the applicable operator (meaning such registered user
(A) has placed a bet with such operator within the immediately prior ten (10) months
and
(B) has (1) a payment mechanism (e.g., credit card) on file with such operator and/or (2) cash and/or credits available in such account to place wagers), and either of
(i) an active bet that includes the relevant Live Content being reviewed (e.g., a pre-match or in-play bet involving the Live Content or a player in the Live Content, including as part of a parlay bet); or
(ii) access to the Live Content for a promotional period if no bet has been placed (Genius and NFL shall have approval rights over the promotional period).
Use Restrictions
No simultaneous streams: Live Game streams must be limited to one stream at a time per Active Bettor account, i.e. No in-app multi-view.
Theming
Theming of video player controls
Documentation for Styling of the Genius Live player controls can be found here: https://dap-docs.betstream.betgenius.com/styling-genius-live-player.html
Theming the content in the video player
Genius Sports will take care of applying the desired themes to the overlays on behalf of customers. The theming of content will follow the same approach as outlined here.
Examples
An example of an Event listener loading the auth token and listening for betslip interaction
You need to have a listener to receive the events that the Multibet Widget will send when the player sends their bet in the "Add to betslip" action.
An example of how the code will look that listens to the video player events:
window.addEventListener('geniussportsmessagebus', async (event: Event) => { let typedEvent = event as unknown as GeniusSportsEvent if (typedEvent.detail.type = 'multibet-event') { switch(typedEvent.detail.body.command) { case "addToBetslip": /** * { * command: 'addToBetslip', * sportsbookMarketContext: tradingPlatformMetadata, * sportsbookFixtureId: tradingPlatformFixtureId, * sportsbookMarketId: tradingPlatformId, * marketId: id, * decimalPrice: totalOdds * } */ break; case "removeFromBetslip": break; case "placeBet": /** * { * command: 'placeBet', * sportsbookMarketContext: tradingPlatformMetadata, * sportsbookFixtureId: tradingPlatformFixtureId, * sportsbookMarketId: tradingPlatformId, * marketId: id, * decimalPrice: totalOdds, * stake: 100 * } */ } } else if (typedEvent.detail.type === 'player_ready') { const playerReadyEvent = typedEvent as PlayerReadyEvent const deliveryType = playerReadyEvent.detail.body.deliveryType const streamId = playerReadyEvent.detail.body.streamId const deliveryId = playerReadyEvent.detail.body.deliveryId const geniusSportsFixtureId = playerReadyEvent.detail.body.geniusSportsFixtureId const dataToPost = { endUserSessionId: document.cookie, //user session id region: 'CO', //region device: 'DESKTOP', //device } postData( `${domain}/v3/fixtures/${geniusSportsFixtureId}/live-streams/${streamId}/deliveries/${deliveryType}/${deliveryId}`, dataToPost ) .then((data) => { console.log('Token data arrived', JSON.stringify(data)) // @ts-ignore GeniusLivePlayer.player.start(data) }) .catch((error) => { console.error(error) }) } }) async function postData(url = '', data = { }) { // Default options are marked with * const response = await fetch(url, { method: 'POST', // *GET, POST, PUT, DELETE, etc. mode: 'cors', // no-cors, *cors, same-origin cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached credentials: 'include', // include, *same-origin, omit headers: { 'Content-Type': 'application/json', }, redirect: 'follow', // manual, *follow, error referrerPolicy: 'no-referrer', body: JSON.stringify(data), }) return response.json() }
Checklist
Checklist for Bookmaker client
Betting prices and markets
Push prices
- Received an API key to push prices to the Odds ingestion API.
- Received a Source ID for our prices.
- Genius Sports has confirmed to be able to match all the markets we as bookmaker wish to push.
Video Player and Front End
- We have integrated the normal video player.
- We have added the extra event handlers for listening to the “Add to Betslip” event.
- We have supplied the styling information for the overlays.