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 Suggested Bets feature in the Bet Concierge displayed to users.
For more general information about Sportradar adapters see Adapter Overview.
When you register an adapter, it listens for specific endpoints from the widget:
| Adapter Endpoint | Description | Type |
|---|---|---|
availableMarketsForEvent | The Bet Concierge AI assistant will suggest bet from one of these markets based on conversation context. | AvailableMarketsForEvent |
market | Get full market information about market that AI suggested. Implement either this OR eventMarkets. | Market |
eventMarkets | Get full market information about market that AI suggested. Implement either this OR market. | EventMarkets |
betSlipSelection | Matches selections to the user's bet slip. Outcome on bet suggestion will be marked as selected | BetSlipSelection |
recommendedSelections | Will mark selection as recommended. Outcome on suggested bet market will be marked as suggested - use for the promotions. | RecommendedSelections |
calculateCustomBetXML | Prepares custom bet XML payload for UOF odds calculation. Endpoint for custom bet feature. | calculateCustomBetXML |
This is an example of an adapter implementing all endpoints. It is intended to be a copy/paste template, where only data fetching and transformation need to be implemented. When implementing an adapter, implement only the endpoints which are required by the widget being integrated, and discard the rest. For each endpoint, only the getData${ENDPOINT_NAME}() and transormData${ENDPOINT_NAME}() functions need to be implemented.
Expand Adapter Template Code
SIR Widgets supports two types of adapter implementations:
<script type="text/javascript">
// Widget loader script from Step 3
ndatory
// -------- Data + Transform functions --------
async function getDataMarket(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataMarket(data) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
return {
market: {
id: data.marketId,
name: data.marketName,
outcomes: data.outcomes.map((outcome) => { id: outcome.id, name: outcome.name, odds: outcome.odds } )
},
event: { id: data.eventId, type: data.eventType }
};
*/
return {
market: {
id: "sr:market:1",
name: "Match Winner",
outcomes: [
{ id: "1", name: "Home", odds: 2.5 },
{ id: "X", name: "Draw", odds: 3.0 },
{ id: "2", name: "Away", odds: 3.2 }
]
},
event: "sr:match:12345"
};
}
async function getDataAvailableMarketsForEvent(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataAvailableMarketsForEvent(data) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
return {
selection: data.map((selection) => { type: selection.type, event: selection.event, market: selection.market})
};
*/
return {
selection: [
{
type: "uf",
event: "61513908",
market: "1",
},
],
};
}
async function getDataEventMarkets(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataEventMarkets(data, args) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
let markets = []
function mapMarkets(market){
return {
id: market.id,
status: market.status,
name: market.name,
outcomes: market.outcomes.map((outcome) => {id: outcome.id, name: outcome.name , odds: { type: outcome.odds.type, value: outcome.odds.value}, status: outcome.status})
};
}
return data.forEach(mapMarkets);
*/
return {
event: args.selection.event,
markets: [
{
id: "1",
status: "active",
name: "1x2",
outcomes: [
{
id: "1",
name: "Tenhaisen",
odds: { type: "eu", value: "1.88" },
status: "active",
},
{
id: "2",
name: "draw",
odds: { type: "eu", value: "3.85" },
status: "active",
},
{
id: "3",
name: "Hoftenstain",
odds: { type: "eu", value: "3.7" },
status: "active",
},
],
},
],
};
}
async function getDataEvent(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataEvent(data) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
return {
event: {
id: data.event,
date: {
displayValue: data.displayTime,
startTime: data.dateTime,
},
sport: {
id: data.sport.id,
name: data.sport.name,
},
category: {
id: data.category.id,
name: data.category.country,
},
tournament: {
id: data.tournament.id,
name: data.tournament.name,
},
teams: data.teams.map((team) => {id: team.id, name: team.name}),
isLive: data.isLive,
},
};
*/
return {
event: {
id: args.selection.event,
date: {
displayValue: "14/01/26, 19:30",
startTime: "2026-01-14T19:30:00.000Z",
},
sport: {
id: "1",
name: "Soccer",
},
category: {
id: "30",
name: "Germany",
},
tournament: {
id: "42",
name: "Liga Supreme",
},
teams: [
{ id: "1270229", name: "Tenhaisen" },
{ id: "31531", name: "Hoftenstain" },
],
isLive: false,
},
};
}
async function getDataFilterMarkets(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataFilterMarkets(data) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
return {
selection: data.selection.map((market) => {type: market.type, event: market.event, market: market.id})
}
*/
return {
selection: [
{
type: "uf",
event: "61513908",
market: "1",
},
],
};
}
async function getDataBetSlipSelection(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataBetSlipSelection(data) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
return {
selection: data.selection.map((market) => {event: market.event, market: market.market, outcome: market.outcome, type: market.type}),
};
*/
return {
selection: [
{
event: "61513908",
market: "1",
outcome: "1",
type: "uf",
},
],
};
}
async function getDataCashBackSelections(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataCashBackSelections(data) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
return {
events: data.events.map((event) => {event: event.id, type: event.type}),
}
*/
return {
events: [
{
event: "56418457",
type: "uf",
},
],
};
}
async function getDataTickets(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataTickets(data) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
return {
tickets: data.tickets.map((ticket) => {
ticketId: ticket.id,
bets: ticket.bets.map((bet) => {
betId: bet.id,
selections: bet.selections.map((selection) => {
type: selection.type,
event: selection.event,
market: selection.market,
outcome: selection.outcome,
odds: { type: selection.odds.type, value: selection.odds.value },
}),
stake: bet.stake.map((stake) => {
type: stake.type,
currency: stake.currency,
amount: stake.amount,
mode: stake.mode
}),
}),
}),
};
*/
return {
tickets: [
{
ticketId: "ticket_123456",
bets: [
{
betId: "bet_001",
selections: [
{
type: "uf",
event: "sr:match:12345",
market: "1",
outcome: "1",
odds: { type: "eu", value: "2.10" }
}
],
stake: [{
type: "cash",
currency: "USD",
amount: "10.00",
mode: "total"
}]
}
],
type: "ticket",
version: "1.0"
}
]
};
}
async function getDataMatchEventSuggestedSelection(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataMatchEventSuggestedSelection(data) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
return {
selections: data.selections.map((selection) => {
event: selection.event,
market: selection.market,
outcome: selection.outcome,
type: selection.type,
specifiers: selection.specifiers
})
};
*/
return {
selections: [
{ event: "sr:match:12345", market: "1", outcome: "1", type: "uf" },
{ event: "sr:match:12345", market: "18", specifiers: "total=2.5", type: "uf" }
]
};
}
async function getDataRecommendedSelections(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataRecommendedSelections(data) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
return {
selection: data.selections.map((selection) => {
event: selection.event,
market: selection.market,
outcome: selection.outcome,
type: selection.type,
specifiers: selection.specifiers
})
};
*/
return {
selection: [
{ event: "sr:match:12345", market: "1", outcome: "1", type: "uf" },
{ event: "sr:match:67890", market: "18", specifiers: "total=2.5", outcome: "13", type: "uf" }
]
};
}
async function getDataCalculateCustomBetXML(args) {
// Here fetch data from your data source and return it
return {};
}
function transformDataCalculateCustomBetXML(data) {
// Here transform your data into data structure exemplified by the object below.
/*
// Illustration how data transformation might work from client data to Adapter types
return {
payload: '<xml>data</xml>',
}
*/
return {
payload: `<filtered_calculation_response generated_at="2025-04-16T13:29:08+00:00">
<calculation odds="27.50303106727931" probability="0.027418715351118873" harmonization="false"/>
<available_selections>
<event id="sr:match:12345678">
<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>`
};
}
// -------- Adapter --------
const adapter = {
config: {},
endpoints: {
market: (args, callback) => {
getDataMarket(args)
.then(data => transformDataMarket(data))
.then(result => callback(undefined, result));
return () => {};
},
availableMarketsForEvent: (args, callback) => {
getDataAvailableMarketsForEvent(args)
.then(data => transformDataAvailableMarketsForEvent(data))
.then(result => callback(undefined, result));
return () => {};
},
eventMarkets: (args, callback) => {
getDataEventMarkets(args)
.then(data => transformDataEventMarkets(data, args))
.then(result => callback(undefined, result));
return () => {};
},
event: (args, callback) => {
getDataEvent(args)
.then(data => transformDataEvent(data, args))
.then(result => callback(undefined, result));
return () => {};
},
filterMarkets: (args, callback) => {
getDataFilterMarkets(args)
.then(data => transformDataFilterMarkets(data))
.then(result => callback(undefined, result));
return () => {};
},
betSlipSelection: (args, callback) => {
getDataBetSlipSelection(args)
.then(data => transformDataBetSlipSelection(data))
.then(result => callback(undefined, result));
return () => {};
},
cashBackSelections: (args, callback) => {
getDataCashBackSelections(args)
.then(data => transformDataCashBackSelections(data))
.then(result => callback(undefined, result));
return () => {};
},
tickets: (args, callback) => {
getDataTickets(args)
.then(data => transformDataTickets(data))
.then(result => callback(undefined, result));
return () => {};
},
matchEventSuggestedSelection: (args, callback) => {
getDataMatchEventSuggestedSelection(args)
.then(data => transformDataMatchEventSuggestedSelection(data))
.then(result => callback(undefined, result));
return () => {};
},
recommendedSelections: (args, callback) => {
getDataRecommendedSelections(args)
.then(data => transformDataRecommendedSelections(data))
.then(result => callback(undefined, result));
return () => {};
},
calculateCustomBetXML: (args, callback) => {
getDataCalculateCustomBetXML(args)
.then(data => transformDataCalculateCustomBetXML(data))
.then(result => callback(undefined, result));
return () => {};
},
},
};
</script>