---
title: "Hosted Adapter"
canonical_url: "https://apidocs.sportradar.com/resources/widgets/docs/adapter/HostedImplementation"
markdown_url: "https://apidocs.sportradar.com/resources/widgets/docs/adapter/HostedImplementation.md"
last_updated: "2026-07-30T12:55:11Z"
---

# Hosted Adapter

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

If you use a different data provider, contact your Sportradar sales representative to discuss available options.

## 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.

> **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(c)[0],g.async=1,g.src=d,g.setAttribute("n",e),h.parentNode.insertBefore(g,h)
      )})(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>
```

1. **Step 1**

   #### Basic Structure

   Base structure needed for a standalone HTML file.

2. **Step 2**

   #### Styling

   If you are working from starting standalone HTML file add CSS styles for the widget container.
   When integrating into an existing website, style the widget container according to your page design instead of using these example styles.

3. **Step 3**

   #### Widget Loader Script

   Add the SIR widget loader script in the `<head>` section. This loads the widget framework asynchronously and makes the global `SIR` function available.

   Make sure to replace:

   - `<YOUR_CLIENT_ID>` with your actual Sportradar client ID.
   - `<ADAPTER_DATA_SOURCE_NAME>` with the adapter data source provided to you during the integration process.

4. **Step 4**

   #### Add Widget

   Initialize the widget using `SIR("addWidget", ...)` inside a `load` event listener. This ensures the widget is added after the page and framework are valid.

   Make sure to replace:

   - `<WIDGET_NAME>` with the actual widget name (e.g. `betInsights`)
   - `...widgetProps` with the specific properties for that widget (e.g., `{ matchId: 12345678 }`)

5. **Step 5**

   #### Widget Container

   Create a container element (`#sr-widget`) where the widget will be rendered. Widgets need a target element to mount into.

## 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': 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'
              }
            ]
          }
        }
      }
    }
  }
});
```

### 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 bettor'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 bettor'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`

| Argument | Type                                                                                                                                                                                                                          | Required | Description                                      |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------ |
| args     | `undefined`                                                                                                                                                                                                                   |          | No arguments                                     |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`BetSlipSelectionResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betslipselectionresponse)> | yes      | Function to receive bet slip selections or error |

**Returns:** [`UnsubscribeFunction`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#unsubscribefunction) - Optional cleanup function to stop receiving updates

```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
  };
};
```

<details>
<summary>Usage Example</summary>

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

      // 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: "decimal", value: sel.odds }
          }))
        });
      });

      return () => {
        // Cleanup: unsubscribe from bet slip changes when widget unmounts
        yourBetSlipStore.offBetSlipChange();
      };
    }
  }
}
SIR("registerAdapter", adapterExtension);
```

</details>
