Risk Services Integration

 

Introduction

Risk Services (GTS) is an operational service that Genius Services Group (GSG) offers to its customers (trading platforms or bookmakers). It is a combination of Outsourced Trading (OST) with Risk Management by GSG's operational staff. For the bookmaker, their prices are continuously adjusted not only according to the match state but also according to a particular fixture's liabilities.

In order to provide GTS services, the bookmaker must provide a continuous stream of bets that come into their system.

There are two APIs built for this purpose:

  • Bet Assessment API - before a bet is placed, it checks the current status, price, and liability levels against preconfigured liability limits to suggest whether the bet should be accepted or rejected. For InPlay bets, it also includes the configured bet delay timespan.

  • Bet Feed Receiver API - after a bet is confirmed, it receives the Bet States and provides them to Risk Services. Confirmed, unsettled bets count towards the liability values that are then used to assess new bets.

Bet Assessment and Bet Feed Receiver APIs needs to be set up on Genius Sports side for the specific customer and that could take up to 2 weeks from the time when the integration is agreed.

Overall GTS integration data flow requirements:

  1. [OPTIONAL] Non-Genius Sports content (fixtures/markets/selections) is sent to GTS using our OddsFeed Platform Ingestion API. See Risk Services Integration | Non Genius Sports content for more information.

  2. Before the bet is placed, the bet assessment request is sent to the Bet Assessment API to know if the bet should be accepted or rejected.

    1. If there is no bet delay applied, then the assessment result is returned in the Bet Assessment API response.

    2. If there is a bet delay applied then the Bet Assessment API returns the bet status delayed and the assessment result is returned via Ably messaging after the configured bet delay value (see Appendix D for how to receive Ably messages).

  3. If the bet is rejected by the assessment and it is not placed then no further actions are required.

  4. If the bet is accepted and placed, then it needs to be sent to GTS using the Bet Feed Receiver API.

  5. If the bet state or any leg state of the already placed bet changes, then the update needs to be sent to GTS using Bet Feed Receiver API.

System Bet Types Definitions

It is very important to understand the concept of the System Bet Type Definition we use to describe system bet types in data contracts below. Please see Appendix A for a list of system bet types we support at the moment.

In the case of Single, Multi, and System bets, the bet is represented by a number of legs.

A Single is a bet that has only one leg.

For a Multi Bet (which is a bet that has multiple legs) to win, each of the supplied legs must win.

A System Bet is also a bet that has multiple legs, but in addition to them, it has a set of variable-length combinations of these legs. Each combination can win, and for any individual combination to win, each of its legs must win. A System Bet may therefore contain both winning and losing combinations.

To define these combinations, we use an array of numbers that refer to the number of legs in the combination. Let's take a bet with 3 legs - A, B, and C.

  1. If we want to define a system bet as a combination of two legs (doubles), i.e. AB, AC, and BC, we use [2]. We call it "BXMUL-2L" in Appendix A.

  2. If we want all possible combinations (singles, doubles and trebles), i.e. A, B, C, AB, AC, BC, and ABC we use [1, 2, 3]. We call it “PATENT” in Appendix A.

Bet Assessment API

Overview

Swagger documentation https://docs.uat.risk.api.geniussports.com/#/Resources/BetAssessment

The primary purpose of the Bet Assessment API is to assess the risk of each incoming bet and reserve some amount of the current player’s liability.

In the response, the API provides the results of the checks against selection status, price, liability, and bet delay if applicable.

