# Hosted Implementation

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

### Integration Example

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.

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

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

#### Self-service example

```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>Self-Service 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
      });
      
      const adapter = {
        // < Adapter code will go here >
      };
    
      SIR("registerAdapter", adapter);

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

[Learn more about Self-Service Implementation →](https://docs.sportradar.com/engagement-tools/adapter/self-service-implementation)

#### Hosted Example"

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

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

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

<table><thead><tr><th>Argument</th><th width="241">Type</th><th>Required</th><th>Description</th></tr></thead><tbody><tr><td>args</td><td><code>undefined</code></td><td></td><td>No arguments</td></tr><tr><td>callback</td><td><code>Callback</code>&#x3C;<a href="../types#betslipselection-function"><code>BetSlipSelectionResponse</code></a>></td><td>yes</td><td>Function to receive bet slip selections or error</td></tr></tbody></table>

**Returns:** [`UnsubscribeFunction`](https://docs.sportradar.com/engagement-tools/types#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: "eu", 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: "eu", value: sel.odds }
          }))
        });
      });

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