...
[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 https://geniussports.atlassian.net/wiki/spaces/BID/pages/4396679262/Risk+Services+Integration#Root-objectThe price change tolerance is configurable per customer (bookmaker). 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.
...
Bet Assessment Request
Root object
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:
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:
In the case of using bet delay handled in GTS version:
In case if |
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:
|
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:
|
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
|
reasonMessage | string (500) | Optional | Description of the rejection reason. |
Examples
Expand | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
RequestsSingle bet without price change property
Single bet with price change property
Multi bet without price change property
Multi bet with price change property
System bet without price change property
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 |
---|---|---|
401 | Unauthorized | A request was made without a valid token in the |
403 | Forbidden | A request was made without a valid API Key in the |
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
Lucidchart | ||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
...
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. |
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 /wiki/spaces/GSG/pages/1311607730. | 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 /wiki/spaces/GSG/pages/1311607730 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) | Required | Unique Genius Sports identifier for the sport. It needs to be unique for the entire service per bookmaker. |
sportName | string (200) | Required | Genius Sports sport name. |
competitionId | string (100) | Required | Unique Genius Sports identifier for competition. It needs to be unique for the entire service per bookmaker. |
competitionName | string (200) | Required | Genius Sports competition name. |
fixtureId | string (100) | Required | Unique Genius Sports identifier for the fixture. It needs to be unique for the entire service per bookmaker. |
fixtureName | string (200) | Required | Genius Sports fixture name. |
fixtureStartTimeUTC | DateTime | Required | Genius Sportd fixture start time. Please use the format "yyyy-MM-ddTHH:mm:ss.ffffZ". Details are here. |
marketId | string (500) | Required | Unique Genius Sports identifier for the market. It needs to be unique for the entire service per bookmaker. |
marketName | string (200) | Required | 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) | Required | 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
Expand | |||||||||
---|---|---|---|---|---|---|---|---|---|
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 | |||||||
---|---|---|---|---|---|---|---|---|---|---|
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
...