For each incoming bet, it provides an answer to the following questions:

  • [OPTIONAL] Is it safe for the bookmaker to accept this bet, based on the current selection status and price?

    • priceChangeRule property needs to be sent with the assessment request to have selections status and price checked as a part of the assessment. Further details are given in Risk Services Integration | Root object

    • The price change tolerance is configurable per customer (bookmaker). It is a price change in percentage. For example if the price is changed from 1.91 to 1.77 then the change is 7.33%. Please contact your Genius Sports Customer Integration Manager for the initial set up of the price change tolerance.

  • Is it safe for the bookmaker to accept this bet, based on current liability and limits on player and selection(s)?

  • What is the maximum stake that can be placed on this bet based on the current price, liability, and limits on player and selection(s)?

  • In the case of InPlay betting, how long should I artificially delay acceptance of the bet? The exact behavior depends on the customer’s integration option:

    • OPTION 1 - Bet delay handled by the customer, only HTTP REST API Integration

      • The configured suggested bet delay is returned in the assessment response betDelay property, and it is up to the customer's system to implement the delay or decide not to. The customer should check the market and selection status and price after the suggested bet delay and if it is changed then they should send a new assessment request with the new price.

    • OPTION 2 - Bet delay handled by GTS, HTTP REST API, and Messaging Integration

      • The configured bet delay is implemented as part of the bet assessment process and is handled by GTS. In addition to returning the bet delay value in the assessment response, the bet delay is already implemented on our side. When the bet is delayed, then the REST API assessment response has the betAssessmentResult = AssessmentDelayed and the bet assessment result is returned via Ably messaging after the configured bet delay value.

    • The Bet Delay value is configured in the GTS by Genius Sports risk analysts. It is possible to configure it on different levels (sport, competition, fixture, market).

  • The detailed explanation of the assessment process is described here GTS Bet Assessment Calculations.

The API only notifies the customer’s system if a bet should be rejected, because of the selection status and price check or due to the liability threshold being breached. It is up to the customer’s system to reject the bet (or decide to accept it anyway).

If the bet is accepted, then it should then be posted to the Bet Feed Receiver API signifying that the bet has now been confirmed.

If the bet is rejected, the sportsbook platform can optionally release the reserved liability. Please read the section below entitled Liability Reservation for further details.

Once a bet has been confirmed, it should not be re-submitted for Assessment. Doing so will return a 422 (Unprocessable Entity) response.

The Assessment endpoint is an HTTP REST API that expects to receive data in JSON format, as a body of an HTTP POST request.

The assessment service supports a maximum of 50 legs in regular multi bets and a maximum of 16 legs in system bets.

Bet Assessment Request

Root object

Property 

Type 

Required 

Explanation 

Comments 

Property 

Type 

Required 

Explanation 

Comments 

betId 

string (50)

Required 

A unique identifier for the bet.

 

playerId 

string (50)

Required 

A unique identifier for the player placing the bet.

 

totalStake 

decimal 

Required 

The total stake of the bet. 

 

currencyCode

string (3)

Required

The ISO 4217 code of the stake’s currency

The currency of the stake.

systemBetType 

string (50)

Optional 

Identifies the type of the System Bet, see Appendix A: Supported System Bet Types definitions for a list of supported system bet types.

A required field for system bets.

If the bet has multiple legs and this field is not populated, we assume this bet is a Multi Bet.

Please, also, check the Appendix B: Fallback scenarios to define a bet type for liability calculations section below

legs 

An array of Leg (see below)

Required 

Details of the bet. 

 

priceChangeRule

string (50)

Optional

Property to determine what type of price change is allowed. Used for OPTION 2 - Bet delay handled by GTS, HTTP REST API, and Messaging Integration

Possible values:

  • AcceptAny - if the selection price, or all selections prices in a multi or system bet, are the same or changed in any direction within the configured threshold then accept the bet if it does not breach any liability limits.

  • AcceptHigher - if the selection price, or all selections prices in a multi or system bet, are the same or have become higher within the configured threshold then accept the bet if it does not breach any liability limits.

  • AcceptNone - if the selection price, or any selection price in a multi or system bet, changes then do not accept the bet.

If this property is not defined, there will be no price check made and the assessment is done only against the current liability and limits on player and selection(s).

Leg

Property 

Type 

Required 

Explanation 

Comments

selectionId 

string (200)

Required 

A unique identifier for the outcome of the market. It needs to be unique for the entire service per bookmaker.

 

In case of GeniusSports content this must match with the selectionId in betgeniusContent property sent to Bet Feed Receiver once the bet is confirmed.

