Skip to main content
Logo
Explore APIsContact Us
  • Home
  • Match Preview
  • Tournament Preview
  • Virtual Stadium
  1. Resources
  2. Widgets
  3. Hosted Implementation

Hosted Implementation

Widgets, Engagement Tools
OverviewSelf-Service Adapter
Last updated about 2 months ago
Is this site helpful?
On this page
  • When to Use Hosted Adapter
  • Getting Started
  • Advanced Configuration and Extensions
  • Tailoring Widget Behavior
  • Extending Functionality via Custom Endpoints

The Hosted Adapter is a Sportradar-managed solution designed for clients using common data source for odds and markets. With this approach, Sportradar handles the adapter infrastructure and development allowing you to focus on integrating widgets into your platform.

#When to Use Hosted Adapter

The hosted adapter is the right choice when:

  • You use Sportradar data for your betting markets and odds and you want a faster integration path with minimal development effort

#Getting Started

This example shows starting from scratch with a plain HTML file. If you're integrating into an existing website, add the corresponding elements to your existing pages.

Important

Replace <YOUR_CLIENT_ID> with your actual Sportradar client ID. Also replace <WIDGET_NAME> and ...widgetProps with the actual widget name and configuration.

#Advanced Configuration and Extensions

The Hosted Adapter provides sensible defaults for most integrations, but you can extend its functionality or override behavior by providing a partial adapter object as an optional third parameter to the SIR("registerAdapter", ...) call. This hybrid approach offers the reliability of a Sportradar-managed solution alongside the flexibility of local customization.

#Tailoring Widget Behavior

Providing a custom config object allows you to implement granular, per-widget filtering and layout overrides. This is particularly useful when you need to restrict specific markets for certain sports or align the widget's data presentation with your platform's unique requirements.

javascript
SIR("registerAdapter", {
  config: {
    widget: {
      'betRecommendation.eventList': {
        allowedMarkets: {
          '1': { '1': true, '18': true, '16': true }, // Soccer: 1x2, Total, Handicap
          '2': { '1':

















#Extending Functionality via Custom Endpoints

You can augment the Hosted Adapter by implementing specific custom endpoints. This enables deeper integration with your platform's stateful data, such as user-specific configurations or live bet slip information.

#Synchronizing the Bet Slip

One of the most valuable extensions is implementing the betSlipSelection endpoint. This allows the widget to reflect the current state of a user's bet slip in real-time—automatically highlighting outcomes that have already been selected.

This endpoint is called once at initialization to subscribe to the punter's bet slip selections. Save the callback function and invoke it whenever the bet slip changes to keep widgets synchronized with the user's current selections.

BetSlipSelection Function

Subscribes to the current punter's bet slip selections (their betting cart). Widgets use this data to display selections as selected or, depending on the widget, may hide certain selections.

Used by: betRecommendation.highlights, betRecommendation.eventList, betRecommendation.swipeBet, betRecommendation.similarBets, betRecommendation.markets, betRecommendation.myCombo, betInsights, betConcierge

ArgumentTypeRequiredDescription
argsundefinedNo arguments
callbackCallback<BetSlipSelectionResponse>yesFunction to receive bet slip selections or error

Returns: UnsubscribeFunction - Optional cleanup function to stop receiving updates

Usage Example
javascript
// Usage example:
const adapterExtension = {
  endpoints: {
    betSlipSelection: (args, callback) => {
      // Store the callback to invoke it whenever bet slip changes
      const notifyBetSlipChange = callback;






















danger

Register the adapter once on page load, before adding any widgets. Do not call registerAdapter multiple times or register different adapters. Doing so will cause unpredictable behavior. Widgets added before adapter registration will fail to load data.

html
<!DOCTYPE html>
<html>
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Hosted Adapter Demo</title>
    <style>
      body {
        display: flex;
        justify-content: center;
      }
      .widgets {
        max-width: 620px;
        width: 100%;
      }
      .sr-widget {
        border: rgba(0, 0, 0, 0.12) solid 1px;
      }
    </style>
    <script type="text/javascript">
      (function(a,b,c,d,e,f,g,h,i){a[e]||(i=a[e]=function(){(a[e].q=a[e].q||[]).push(arguments)},i.l=1*new Date,i.o=f,g=b.createElement(c),h=b.getElementsByTagName
      )})(window,document,"script","https://widgets.sir.sportradar.com/<YOUR_CLIENT_ID>/widgetloader","SIR", {
          language: 'en', // SIR global options
          adapterDataSource: '<ADAPTER_DATA_SOURCE_NAME>'
      });

      SIR("addWidget", "#sr-widget", "<WIDGET_NAME>", {
        ...widgetProps // Replace with widget props
      });
    </script>
  </head>
  <body>    
    <div class="widgets">
      <div id="sr-widget">Widget will load here...</div>
    </div>
  </body>
</html>
true
,
'18'
:
true
,
'14'
:
true
}
// Basketball: 1x2, Total, Handicap
},
layout: {
'1': {
sportId: 1,
markets: [
{
title: '3 Way',
columns: ['1', 'x', '2'],
preMatchMarketId: '1',
liveMarketId: '1'
}
]
}
}
}
}
}
});
javascript
// Example implementation
adapter.endpoints.betSlipSelection = (args, callback) => {
  // args is undefined for this endpoint

  // Your implementation here - subscribe to bet slip changes
  // Call callback whenever bet slip changes
  callback(undefined, {
    selection: [
      { event: "sr:match:12345", market: "1", outcome: "2", odds: { type: "decimal", value: "1.95" } },
      // ... current bet slip selections
    ]
  });

  // Return unsubscribe function to stop receiving updates
  return () => {
    // Cleanup bet slip subscription
  };
};
// Subscribe to your platform's bet slip change events
yourBetSlipStore.onBetSlipChange((currentSelections) => {
// Map your internal data structure to the BetSlipSelectionResponse format
// Execute latest saved callback function
notifyBetSlipChange(undefined, {
selection: currentSelections.map((sel) => ({
event: sel.eventId, // e.g., "sr:match:12345"
market: sel.marketId, // e.g., "1"
outcome: sel.outcomeId, // e.g., "2"
odds: { type: "eu", value: sel.odds }
}))
});
});
return () => {
// Cleanup: unsubscribe from bet slip changes when widget unmounts
yourBetSlipStore.offBetSlipChange();
};
}
}
}
SIR("registerAdapter", adapterExtension);
(c)[
0
]
,
g
.
async
=
1
,
g
.
src
=
d
,
g
.
setAttribute
(
"n"
,
e)
,
h
.
parentNode
.
insertBefore
(g
,
h)