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

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.

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