In case of non GeniusSports content this must match with the selection id sent to OddsFeed Platform Ingestion API and the selectionId in BookmakerContent property sent to Bet Feed Receiver once the bet is confirmed.

price 

decimal 

Required 

The odds for the selection. Decimal prices - up to 5 decimal places.

Values with more than 5 decimal places will be truncated.

Example: Price of 5.5547878 will be truncated to 5.55478.

gameState 

string (10)

Required 

Whether the leg is for an InPlay or PreMatch market, supported values: [“PreMatch“/”InPlay”]. 

Markets could have different liability limits for PreMatch and InPlay, so we need to know what was the game state at the time of the bet placement.

Bet Assessment Successful Response

Root object

Property 

Type 

Required 

Explanation 

isBetAllowed

boolean 

Required 

Whether the bet should be accepted or rejected.

Possible values:

  • true

  • false

In the case of using bet delay handled in GTS version:

  • If the bet is delayed (betAssessmentResult = AssessmentDelayed) then isBetAllowed = false is the initial response to the HTTP assessment request and the final result of the request is delivered via Ably after the configured bet delay value.

In case if betAssessmentResult property is present, its value supersedes the isBetAllowed value, i.e. isBetAllowed should be ignored in this case

maxAllowedStake 

decimal 

Optional 

This value signifies the maximum total stake for the bet that will not breach the limits. maxAllowedStake is not rounded and is correct to at least 10 significant figures. It is the responsibility of the caller to round this value down to their nearest minimum unit size (e.g. cent, penny, satoshi, Wei). Be careful not to round-up as a bet re-submitted with a rounded-up stake may still break limits and be subsequently rejected.

betDelay

string (8)

Optional  

The timespan in “HH:mm:ss” format, e.g. “00:01:15“ which means 0 hours, 1 minute and 15 seconds.

Returned for bets where at least one leg has gameState = “InPlay”.

This bet delay is set in Risk Services Templates by our Risk Operational Team, and the value will be greater than 0.

betId

string (50)

Optional 

A unique identifier for the bet.

betAssessmentResult

string (50)

Optional 

The result of bet assessment for delayed assessments when the bet delay is applied on GTS assessment service.

If the value is AssessmentDelayed, the assessment will be delayed and the result will be delivered via Ably.

Possible values:

  • BetAllowed

  • BetRejected

  • AssessmentDelayed

rejectReason

rejectReason (see below)

Optional

Nullable property with code and description of bet rejection reason.

If defined, the rejection reason is not related to the specific leg, e.g. maximum allowed stake limit is breached

If not defined, the rejection reason is specific to some leg(s), e.g. liability limit is breached for selection

legs 

An array of LegAssessment (see below)

Optional 

Details of the bet leg(s) assessment. 

LegAssessment

Property 

Type 

Required 

Explanation 

selectionId 

string (200)

Optional  

A unique identifier for the outcome of the market. It needs to be unique for the entire service per bookmaker.

 

price 

decimal 

Optional  

The most up-to-date price of the selection of the leg.

selectionStatus

string (10)

Optional  

The most up-to-date status of the selection of the leg.

Possible values:

  • Open

  • Suspended

  • Closed

rejectReason

rejectReason (see below)

Optional

A leg-level property with code and description of the leg rejection reason, see details below.

rejectReason

Property 

Type 

Required 

Explanation 

reasonCode

string (50) 

Optional 

An extensible list of possible rejection reasons.

Possible values

  • PriceChanged

  • SelectionClosed

  • SelectionSuspended

  • LiabilityLimitBreached

  • UserLimitBreached

  • LimitNotSet

  • MaxStakeBreached

reasonMessage

string (500) 

Optional 

Description of the rejection reason.

Examples

Requests

Single bet without price change property

{ "betId": "1234", "playerId": "Someone", "totalStake": 10.5, "currencyCode": "EUR", "legs": [ { "selectionId": "331114", "price": 1.04, "gameState": "PreMatch" } ] }

