Betting Entertainment Tools

Data Adapter

What is an Adapter?

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.

What is the Purpose of an Adapter?

The adapter ensures that the data shown in the widget is always:

  • Accurate: Displays the latest active markets and odds.
  • Real-time: Updates markets and live odds.
  • Interactive: Enables users to engage with bets, outcomes, and markets directly from the widget.
In short, it ensures that what the user sees reflects the most up-to-date information from your backend system.

How Does an Adapter Work?

When you register an adapter, it listens for specific types of requests from the widget, such as:

  • Markets (betConcierge.markets): Provides betting suggestions based on conversation with AI assistant. This adapter receives MarketsRequest with `matchId in the arguments and expects MarketsResponse in the callback function.
  • Bet Slip (betConcierge.betSlip): Matches selections to users bet Slip. This adapter receives BetSlipRequest with `matchId` in the arguments and expects BetSlipResponse in the callback function.
  • Custom Bet (calculateCbXml): Prepares custom bet XML payload for UOF odds calculation. This adapter receives CustomBetCalculateRequest and expects CustomBetCalculateResponse in the callback function.
Each request type has a handler function that processes incoming data, formats it properly, and sends a response back to the widget.

How to Register an Adapter

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.

Handling Requests

Here’s the general structure for handling incoming requests:

const onRequest = (requestName, args, callback) => {
  switch (requestName) {
    case 'betConcierge.markets':
      handleMarkets(args, callback);
      break;
    case 'betConcierge.betSlip':
      handleBetSlip(args, callback);
      break;
    case 'calculateCbXml':
      handleCustomBetCalculate(args, callback);
      break;
    default:
      callback(new Error('Unknown request'), undefined);
  }
};

Responding to Requests

The adapter sends back a response using the callback function:

  • First argument: error | undefined
  • Second argument: The data response object.
For example:
callback(undefined, response);
If there is an error:
callback(new Error('Something went wrong'), undefined);

Unsubscribing

The adapter can return an unsubscribe function for cleaning up event listeners or timers:

return () => {
  // Cleanup logic if needed
};

The Adapter implementation Example provides a complete example of how to implement the adapter.

Type Definitions

Object

# Bet

Properties:
Name Type Description
id string | number
event Object
id Object

Sportradar match id

markets MarketsResponse Widgets.BetConcierge.Integration.DataAdapter.MarketsResponse

Array of selected markets and outcomes. Maximum of 500 markets is supported.

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"
            }
        }
    ]
}

# BetConciergeAdapter()

Used to configure the adapter that retrieves and displays the information from the client's API.

Properties:
Name Type Description
requestName string

name of the requested adapter.

args MarketsRequest Widgets.BetConcierge.Integration.DataAdapter.MarketsRequest | BetSlipRequest Widgets.BetConcierge.Integration.DataAdapter.BetSlipRequest | CustomBetCalculateRequest Widgets.BetConcierge.Integration.DataAdapter.CustomBetCalculateRequest

Arguments for individual request

callback OnRequestCallback Widgets.BetConcierge.Integration.DataAdapter.OnRequestCallback

Function that should be executed whenever data for the request changes

Example
function onRequest(requestName, args, callback) {
    // adapter implementation
}

SIR('registerAdapter', onRequest);
Object

# BetSlipRequest

Arguments for the bet slip request.

Properties:
Name Type Description
matchId string | number

Sportradar ID of the match.

Example
{
    matchId: 50955897
}
Object

# BetSlipResponse

Arguments for the bet slip response.

Properties:
Name Type Description
betSlip Object

Users current bet slip. Used to match the selected outcomes form the bet slip to the bet suggestions in the chat - Alternative to isSelected property in the market outcomes.

id string
betType 'single' | 'multibet' | 'sameGameMulti'
bets Array.<Bet> Array.<Widgets.BetConcierge.Integration.DataAdapter.Bet>

Array of bets in the bet slip.

Example
{
    betSlip: {
        id: "demo-bet-slip",
        betType: "single",
        bets: [
            {
                id: "demo-bet",
                event: {
                    id: 50955897
                },
                markets: [
                    {
                        id: "1",
                        name: "1x2",
                        outcomes: [
                            {
                                id: "3",
                                name: "Nice",
                                isSelected: true,
                                status: {
                                    isActive: true
                                }
                            }
                        ],
                        status: {
                            status: "active"
                        }
                    }
                ]
            },
            .....
        ]
    }
}
Object

# CustomBetCalculateRequest

Arguments for the custom bet request.

Properties:
Name 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>`
Object

# CustomBetCalculateResponse

Arguments for the custom bet response.

Properties:
Name 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>`
Object

# MarketSpecifier

Properties:
Name Type Attributes Description
markets.specifier.value string | number
Example
{
    value: "total=2.5"
}
Object

# MarketStatus

Properties:
Name Type Description
markets.status.status 'active' | 'deactivated'

Market status. If market status is not active, market will not be displayed in the widget.

Example
{
    status: "active"
}
Object

# MarketsRequest

Arguments for the markets request.

Properties:
Name Type Description
matchId string | number

Sportradar ID of the match.

Example
{
    matchId: 50955897
}
Object

# MarketsResponse

Arguments for the markets response.

Properties:
Name Type Attributes Description
markets Array.<Object> <required>

Array of supported markets. AI will suggest bets out of these markets.

id string | number <required>

Sportradar market id

name string <required>

Displayed market name

outcomes Array.<Outcome> Array.<Widgets.BetConcierge.Integration.DataAdapter.Outcome> <required>

Array of outcomes

status MarketStatus Widgets.BetConcierge.Integration.DataAdapter.MarketStatus <required>
specifier MarketSpecifier Widgets.BetConcierge.Integration.DataAdapter.MarketSpecifier
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"
            }
        },
        .....
    ]
}

# OnRequestCallback(error, data) → {void}

Callback argument in the adapter onRequest function

Parameters
Name Type Description
error Object | undefined

Error object or undefined if there is no error.

data MarketsResponse Widgets.BetConcierge.Integration.DataAdapter.MarketsResponse | BetSlipResponse Widgets.BetConcierge.Integration.DataAdapter.BetSlipResponse | CustomBetCalculateResponse Widgets.BetConcierge.Integration.DataAdapter.CustomBetCalculateResponse

Shape of this object is defined by requestName.

void
Object

# Outcome

Properties:
Name Type Attributes Description
id string | number <required>

Sportradar outcome id

name string <required>

Displayed outcome name

isSelected boolean <required>

Used to mark outcomes a selected in the bet suggestions in the chat

odds string | number

String or number representation of odds displayed as is, meaning NO FORMATTING.

oddsDecimal number

Numeric EU representation of odds (decimal number) displayed on market outcome.

status Object <required>
isActive boolean <required>

Outcome status. If outcome status is not active, it will not be displayed in the widget.

isRecommended boolean

When this property is set to true, the outcome will be marked as a recommended outcome, and it will be highlighted in the UI.

Example
{
    id: "1",
    name: "PSG",
    odds: "1.44",
    isSelected: false,
    status: {
        isActive: true
    }
}