An adapter is a piece of code that acts as a bridge between two systems. In the context of Bet Suggestions, an adapter connects your data source (such as a backend API or database) to the betting widgets displayed to users.
It listens for requests from the widget, processes them, fetches the necessary data, and then sends a response back to the widget. Think of the adapter as a translator that ensures seamless communication between your backend and the widget, ensuring real-time data synchronization for odds and outcomes.
The adapter ensures that the data shown in the widget is always:
In short, it ensures that what the user sees reflects the most up-to-date information from your backend system.
When you register an adapter, it listens for specific types of requests from the widget:
| Request Type | Description |
|---|---|
betConcierge.markets | Provides betting suggestions based on conversation with the AI assistant. Receives MarketsRequest with matchId and expects MarketsResponse in the callback. |
betSlip | Matches selections to the user's bet slip. Receives BetSlipRequest with userId and expects BetSlipResponse in the callback. |
calculateCbXml | Prepares custom bet XML payload for UOF odds calculation. Receives CustomBetCalculateRequest and expects CustomBetCalculateResponse in the callback. |
Each request type has a handler function that processes incoming data, formats it properly, and sends a response back to the widget.
You register an adapter by calling the SIR global function:
SIR('registerAdapter', onRequest);onRequest is a function that handles different types of requests by listening for events and responding accordingly.
Here's the general structure for handling incoming requests:
const onRequest = (requestName, args, callback) => {
switch (requestName) {
case 'betConcierge.markets':
handleMarkets(args, callback);
break;
case 'betSlip':
handleBetSlip(args, callback);
break;
case 'calculateCbXml':
handleCustomBetCalculate(args, callback);
break;
default:
callback(new Error('Unknown request'), undefined);
}
};The adapter sends back a response using the callback function:
error | undefinedFor example:
callback(undefined, response);If there is an error:
callback(new Error('Something went wrong'), undefined);The adapter can return an unsubscribe function for cleaning up event listeners or timers:
return () => {
// Cleanup logic if needed
};The Adapter documentation provides a complete example of how to implement the adapter.
The client has the possibility to have an adapter implemented by the Sportradar team. Please contact your Sportradar representative for more information.
Used to configure the adapter that retrieves and displays the information from the client's API.
| Parameter | Type | Description |
|---|---|---|
requestName | string | Name of the requested adapter |
args | MarketsRequest | BetSlipRequest | CustomBetCalculateRequest | Arguments for individual request |
callback | OnRequestCallback | Function that should be executed whenever data for the request changes |
Example:
function onRequest(requestName, args, callback) {
// adapter implementation
}
SIR('registerAdapter', onRequest);Callback argument in the adapter onRequest function.
| Parameter | Type | Description |
|---|---|---|
error | Object | undefined | Error object or undefined if there is no error |
data | MarketsResponse | BetSlipResponse | CustomBetCalculateResponse | Shape of this object is defined by requestName |
Returns: void
Arguments for the markets request.
| Property | Type | Description |
|---|---|---|
matchId | string | number | Sportradar ID of the match |
Example:
{
"matchId": 50955897
}| Property | Type | Description |
|---|---|---|
value | string | number | Specifier value |
Example:
{
"value": "total=2.5"
}| Property | Type | Description |
|---|---|---|
status | 'active' | 'deactivated' | Market status. If not active, market will not be displayed in the widget |
Example:
{
"status": "active"
}Individual outcome within a market.
| Property | Type | Required | Description |
|---|---|---|---|
id | string | number | Yes | Sportradar outcome ID |
name | string | Yes | Displayed outcome name |
isSelected | boolean | Yes | Used to mark outcomes as selected in the bet suggestions in the chat |
odds | string | number | No | String or number representation of odds displayed as is (NO FORMATTING) |
oddsDecimal | number | No | Numeric EU representation of odds (decimal number) displayed on market outcome |
status | Object | Yes | |
status.isActive | boolean | Yes | Outcome status. If not active, it will not be displayed in the widget |
isRecommended | boolean | No | When true, the outcome will be highlighted as a recommended outcome |
Example:
{
"id": "1",
"name": "PSG",
"odds": "1.44",
"isSelected": false,
"status": {
"isActive": true
}
}Arguments for the markets response.
| Property | Type | Required | Description |
|---|---|---|---|
markets | Array<Object> | Yes | Array of supported markets. AI will suggest bets out of these markets |
markets.id | string | number | Yes | Sportradar market ID |
markets.name | string | Yes | Displayed market name |
markets.outcomes | Array<[Outcome](#outcome)> | Yes | Array of outcomes |
markets.status | MarketStatus | Yes | Market status object |
markets.specifier | MarketSpecifier | No | Market specifier |
Example:
{
"markets": [
{
"id": "1",
"name": "1x2",
"outcomes": [
{
"id": "1",
"name": "PSG",
"odds": "1.44",
"isSelected": false,
"status": {
"isActive": true
}
},
{
"id": "2",
"name": "Draw",
"odds": "4.80",
"isSelected": false,
"status": {
"isActive": true
}
},
{
"id": "3",
"name": "Nice",
"odds": "7.50",
"isSelected": false,
"status": {
"isActive": true
}
}
],
"status": {
"status": "active"
}
}
]
}Arguments for the bet slip request.
| Property | Type | Description |
|---|---|---|
userId | string | number | ID of the user |
Example:
{
"userId": "user:12345"
}| Property | Type | Description |
|---|---|---|
| id | string | number | |
| event | Object | |
| event.id | string | number | Sportradar match id |
| markets | MarketsResponse | Array of selected markets and outcomes (max 500) |
Example:
{
"id": "demo-bet",
"event": {
"id": 50955897
},
"markets": [
{
"id": "1",
"name": "1x2",
"outcomes": [
{
"id": "3",
"name": "Nice",
"isSelected": true,
"status": {
"isActive": true
}
}
],
"status": {
"status": "active"
}
}
]
}Response containing user's current betting picks.
| Property | Type | Required | Description |
|---|---|---|---|
picks | Array<Object> | Yes | Users current betting picks. Used to match the selected outcomes form the picks array to the bet suggestions in the chat - Alternative to isSelected property in the market outcomes. |
picks.eventId | string | Yes | Sportradar match ID |
picks.marketId | string | Yes | Market ID of the selected outcome |
picks.outcomeId | string | Yes | Selected outcome ID |
picks.specifier | string | No | Market specifier of the selected outcome |
combinedOdds | number | string | No | Combined odds of the bets in the bet slip |
Example:
{
"picks": [
{
"eventId": "sr:match:50955897",
"marketId": "1",
"outcomeId": "3"
},
{
"eventId": "sr:match:50955897",
"marketId": "65",
"outcomeId": "1712",
"specifier": "hcp=0:2"
}
],
"combinedOdds": "21.50"
}Arguments for the custom bet request.
| Property | Type | Description |
|---|---|---|
calculatePayload | string | Custom bet XML payload for UOF odds calculation |
Example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<filterSelections
xmlns="http://schemas.sportradar.com/custombet/v1/endpoints"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://schemas.sportradar.com/custombet/v1/endpoints
http://schemas.sportradar.com/custombet/v1/endpoints/Selections.xsd">
<selection id="sr:match:50955897">
<market market_id="1" outcome_id="3"/>
</selection>
</filterSelections>Arguments for the custom bet response.
| Property | Type | Description |
|---|---|---|
payload | string | Calculate custom bet XML response |
Example:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<filtered_calculation_response generated_at="2025-04-16T13:29:08+00:00">
<calculation odds="21.50303106727931" probability="0.030418715351118873" harmonization="false"/>
<available_selections>
<event id="sr:match:58265377">
<markets>
<market id="65" specifiers="hcp=0:2" conflict="false">
<outcome id="1711" conflict="true"/>
<outcome id="1712" conflict="true"/>
<outcome id="1713" conflict="false"/>
</market>
...
</markets>
</event>
</available_selections>
</filtered_calculation_response>