Single bet with price change property

{ "betId": "1234", "playerId": "Someone", "totalStake": 10.5, "currencyCode": "EUR", "legs": [ { "selectionId": "331114", "price": 1.04, "gameState": "PreMatch" } ], "priceChangeRule": "AcceptAny" }

Multi bet without price change property

{ "betId": "1234", "playerId": "Someone", "totalStake": 10.5, "currencyCode": "EUR", "legs": [ { "selectionId": "331114", "price": 1.04, "gameState": "PreMatch" }, { "selectionId": "55449309", "price": 1.5, "gameState": "InPlay" } ] }

Multi bet with price change property

System bet without price change property

Notice that this bet has multiple legs and the systemBetType field was specified.

System bet with price change property

Responses:

PreMatch single bet accepted with price change check

PreMatch single bet accepted without price change check

PreMatch single bet rejected due to price change more than allowed

PreMatch multi bet accepted with price check

PreMatch multi bet accepted without price check

PreMatch multi bet rejected due to selection closed

PreMatch system bet accepted with price check

PreMatch system bet accepted without price check

PreMatch system bet with price check rejected due to selection liability limit breached

InPlay single bet with price check accepted

InPlay single bet without price check accepted

InPlay single bet rejected due to selection suspended

InPlay multi bet with price check accepted

InPlay multi bet without price check accepted

InPlay multi bet with price check rejected due to player liability limit breached

InPlay system bet with price check accepted

InPlay system bet rejected due to maximum stake breached

InPlay single bet delayed

InPlay multi bet delayed

InPlay system bet delayed

Bet Assessment Failed Responses

Status code

Status name

Description

Status code

Status name

Description

401

Unauthorized

A request was made without a valid token in the Authorization header.

403

Forbidden

A request was made without a valid API Key in the x-api-key header.

422

Unprocessable entity

The format of the POST body was invalid and could not be processed. Resubmitting the same request will fail in the same manner.

503

Service unavailable

The Bet Assessment is unavailable and cannot accept requests. This would normally be a transient condition, so resubmitting the same request should eventually result in success.

500

Unexpected error

This covers all other non-success conditions. Generally, this would be a transient condition, so resubmitting the same request should eventually result in success, although there may be conditions under which that is untrue so the request should not be resubmitted indefinitely.

Liability Reservation

A player may attempt to place multiple bets on the same selection in quick succession in order to exceed any limits the bookmaker has placed on them. In order to manage this case, when any unconfirmed bet is sent for assessment we assume that the bet will shortly be placed, and store the associated liability in the system as a reserved liability. This reserved liability is then counted along with the player’s confirmed bets in order to assess any further bets by that player. Therefore the player will not be able to breach their limits simply by placing multiple similar bets in quick succession.

Once a bet is confirmed, the reserved liability becomes an actual liability. In terms of bet assessment and liability calculation, nothing will change since the bet was already considered to have been placed.

If a bet is rejected by the customer’s sportsbook platform, however, we will still be holding the reserved liability from the rejected bet and thus it still counts towards the player’s liability totals. Now we have the opposite problem - the player may try to place a new valid bet, yet be rejected by bet assessment since the rejected bet’s liability is still reserved in the system.

How is the Reserved Liability released in the case of a Rejected Bet?

There are two ways in which Reserved Liability is released for Rejected Bets:

  • The bookmaker can explicitly release the reservation by calling the bet-reservation-cancellations endpoint of the Bet Assessment API with the bet identifier in the POST body, as in the example below. Explicitly releasing reservations of rejected bets is preferred, but is optional because of the following:

    • Bets that were reserved more than 30 seconds ago are no longer counted.

  • If a bet reservation cancellation request for the original bet that was rejected is sent:

    • Then sending the same assessment request with the reduced stake, which is equal or less than maxAllowedStake, receives a "isBetAllowed": true response.

  • If no bet reservation cancellation request is sent for the original bet that was rejected:

    • Then re-sending the same assessment request with the same betId and reduced stake, which is equal or less than maxAllowedStake, receives a "isBetAllowed": true response.

    • Then re-sending the same assessment request in 30 seconds with a different betId and reduced stake, which is equal or less than maxAllowedStake, receives a "isBetAllowed": false response, because the liability of the original bet is still reserved and counted towards this player’s liability.

  • Bet Reservation Cancellation endpoint: https://{CUSTOMERNAME}-risk-assessment-api.{ENVIRONMENT}.riskmanagement.geniussports.com/api/v{VERSION}/bookmakers/{bookmakerId}/bet-reservation-cancellations

Example

Bet Feed Receiver API

Overview

Swagger documentation https://docs.uat.risk.api.geniussports.com/#/Resources/SendBets

Once bets have been confirmed as placed or the status of the already placed bet is changed then the request should be sent to the Bet Feed Receiver. This is an HTTP REST API that expects to receive bet data in JSON format, as a body of an HTTP POST request.

Data flow requirements

  • The bookmaker’s bets must be delivered to the API within 5 seconds of their placement. Violating this requirement may lead to outdated liability values, thus incorrect Bet Assessment API responses.

  • Timestamps are required for sequencing during peak betting loads.

  • If the state of the bet changes, the full updated bet state should be resubmitted to the Bet Feed Receiver.

  • It is required to resubmit the bet if any of the bet legs was settled or cancelled.

  • It is required to populate a Bet's Payout field for fully settled bets (all legs are settled) and fully cancelled bets (the whole bet is cancelled).

  • For Multi and System Bets it is important to resubmit the bet state when any of the legs are settled, with the new Leg Status and its PayoutPrice. Updates should be sent until all legs of the multi and system bet have been settled.

  • The sender is responsible for the retry of failed API calls.

API URL parameters

For platforms with support for multiple bookmakers, for each bookmaker GSG will provide a numeric identifier to be used in the integration (bookmaker ID).

In the case of a platform integration, the API URL will look like this: https://<bet_feed_receiver_api_hostname>/api/v{api_version}/bookmakers/{bookmaker_id}/bets

Where {api_version} represents a version of the API and {bookmaker_id} is a placeholder for a specific bookmaker ID, e.g. if the platform sends bet for a bookmaker called “geniusbookmaker”, which is assigned to bookmaker ID 5, the URL should be https://<bet_feed_receiver_api_hostname>/api/v1/bookmakers/5/bets

Data contract

Root object (bet)

Property 

Type

Required 

Explanation 

Comments 

id 

string (50)

Required 

A unique identifier for the bet. It needs to be unique for the entire service per bookmaker.

When using Risk Services with Bet Assessment, make sure that both use the same bet identifier.

betPlacedTimestampUTC 

DateTime

Required

UTC Timestamp of when the bet was placed .

Please use the format "yyyy-MM-ddTHH:mm:ss.ffffZ". Details are here.

Initial value should stay the same for every other update.

betUpdatedTimestampUTC 

DateTime 

Required 

UTC Timestamp of the change trigger, i.e. when the bet data changed.

Determines whether this call is the latest state for the Bet, based on existing data.

Please use the format "yyyy-MM-ddTHH:mm:ss.ffffZ". Details are here.

bookmakerName

string (50)

Required

Name of the bookmaker

 

playerId 

string (50)

Required 

A unique identifier for the player placing the bet.

 

totalStake 

decimal 

Required 

The total stake of the bet.

This must only contain the original stake of the bet. In the case of Cash Out or Partial Cash Out, please update the cashedOutTotalStake and cashedOutAmount properties. 

currencyCode

string (3)

Required

The ISO 4217 code of the stake’s currency

The currency of the stake.

systemBetType 

string (50)

Optional 

Identifies the type of the System Bet, see Appendix A: Supported System Bet Types definitions for a list of supported system bet types.

A required field for system bets. This should be empty for Single/Multi bets.

If the bet has multiple legs and this field is not populated, we assume this bet is a Multi Bet.

Please, also check the Appendix B: Fallback scenarios to define a bet type for liability calculations section below.

priority 

number 

Optional 

The priority with which a bet should be processed. Can be 1 (High Priority) or 2 (Low Priority) .

This is used to route messages into a high-priority processing queue. The bookmaker determines which bets are high-priority, and passes the priority into the API.

If not supplied, defaults to low priority.

legs 

An array of Leg (see below)

Required 

Details of the bet.

 

status

string (50)

Required 

Current status of the bet.

Supported values: ["Open"/"Settled"/“Cancelled“]

“Open” represents a bet with any legs that are currently Open.

“Settled” is when all legs have been settled. 

“Cancelled” is when the whole bet is cancelled.

If the bet has been fully cashed-out, you should set the bet status to “Settled”. If the bet has only been partially cashed-out, you should set the bet status to “Open”.

cashedOutTotalStake 

decimal 

Optional 

The amount of the original total stake that has been cashed out.

For example, if the cashedOutTotalStake is 20.00 and the original totalStake was 80.00, then 20.00 of the original 80.00 was cashed out.  Therefore, the currently remaining total stake of the bet is 60.00. A bet may be partially cashed out one or more times, and the cashedOutTotalStake must be the cumulative value. 

cashedOutAmount 

decimal 

Optional 

The total amount paid out for the cashed out total stake.  

 

payout 

decimal 

Optional 

The total settlement amount of all legs.

A required field for fully settled and fully cancelled bets.

 

Only sent upon bet settlements, so not required in the contract. 

Let's say that there is a Multi bet with 3 legs: A, B, C. Each leg is resulted at different times since the majority of the fixtures finish at different times. So, let's say that leg B was resulted as a loser. Then the entire bet is a loser, and Legs A and C would probably not be resulted by a settlement engine.  

Until a bet has lost legs, all won legs are going to be settled.  

Let's assume that leg A had a price of 1.20, leg B had a price of 2.0, and leg C had a price of 3.0, and the player bets 10 EUR. 

If the entire bet wins fully, the player would get 1.20 * 2 * 3 = 7.2 → 72. Therefore the payout field should be set to 72.

When the whole bet is cancelled (“Bet Status” = “Cancelled”) then “Payout” should be equal to initial Stake of the bet.

Leg

Individual component of a bet. Multiples and System bets will have more than one leg.

Property 

Type 

Required 

Explanation 

Comments 

price

decimal 

Required 

The odds for the selection. 

 

gameState 

string (10)

Required 

Whether the leg is for an InPlay or PreMatch market, supported values: [“PreMatch“/”InPlay”]. 

Markets could have different liability limits for PreMatch and InPlay, so we need to know what was the game state at the time of bet placement.

status 

string (50)

Required 

Current status of the bet leg, supported values: ["Open"/"Settled"/"Cancelled"].

Represents the status of the current leg.  

“Open” - the bet was placed, the result of the leg’s market is still unknown.

“Settled“ - the result of the leg’s market is known and the bet was settled.

“Cancelled“ - the bet was cancelled for any reason and does not bear any risk for a bookmaker, thus should be excluded from liability calculations.

betgeniusContent

BetGeniusContent (see below)

Required

Betgenius content ids and names.

The betgeniusContent field is only required when the content for that leg was provided by Genius Sports.

bookmakerContent

BookmakerContent (see below)

Required

Bookmaker’s content ids and names.

Always required.

payoutPrice 

decimal 

Optional 

The payout price for this leg.

A required field for settled legs.

This value should be set only once the status of the leg is known, in other words, once the leg has been settled (resulted) and is no longer active.

If the leg wins, payoutPrice will be the same as the Price the leg was struck at. However, there may be cases such as dead heat, refund, partial push, etc. where payoutPrice is less than the maximum amount. Additionally, if the Leg loses, payoutPrice must be set to 0.

In this example, payoutPrice was 50% of the Struck Price - it may have been a 2-way dead heat, for example.

If payoutPrice is absent or NULL, it means the leg is still active. Any actual amount in the Leg's payoutPrice property means the leg is no longer active.

Although this value is optional. if supplied it will enable advanced liability features such as Progressive Multis, which help us better manage your risk.

BetgeniusContent

The betgeniusContent is only required when the content for that leg was provided by Genius Sports.

Property 

Type 

Required 

Explanation 

sportId 

string (100)

Optional

Unique Genius Sports identifier for the sport. It needs to be unique for the entire service per bookmaker.

sportName 

string (200)

Optional

Genius Sports sport name.

competitionId 

string (100)

Optional

Unique Genius Sports identifier for competition. It needs to be unique for the entire service per bookmaker.

competitionName

string (200)

Optional

Genius Sports competition name.

fixtureId

string (100)

Optional

Unique Genius Sports identifier for the fixture. It needs to be unique for the entire service per bookmaker.

fixtureName 

string (200)

Optional

Genius Sports fixture name.

fixtureStartTimeUTC

DateTime

Optional

Genius Sportd fixture start time. Please use the format "yyyy-MM-ddTHH:mm:ss.ffffZ". Details are here.

marketId

string (500)

Optional

Unique Genius Sports identifier for the market. It needs to be unique for the entire service per bookmaker.

marketName

string (200)

Optional

Genius Sports market name.

selectionId 

string (200)

Required

Unique Genius Sports identifier for the outcome of the market. It needs to be unique for the entire service per bookmaker.

selectionName

string (200)

Optional

Genius Sports selection name.

BookmakerContent

Bookmaker overrides for the content.

Property 

Type 

Required 

Explanation 

sportId

string (100)

Required

Unique Bookmaker identifier for sport. It needs to be unique for the entire service per bookmaker.

sportName 

string (200)

Required

Bookmaker sport name.

competitionId 

string (100)

Required

Unique Bookmaker identifier for competition. It needs to be unique for the entire service per bookmaker.

competitionName

string (200)

Required

Bookmaker competition name.

fixtureId

string (100)

Required

Unique Bookmaker identifier for the fixture. It needs to be unique for the entire service per bookmaker.

fixtureName 

string (200)

Required 

Bookmaker fixture name.

fixtureStartTimeUTC

DateTime

Required

Bookmaker fixture start time. Please use the format "yyyy-MM-ddTHH:mm:ss.ffffZ". Details are here.

marketId

string (500)

Required 

Unique Bookmaker identifier for the market. It needs to be unique for the entire service per bookmaker.

marketName

string (200)

Required

Bookmaker market name.

selectionId 

string (200)

Required 

In case of GeniusSports content: unique Genius Sports identifier for the outcome of the market. It must match with the selectionId sent in Bet Assessment API assessment request.

In case of non GeniusSports content: unique Bookmaker identifier for the outcome of the market. Needs to be unique for the entire service per bookmaker. It must match with the selectionId sent to OddsFeed Platform Ingestion API and the selectionId sent in Bet Assessment API assessment request.

selectionName

string (200)

Required

Bookmaker selection name.

Example JSON

Single bet request body

Notice that the bet has only one leg.

Multi bet request body

Notice that the bet has multiple legs, but no systemBetType field was specified.

System bet request body

Notice that the bet has multiple legs and systemBetType field was specified.

 

Bet Feed Receiver Response types

Response code

Sample Request

Sample Response

Comments

Response code

Sample Request

Sample Response

Comments

200 (Success)

 

 

When the data sent to the endpoint is valid.

400 (Bad Request)

When some of the fields required by the contract are not sent, the server returns a validation error.

401 (Unauthorized)

 

 

When the sender is not authorised to post a request.

503 (Internal Server Error)

 

 

When there is a failure to process a request yet the data POSTed is correct.

Non-Genius Sports content

Bets on non-Genius Sports content are supported in GTS, for the case of OPTION 1 - Bet delay handled by customer, only HTTP REST API Integration.

By default, bets on non-Genius Sports content is assessed based on the default risk limits set on bookmaker level, but in order to receive the same functionality as for Genius Sports content the bookmaker needs to make non Genius content available for GTS.

Non-Genius content could be sent to GTS using our OddsFeed Platform Ingestion API. The content updates should be sent at the time when it is created or updated on the bookmaker’s platform, before the content is made available for betting. This is needed to allow the GTS service to assess bets based on the preset risk templates on the specific sport/competition/fixture/market. If the content is not sent prior to the bets, then these bets are assessed based on the default limits set for the specific customer.

OddsFeed Platform Ingestion API Specification

PRODUCTION: https://swaggerui.api.geniussports.com/?url=https://explorer.api.geniussports.com/OddsFeed-Ingestion%2Fv1%2FProduction%2Fswagger-latest.yaml

UAT: https://swaggerui.api.geniussports.com/?url=https://explorer.api.geniussports.com/OddsFeed-Ingestion%2Fv1%2FUAT%2Fswagger-latest.yaml

NB! The selections Ids sent to OddsFeed Platform Ingestion API, Bet Feed Receiver API bookmakerContent and Bet Assessment API requests need to match.

Appendix A: Supported System Bet Types definitions

There is a predefined list of supported System Bet Type Definitions we currently use. It could be extended by adding missing combinations supported by the bookmaker.

Here you can find more information about each supported system bet type GTS Supported System Bet Definitions.

Appendix B: Fallback scenarios to define the System Bet type of bet state messages for liability calculations

We are trying to avoid pushing back bet state messages with inconsistent data, using the following rules:

  1. The number of legs takes precedence over System Bet Type, i.e. if the systemBetType field is set, but the Bet has one leg, the systemBetType value will be ignored.

  2. If the number of legs in a bet is more than one, and the systemBetType value could not be found in the list of Supported System Bet Types (see Appendix A), the bet will be treated as a System Bet with all available combinations. I.e. for the bet with N legs, we will have a System Bet with the following array of leg combinations: [1, 2, 3, …, N]. The assessment of the unsupported bet types is approximate and not as accurate as the supported bet types.

Appendix C: Frequently Asked Questions

Appendix D: Receiving delayed bet assessments via Ably

If you are set up to use delayed bet assessment via supplying a valid priceChangeRule value in the Bet Assessment API request body, then the actual response where the bet is assessed will be returned as a message on the Ably messaging platform. Please see https://ably.com/docs for how to integrate with the Ably messaging platform.

Required Information

Your Genius Sports Customer Integration Manager will supply you with the following information, which is required for receiving messages from Genius Sports on Ably:

  • API key for Ably

  • Ably channel name prefix - your customer name as recorded by Genius Sports, set as all lower-case

  • The number of channels - will be given based on the expected peak load generated by your platform (By default, 1 - Testing environment and 10 - Production). You will use this as the channel suffix, where numbering starts from 0. The naming schema for channels is loweredcustomername:number

Example

For example, the customer TestBet would be supplied with the following information required for connecting to Ably to receive delayed Bet Assessment responses:

  • API key: MJ28HZ.bajd-4h37_bsHGL8l0habs-bB7FGnZZ08TAzpOLK72gHaADMMG

  • Ably channel name prefix: testbet

  • Number of channels: 5

Therefore, the TestBet platform would connect to 5 Ably channels, each of which would contain delayed Bet Assessments and should be connected to. The channels would be named as follows:

  • testbet:0

  • testbet:1

  • testbet:2

  • testbet:3

  • testbet:4

Genius Sports specific connection details

As Genius Sports has a specially configured set up with Ably there are some slight modifications required compared to the standard documentation when connecting, so when setting the ClientOptions in any Ably connection in any Ably library, you must:

  1. Set the Environment as geniussports

  2. Set the FallbackHosts as an array with 5 elements:

    1. geniussports-a-fallback.ably-realtime.com

    2. geniussports-b-fallback.ably-realtime.com

    3. geniussports-c-fallback.ably-realtime.com

    4. geniussports-d-fallback.ably-realtime.com

    5. geniussports-e-fallback.ably-realtime.com

Example 1 - C#

Example 2 - Node.js