---
title: "Adapter API Reference and Types"
canonical_url: "https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types"
markdown_url: "https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md"
last_updated: "2026-09-14T11:55:40Z"
---

# Adapter API Reference and Types

## Adapter Object

| Property  | Type                                                                                                         | Required | Description                      |
| --------- | ------------------------------------------------------------------------------------------------------------ | -------- | -------------------------------- |
| config    | [`ConfigObject`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#config-object)       |          | Adapter configuration settings   |
| endpoints | [`EndpointsObject`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#endpoints-object) | yes      | Adapter endpoint implementations |

### Config Object

The `config` object controls adapter behavior and widget-specific configurations.

| Property | Type                                                                                                  | Required | Description                    |
| -------- | ----------------------------------------------------------------------------------------------------- | -------- | ------------------------------ |
| widget   | [`WidgetConfig`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#widgetconfig) |          | Widget-specific configurations |

#### WidgetConfig

| Property                        | Type                                                                                                            | Required | Description                                            |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------ |
| `'betRecommendation.eventList'` | [`BrEventListConfig`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#breventlistconfig) |          | Configuration for bet recommendation event list widget |

### Endpoints Object

The `endpoints` object contains all adapter endpoint implementations.

> **Tip**
>
> The `market` and `eventMarkets` endpoints are **mutually exclusive** – you only need to implement ONE of these two. Choose based on your API capabilities:
>
> - Implement **`market`** if your API can fetch a specific market for an event efficiently
> - Implement **`eventMarkets`** if your API can fetch all markets for an event in a single call
> - If implementing `market`, you can optionally add `availableMarketsForEvent` to list available markets first
>
> **Shared Endpoints Across Widgets:** All widgets use the same adapter endpoints. When a specific widget needs to limit returned data, the request `args` will include a `widget` property containing the widget name (the same value used in `SIR('addWidget', widgetName, ...)`). Use this to conditionally filter or modify your response per widget if needed.

| Property                     | Type                                                                                                                                         | Description                                                                                                                                                |
| ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| availableMarketsForEvent     | [AvailableMarketsForEvent](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#availablemarketsforevent-function)         | Retrieves all available markets selections for a specific event. Use with `market` endpoint to discover available markets.                                 |
| market                       | [Market](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#market-function)                                             | **Implement either this OR `eventMarkets`** – Retrieves a specific market data for a specific event.                                                       |
| eventMarkets                 | [EventMarkets](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#eventmarkets-function)                                 | **Implement either this OR `market`** – Retrieves all markets data for a specific event in one call. Use if your API provides all markets on one endpoint. |
| event                        | [Event](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#event-function)                                               | Retrieves detailed event data including event start time, scores, team names, tournament name, and more.                                                   |
| filterMarkets                | [FilterMarkets](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#filtermarkets-function)                               | Filters available markets based on widget requirements and provided selections, returning all or a subset.                                                 |
| betSlipSelection             | [BetSlipSelection](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betslipselection-function)                         | Subscribes to the current bettor's bet slip selections (their betting cart)                                                                                |
| cashBackSelections           | [CashBackSelections](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#cashbackselections-function)                     | Retrieves selections eligible for cash back promotions.                                                                                                    |
| tickets                      | [Tickets](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#tickets-function)                                           | Retrieves the bettor's placed bets (tickets)                                                                                                               |
| matchEventSuggestedSelection | [MatchEventSuggestedSelection](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#matcheventsuggestedselection-function) | Retrieves suggested selections for a specific match event (incident).                                                                                      |
| recommendedSelections        | [RecommendedSelections](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#recommendedselections-function)               | Retrieves recommended selections for a given event.                                                                                                        |
| calculateCustomBetXML        | [CalculateCustomBetXML](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#calculatecustombetxml-function)               | Calculates custom bet XML for given markets and match.                                                                                                     |

```javascript
// Example adapter implementation
const adapter = {
  config: {
    widget: {
      'betRecommendation.eventList': {
        layout: { /* EventListMarketsConfig */ },
        allowedMarkets: { /* SportMarketsMap */ }
      }
    }
  },
  endpoints: {
    event: (args, callback) => {
      // Fetch and return event data
      // Return optional unsubscribe function
    },
    eventMarkets: (args, callback) => {
      // Fetch and return markets for event
    },
    betSlipSelection: (args, callback) => {
      // Fetch and return markets selected in betslip
    }
    // ... other endpoints
  }
};
```

### Widget Specific Endpoints

> **Warning**
>
> In all widgets below, where `eventMarkets`, `market` and `availableMarketsForEvent` endpoints are listed as mandatory, either `eventMarkets` endpoint needs to be implemented, or both `market` and `availableMarketsForEvent`, not all three.
>
> It depends on the nature of your data, which option is more convenient to implement. If your API endpoint returns a single market object, it is more convenient to implement the `market` and `availableMarketsForEvent` combination, if your API returns a list of markets, it is more convenient to implement the `eventMarkets` endpoint.

#### betRecommendation.highlights

##### Mandatory Endpoints

- `eventMarkets` or (`market` + `availableMarketsForEvent`)
- `event`

##### Optional Endpoints

- `filterMarkets` - narrows markets selection for widget specific use
- `betSlipSelection` - visual representation of markets already in betslip
- `cashBackSelections` - adds visual representation of cash back markets

#### betRecommendation.eventList

##### Mandatory Endpoints

- `eventMarkets` or (`market` + `availableMarketsForEvent`)
- `event`

##### Optional Endpoints

- `filterMarkets` - narrows markets selection for widget specific use
- `betSlipSelection` - visual representation of markets already in betslip
- `cashBackSelections` - adds visual representation of cash back markets

#### betRecommendation.swipeBet

##### Mandatory Endpoints

- `eventMarkets` or (`market` + `availableMarketsForEvent`)
- `event`

##### Optional Endpoints

- `filterMarkets` - narrows markets selection for widget specific use
- `betSlipSelection` - visual representation of markets already in betslip
- `cashBackSelections` - adds visual representation of cash back markets

#### betRecommendation.similarBets

##### Mandatory Endpoints

- `eventMarkets` or (`market` + `availableMarketsForEvent`)
- `event`

##### Optional Endpoints

- `filterMarkets` - narrows markets selection for widget specific use
- `betSlipSelection` - visual representation of markets already in betslip
- `cashBackSelections` - adds visual representation of cash back markets

#### betRecommendation.markets

##### Mandatory Endpoints

- `eventMarkets` or (`market` + `availableMarketsForEvent`)
- `event`

##### Optional Endpoints

- `betSlipSelection` - visual representation of markets already in betslip

#### betRecommendation.myCombo

##### Mandatory Endpoints

- `eventMarkets` or (`market` + `availableMarketsForEvent`)
- `event`

##### Optional Endpoints

- `betSlipSelection` - visual representation of markets already in betslip

#### betInsights

##### Mandatory Endpoints

- `eventMarkets` or (`market` + `availableMarketsForEvent`)
- `event`

##### Optional Endpoints

- `betSlipSelection` - visual representation of markets already in betslip

#### betConcierge

##### Mandatory Endpoints

- `availableMarketsForEvent` - the AI assistant suggests bets from one of these markets based on conversation context
- `eventMarkets` or `market` - implement one (mutually exclusive); provides full market info for the AI-suggested market
- `betSlipSelection` - marks outcomes already in the user's bet slip as selected

##### Optional Endpoints

- `recommendedSelections` - marks a selection as recommended (use for promotions)
- `calculateCustomBetXML` - enables custom bet combo suggestions (requires `enableCustomBet: true` widget prop)
- `event` - event data is passed trough to `addSelectionsToBetSlip` action.

#### virtualStadium

##### Optional Endpoints

- `tickets` - enables bet sharing (Virtual Stadium chat bet-share picker, Central Hub share-betslip flows)
- `matchEventSuggestedSelection` - to enable flash bet
- `eventMarkets` or (`market` + `availableMarketsForEvent`) - to enable flash bet

> **Note**
>
> betInsights is an optional component of Virtual Stadium. If betInsights is enabled, all adapter endpoints required by betInsights must be implemented as well.

## Complete Adapter Example

This is an example of an adapter implementing all endpoints. It is intended to be a copy/paste template, where only data fetching and transformation need to be implemented. When implementing an adapter, implement only the endpoints which are required by the widget being integrated, and discard the rest. For each endpoint, only the `getData${ENDPOINT_NAME}()` and `transormData${ENDPOINT_NAME}()` functions need to be implemented.

***Expand Adapter Template Code***

```html
<script type="text/javascript">
// Widget loader script from Step 3 
ndatory 
// -------- Data + Transform functions --------

async function getDataMarket(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataMarket(data) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  return {
    market: {
      id: data.marketId,
      name: data.marketName,
      outcomes: data.outcomes.map((outcome) =>  { id: outcome.id, name: outcome.name, odds: outcome.odds } )
    },
    event: { id: data.eventId, type: data.eventType }
  };
  */

  return {
    market: {
      id: "sr:market:1",
      name: "Match Winner",
      outcomes: [
        { id: "1", name: "Home", odds: 2.5 },
        { id: "X", name: "Draw", odds: 3.0 },
        { id: "2", name: "Away", odds: 3.2 }
      ]
    },
    event: "sr:match:12345"
  };
}

async function getDataAvailableMarketsForEvent(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataAvailableMarketsForEvent(data) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  return {
    selection: data.map((selection) => { type: selection.type, event: selection.event, market: selection.market})
  }; 
  */

  return {
    selection: [
      {
        type: "uf",
        event: "61513908",
        market: "1",
      },
    ],
  };
}

async function getDataEventMarkets(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataEventMarkets(data, args) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  let markets = []

  function mapMarkets(market){
    return {
      id: market.id,
      status: market.status,
      name: market.name,
      outcomes: market.outcomes.map((outcome) => {id: outcome.id, name: outcome.name , odds: { type: outcome.odds.type, value: outcome.odds.value}, status: outcome.status})
    };
  }

  return data.forEach(mapMarkets);
  */

  return {
    event: args.selection.event,
    markets: [
      {
        id: "1",
        status: "active",
        name: "1x2",
        outcomes: [
          {
            id: "1",
            name: "Tenhaisen",
            odds: { type: "decimal", value: "1.88" },
            status: "active",
          },
          {
            id: "2",
            name: "draw",
            odds: { type: "decimal", value: "3.85" },
            status: "active",
          },
          {
            id: "3",
            name: "Hoftenstain",
            odds: { type: "decimal", value: "3.7" },
            status: "active",
          },
        ],
      },
    ],
  };
}

async function getDataEvent(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataEvent(data) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  return {
    event: {
      id: data.event,
      date: {
        displayValue: data.displayTime,
        startTime: data.dateTime,
      },
      sport: {
        id: data.sport.id,
        name: data.sport.name,
      },
      category: {
        id: data.category.id,
        name: data.category.country,
      },
      tournament: {
        id: data.tournament.id,
        name: data.tournament.name,
      },
      teams: data.teams.map((team) => {id: team.id, name: team.name}),
      isLive: data.isLive,
    },
  }; 
  
  */
  return {
    event: {
      id: args.selection.event,
      date: {
        displayValue: "14/01/26, 19:30",
        startTime: "2026-01-14T19:30:00.000Z",
      },
      sport: {
        id: "1",
        name: "Soccer",
      },
      category: {
        id: "30",
        name: "Germany",
      },
      tournament: {
        id: "42",
        name: "Liga Supreme",
      },
      teams: [
        { id: "1270229", name: "Tenhaisen" },
        { id: "31531", name: "Hoftenstain" },
      ],
      isLive: false,
    },
  };
}

async function getDataFilterMarkets(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataFilterMarkets(data) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  return {
    selection: data.selection.map((market) => {type: market.type, event: market.event, market: market.id})
  }
  */
  return {
    selection: [
      {
        type: "uf",
        event: "61513908",
        market: "1",
      },
    ],
  };
}

async function getDataBetSlipSelection(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataBetSlipSelection(data) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  return {
    selection: data.selection.map((market) => {event: market.event, market: market.market, outcome: market.outcome, type: market.type}),
  };
  */

  return {
    selection: [
      {
        event: "61513908",
        market: "1",
        outcome: "1",
        type: "uf",
      },
    ],
  };
}

async function getDataCashBackSelections(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataCashBackSelections(data) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  return {
    events: data.events.map((event) => {event: event.id, type: event.type}),
  }
  */

  return {
    events: [
      {
        event: "56418457",
        type: "uf",
      },
    ],
  };
}

async function getDataTickets(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataTickets(data) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  return {
    tickets: data.tickets.map((ticket) => {
      ticketId: ticket.id,
      bets: ticket.bets.map((bet) => {
        betId: bet.id,
        selections: bet.selections.map((selection) => {
          type: selection.type,
          eventId: selection.eventId,
          marketId: selection.marketId,
          outcomeId: selection.outcomeId,
          odds: { type: selection.odds.type, value: selection.odds.value },
        }),
        odds: { type: bet.odds.type, value: bet.odds.value },
        stake: bet.stake.map((stake) => {
          type: stake.type,
          currency: stake.currency,
          amount: stake.amount,
          mode: stake.mode
        }),
      }),
      version: ticket.version,
    }),
  };
  */

  return {
    tickets: [
      {
        ticketId: "ticket_123456",
        bets: [
          {
            betId: "bet_001",
            selections: [
              {
          type: "uf",
          productId: "1",
          eventId: "sr:match:12345",
          marketId: "1",
          outcomeId: "1",
          odds: { type: "decimal", value: "2.10" },
          context: {
            eventName: "Manchester United vs Liverpool",
            marketName: "1x2",
            outcomeName: "Home",
            tournament: "Premier League",
            sportName: "Soccer",
            categoryName: "England",
            isLive: false,
            eventStartTime: "1738519200000",
            sportId: "1"
          }
        }
            ],
            odds: { type: "decimal", value: "2.10" },
            stake: [{
              type: "cash",
              currency: "USD",
              amount: "10.00",
              mode: "total"
            }],
            payout: [{ type: "cash", currency: "USD", amount: "21.00" }]
          }
        ],
        version: "2.0"
      }
    ]
  };
}

async function getDataMatchEventSuggestedSelection(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataMatchEventSuggestedSelection(data) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  return {
    selections: data.selections.map((selection) => {
      event: selection.event,
      market: selection.market,
      outcome: selection.outcome,
      type: selection.type,
      specifiers: selection.specifiers
    })
  };
  */

  return {
    selections: [
      { event: "sr:match:12345", market: "1", outcome: "1", type: "uf" },
      { event: "sr:match:12345", market: "18", specifiers: "total=2.5", type: "uf" }
    ]
  };
}

async function getDataRecommendedSelections(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataRecommendedSelections(data) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  return {
    selection: data.selections.map((selection) => {
      event: selection.event,
      market: selection.market,
      outcome: selection.outcome,
      type: selection.type,
      specifiers: selection.specifiers
    })
  };
  */

  return {
    selection: [
      { event: "sr:match:12345", market: "1", outcome: "1", type: "uf" },
      { event: "sr:match:67890", market: "18", specifiers: "total=2.5", outcome: "13", type: "uf" }
    ]
  };
}

async function getDataCalculateCustomBetXML(args) {
  // Here fetch data from your data source and return it
  return {};
}

function transformDataCalculateCustomBetXML(data) {
  // Here transform your data into data structure exemplified by the object below.
  /*
  // Illustration how data transformation might work from client data to Adapter types
  return {
    payload: '<xml>data</xml>',
  }
  */
  return {
    payload: `<filtered_calculation_response generated_at="2025-04-16T13:29:08+00:00">
                <calculation odds="27.50303106727931" probability="0.027418715351118873" harmonization="false"/>
                <available_selections>
                  <event id="sr:match:12345678">
                    <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>`
  };
}

// -------- Adapter --------

const adapter = {
  config: {},
  endpoints: {
    market: (args, callback) => {
      getDataMarket(args)
        .then(data => transformDataMarket(data))
        .then(result => callback(undefined, result));
      return () => {};
    },

    availableMarketsForEvent: (args, callback) => {
      getDataAvailableMarketsForEvent(args)
        .then(data => transformDataAvailableMarketsForEvent(data))
        .then(result => callback(undefined, result));
      return () => {};
    },

    eventMarkets: (args, callback) => {
      getDataEventMarkets(args)
        .then(data => transformDataEventMarkets(data, args))
        .then(result => callback(undefined, result));
      return () => {};
    },

    event: (args, callback) => {
      getDataEvent(args)
        .then(data => transformDataEvent(data, args))
        .then(result => callback(undefined, result));
      return () => {};
    },

    filterMarkets: (args, callback) => {
      getDataFilterMarkets(args)
        .then(data => transformDataFilterMarkets(data))
        .then(result => callback(undefined, result));
      return () => {};
    },

    betSlipSelection: (args, callback) => {
      getDataBetSlipSelection(args)
        .then(data => transformDataBetSlipSelection(data))
        .then(result => callback(undefined, result));
      return () => {};
    },

    cashBackSelections: (args, callback) => {
      getDataCashBackSelections(args)
        .then(data => transformDataCashBackSelections(data))
        .then(result => callback(undefined, result));
      return () => {};
    },

    tickets: (args, callback) => {
      getDataTickets(args)
        .then(data => transformDataTickets(data))
        .then(result => callback(undefined, result));
      return () => {};
    },

    matchEventSuggestedSelection: (args, callback) => {
      getDataMatchEventSuggestedSelection(args)
        .then(data => transformDataMatchEventSuggestedSelection(data))
        .then(result => callback(undefined, result));
      return () => {};
    },

    recommendedSelections: (args, callback) => {
      getDataRecommendedSelections(args)
        .then(data => transformDataRecommendedSelections(data))
        .then(result => callback(undefined, result));
      return () => {};
    },

    calculateCustomBetXML: (args, callback) => {
      getDataCalculateCustomBetXML(args)
        .then(data => transformDataCalculateCustomBetXML(data))
        .then(result => callback(undefined, result));
      return () => {};
    },
  },
};
</script>
```

## Adapter Endpoints

### Market Function

Retrieves data for a specific market of a specific event.

> **Tip**
>
> The `market` and `eventMarkets` endpoints are **mutually exclusive** – you only need to implement **ONE**. If your API does not support fetching individual markets, consider using the eventMarkets endpoint instead.

> **Warning**
>
> Names such as market names, outcome names, and other text content should be provided in the language specified by `args.language` to ensure proper localization for users.
>
> The `oddsType` parameter specifies the current format of odds set for the widget. If you provide odds in a different format, consider updating the odds type in the widget loader configuration. See the [Global SIR API documentation](https://apidocs.sportradar.com/resources/widgets/docs/tutorials/SIR.md) for details on configuring odds formats.

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

| Argument | Type                                                                                                                                                                                                      | Required | Description                                                                    |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------ |
| args     | [`MarketRequest`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#marketrequest)                                                                                                   | yes      | Request parameters including market/outcome selection, language, and odds type |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`MarketResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#marketresponse)> | yes      | Function to receive market data 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.market = (args, callback) => {
  // args example:
  // {
  //   selection: { event: "sr:match:123", market: "18", specifiers: "total=2.5", type: 'uf' },
  //   language: "en",
  //   oddsType: "decimal"
  // }

  // Your implementation here - fetch specific market data based on args
  // Then call callback with the result
  callback(undefined, {
    market: {
    id: "1",
    name: "Match Winner (1X2)",
    outcomes: [
      { id: "1", name: "Home", status: "active", odds: { type: "decimal", value: "2.10" } },
      { id: "X", name: "Draw", status: "active", odds: { type: "decimal", value: "3.40" } },
      { id: "2", name: "Away", status: "active", odds: { type: "decimal", value: "3.50" } }
    ],
    status: "active"
  },
    event: "sr:match:12345"
  });

  // Return optional unsubscribe function
  return () => {
    // Cleanup subscriptions if needed
  };
};
```

### EventMarkets Function

Retrieves data for all markets of a specific event.

> **Tip**
>
> The `eventMarkets` and `market` endpoints are **mutually exclusive** – you only need to implement **ONE**. If your API does not support fetching all markets for requested event, consider using the market endpoint instead.

> **Warning**
>
> Names such as market names, outcome names, and other text content should be provided in the language specified by `args.language` to ensure proper localization for users.
>
> The `oddsType` parameter specifies the current format of odds set for the widget. If you provide odds in a different format, consider updating the odds type in the widget loader configuration. See the [Global SIR API documentation](https://apidocs.sportradar.com/resources/widgets/docs/tutorials/SIR.md) for details on configuring odds formats.

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

| Argument | Type                                                                                                                                                                                                                  | Required | Description                                                           |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------- |
| args     | [`EventMarketsRequest`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#eventmarketsrequest)                                                                                                   | yes      | Request parameters including event selection, language, and odds type |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`EventMarketsResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#eventmarketsresponse)> | yes      | Function to receive markets data 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.eventMarkets = (args, callback) => {
  // args example:
  // {
  //   selection: { event: "sr:match:12345", type: "uf" },
  //   language: "en",
  //   oddsType: "decimal"
  // }

  // Your implementation here - fetch markets data based on args
  // Then call callback with the result
  callback(undefined, {
    markets: [
       {
        id: "18",
        name: "Total Goals",
        specifiers: "total=2.5",
        outcomes: [
          { id: "12", name: "Over 2.5", status: "active", odds: { type: "decimal", value: "1.85" } },
          { id: "13", name: "Under 2.5", status: "active", odds: { type: "decimal", value: "2.05" } }
        ],
        status: "active"
      },
      // ... other of market objects ofr this event
    ],
    event: "sr:match:12345" // Event should match args.selection.id, else it will get discarded
  });

  // Return optional unsubscribe function
  return () => {
    // Cleanup subscriptions if needed
  };
};
```

### Event Function

Retrieves detailed event data including event start time, scores, team names, tournament name, and more.

> **Warning**
>
> Names such as team names, tournament names, and other text content should be provided in the language specified by `args.language`. Event times should be converted and displayed in the timezone specified by `args.displayedTimezone` to ensure proper localization for users.

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

| Argument | Type                                                                                                                                                                                                     | Required | Description                                                          |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------- |
| args     | [`EventRequest`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#eventrequest)                                                                                                    | yes      | Request parameters including event selection and display preferences |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`EventResponse>`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#eventresponse)> | yes      | Function to receive event data 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.event = (args, callback) => {
  // args example:
  // {
  //   selection: { event: "sr:match:12345", type: "uf" },
  //   language: "en",
  //   displayedTimezone: "Europe:Berlin"
  // }

  // Your implementation here - fetch event data based on args
  // Then call callback with the result
  callback(undefined, {
    event: {
      id: "sr:match:12345" // Id should match event given in arguments - args.selection.id,
      // ... other event properties
    }
  });

  // Return optional unsubscribe function
  return () => {
    // Cleanup subscriptions if needed
  };
};
```

### AvailableMarketsForEvent Function

Retrieves all available market offering in Selection format for a requested event. Only called when implementing the `market` endpoint (not used with `eventMarkets`).

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

| Argument | Type                                                                                                                                                                                                                                          | Required | Description                                    |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------- |
| args     | [`AvailableMarketsForEventRequest`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#availablemarketsforeventrequest)                                                                                                   | yes      | Request parameters including event selection   |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`AvailableMarketsForEventResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#availablemarketsforeventresponse)> | yes      | Function to receive available markets 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.availableMarketsForEvent = (args, callback) => {
  // args example:
  // {
  //   selection: { event: "sr:match:12345", type: "uf" }
  // }

  // Your implementation here - fetch available markets for the event
  // Then call callback with the result
  callback(undefined, {
    selection: [
      { event: "sr:match:12345", market: "1", type: "uf" },
      { event: "sr:match:12345", market: "18", specifiers: "total=1.5" type: "uf" },
      { event: "sr:match:12345", market: "18", specifiers: "total=2.5" type: "uf" },
      // ... other market offering selections
    ]
  });

  // Return optional unsubscribe function
  return () => {
    // Cleanup subscriptions if needed
  };
};
```

### FilterMarkets Function

This endpoint is called to perform additional filtering based on widget-specific requirements or other parameters. The `widget` property in the request arguments identifies which widget is requesting the filtering, allowing you to customize market filtering logic per widget. If no filtering is required, you can simply return the input selections unchanged. Example: For Swipe Bet you only want to use market 1x2 out of all available.

**Used by:** `betRecommendation.highlights`, `betRecommendation.eventList`, `betRecommendation.swipeBet`, `betRecommendation.similarBets`

The `widget` argument value passed by each widget:

- `betRecommendation.highlights` and `betRecommendation.similarBets` → `"betRecommendation"`
- `betRecommendation.eventList` → `"betRecommendation.eventList"`
- `betRecommendation.swipeBet` → `"betRecommendation.swipeBet"`

| Argument | Type                                                                                                                                                                                                                    | Required | Description                                                            |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------- |
| args     | [`FilterMarketsRequest`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#filtermarketsrequest)                                                                                                   | yes      | Request parameters including widget name and optional event selections |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`FilterMarketsResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#filtermarketsresponse)> | yes      | Function to receive filtered markets 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.filterMarkets = (args, callback) => {
  // args example:
  // {
  //   widget: "swipeBet",
  //   selection: [
  //     { event: "sr:match:12345", type: "uf", market: "1" },
  //     { event: "sr:match:12345", type: "uf", market: "18", specifiers: "total=2.5" }
  //   ]
  // }

  // Your implementation here - filter markets based on widget and selections
  // Then call callback with the result
  // callback(undefined, {
  //   selection: [
  //     { market: "sr:match:12345", type: "uf", market: "1" },
  //     // ... filtered selections
  //   ]
  // });

  // Or just return the selection if you don't wish to filter
  callback(undefined, {
    selection: args.selection
  });

  // Return optional unsubscribe function
  return () => {
    // Cleanup subscriptions if needed
  };
};
```

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

### CashBackSelections Function

Retrieves selections eligible for cash back promotions.

**Used by:** `betRecommendation.highlights`, `betRecommendation.eventList`, `betRecommendation.swipeBet`, `betRecommendation.similarBets`

| Argument | Type                                                                                                                                                                                                                              | Required | Description                                                   |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------- |
| args     | [`CashBackSelectionsRequest`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#cashbackselectionsrequest)                                                                                                   | yes      | Request parameters including widget name and event selections |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`CashBackSelectionsResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#cashbackselectionsresponse)> | yes      | Function to receive cash back 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.cashBackSelections = (args, callback) => {
  // args example:
  // {
  //   widget: "cashBack",
  //   selection: [
  //     { event: "sr:match:12345", type: "uf" },
  //     { event: "sr:match:67890", type: "uf" }
  //   ]
  // }

  // Your implementation here - fetch cash back eligible events
  // Then call callback with the result
  callback(undefined, {
    events: [
      { event: "sr:match:12345", type: "uf" },
      // ... events eligible for cash back
    ]
  });

  // Return optional unsubscribe function
  return () => {
    // Cleanup subscriptions if needed
  };
};
```

### Tickets Function

Retrieves the bettor's placed tickets (bets).

The callback receives a [`TicketsResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketsresponse): prefer [`TicketResponseV2`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketresponsev2). Deprecated [`BetShareResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betshareresponse-deprecated) remains supported for legacy integrations.

**Used by:** bet-sharing flows in **Virtual Stadium** (chat bet-share picker) and **Central Hub** (share-betslip list). Both consume the same adapter contract via the internal `betShare` feed, which maps to your `tickets` endpoint.

| Argument | Type                                                                                                                                                                                                        | Required | Description                                                                                                                              |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| args     | [`TicketsRequest`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketsrequest)                                                                                                   | yes      | Request parameters: `endCustomerId` and optional `events` / `channelId` filters                                                          |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`TicketsResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketsresponse)> | yes      | Function **you** call to deliver ticket data to the widget. Store it if you need to deliver additional pages (Option B pagination only). |

**Returns:** [`UnsubscribeFunction`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#unsubscribefunction) — optional cleanup function the widget calls when the bet-share picker closes or the widget unmounts.

> **Who calls callback?**
>
> The widget calls your `tickets(args, callback)` function once when the bet-share picker opens. **You** (your adapter code, or your embed-page handler after `onAction` `ticketsFetchMore`) call `callback(undefined, data)` to deliver data to the widget.
>
> For Option A, call `callback` once with the full list. For Option B, call it for the first page, then again with `newTickets` after `ticketsFetchMore`. Return an unsubscribe function to cancel any in-flight fetch when the picker closes.

#### Two ways to implement the tickets endpoint

Choose **one** of the following patterns. Both use the same `tickets(args, callback)` signature.

|                       | **Option A — Non-paginated**                                           | **Option B — Paginated**                                                                                             |
| --------------------- | ---------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| **When to use**       | Small ticket lists; your backend can return everything at once         | Large ticket histories; your backend loads in batches                                                                |
| **First callback**    | `{ tickets: Ticket[] }` — complete list                                | `{ tickets, pageSize, hasMore, nextCursor }` — first batch only                                                      |
| **Further callbacks** | Usually none — single `{ tickets }` emission is tested and recommended | You call the **stored** `callback` with `{ newTickets, hasMore?, nextCursor? }` after `onAction` `ticketsFetchMore`  |
| **Widget behaviour**  | Renders the full list immediately                                      | Detects paginated mode from `pageSize` / `hasMore`; fires `onAction` `ticketsFetchMore` when the next page is needed |

> **Pagination does not call tickets() again**
>
> Paginated delivery does not trigger a second `tickets(args, callback)` invocation, and there is no dedicated adapter endpoint for additional pages. Retain the `callback` reference from the initial `tickets()` call. When the widget emits `onAction` `ticketsFetchMore`, your embed-page handler fetches the next batch from your backend and delivers it through that stored `callback` as `{ newTickets, hasMore?, nextCursor? }`.

For a full step-by-step walkthrough of both options, see the [Adapter Tickets Endpoint Example](https://apidocs.sportradar.com/resources/widgets/docs/tutorials/examples/adapter-tickets-endpoint-example.md).

***

##### Option A — Non-paginated (all tickets immediately)

Use when you can return the user's full open-ticket list in a single response.

```mermaid
sequenceDiagram
  participant Widget as Widget
  participant Adapter as ClientAdapter

  Widget->>Adapter: tickets(args, callback)
  Adapter-->>Widget: callback(undefined, { tickets: [all tickets] })
  Note over Widget: Renders full list. No pagination.

  Widget->>Adapter: unsubscribe()
```

| Step | Who          | Action                                                                      |
| ---- | ------------ | --------------------------------------------------------------------------- |
| 1    | Widget stack | Calls your `tickets(args, callback)` once                                   |
| 2    | Your adapter | Fetches all tickets from your backend                                       |
| 3    | Your adapter | Calls `callback(undefined, { tickets: [...] })` once with the complete list |
| 4    | Widget       | Renders all tickets immediately                                             |
| 5    | Your adapter | Returns unsubscribe function; widget calls it on unmount                    |

```javascript
// Option A — non-paginated (recommended)
adapter.endpoints.tickets = (args, callback) => {
  fetchAllUserTickets(args.endCustomerId, args.events, (error, allTickets) => {
    if (error) {
      return callback(error);
    }
    callback(undefined, { tickets: allTickets });
  });

  return () => {
    // Cancel any in-flight fetch
  };
};
```

***

##### Option B — Paginated (widget requests next page via callback)

Use when ticket histories are large. Signal paginated mode on the **first** callback with `pageSize` and `hasMore`. Subsequent pages are delivered as `newTickets` when **you** call the stored `callback` after the widget fires `onAction` `ticketsFetchMore`.

```mermaid
sequenceDiagram
  participant Widget as Widget
  participant Page as EmbedPage_onAction
  participant Adapter as ClientAdapter

  Widget->>Adapter: tickets(args, callback)
  Adapter-->>Widget: callback(undefined, { tickets: [page1], pageSize: 20, hasMore: true, nextCursor: "c1" })
  Note over Widget: Detects paginated mode.

  Widget->>Page: onAction ticketsFetchMore { cursor: "c1" }
  Page->>Adapter: loadMoreTickets("c1")
  Adapter-->>Widget: callback(undefined, { newTickets: [page2], hasMore: true, nextCursor: "c2" })
  Note over Widget: Appends page 2.

  Widget->>Page: onAction ticketsFetchMore { cursor: "c2" }
  Page->>Adapter: loadMoreTickets("c2")
  Adapter-->>Widget: callback(undefined, { newTickets: [page3], hasMore: false })
  Note over Widget: Appends page 3. End of list.

  Widget->>Adapter: unsubscribe()
```

| Step | Who          | Action                                                                                                                           |
| ---- | ------------ | -------------------------------------------------------------------------------------------------------------------------------- |
| 1    | Widget       | Calls `tickets(args, callback)`                                                                                                  |
| 2    | Your adapter | Fetches the first page; calls `callback(undefined, { tickets: [batch], pageSize, hasMore, nextCursor })`                         |
| 3    | Widget       | Detects paginated mode; renders the first batch                                                                                  |
| 4    | Widget       | Needs the next page; fires `onAction({ type: 'ticketsFetchMore', data: { cursor } })`                                            |
| 5    | Embed page   | `onAction` handler calls your backend with the cursor                                                                            |
| 6    | Your adapter | Calls the **stored** `callback` from step 2 with `{ newTickets: [...], hasMore, nextCursor }` — not a new `tickets()` invocation |
| 7    | Widget       | Appends new tickets; repeats steps 4–6 until `hasMore: false`                                                                    |

```javascript
// Option B — paginated (adapter side)
let ticketsCallback = null;

adapter.endpoints.tickets = (args, callback) => {
  ticketsCallback = callback;

  fetchTicketPage(args.endCustomerId, null, (error, page) => {
    if (error) {
      return callback(error);
    }
    callback(undefined, {
      tickets: page.items,
      pageSize: page.pageSize,
      hasMore: page.hasMore,
      nextCursor: page.nextCursor
    });
  });

  return () => {
    ticketsCallback = null;
  };
};

// Called from your onAction handler when the widget requests the next page
function loadMoreTickets(cursor) {
  if (!ticketsCallback) {
    return;
  }
  fetchTicketPage(currentCustomerId, cursor, (error, page) => {
    if (error) {
      return ticketsCallback(error);
    }
    ticketsCallback(undefined, {
      newTickets: page.items,
      hasMore: page.hasMore,
      nextCursor: page.nextCursor
    });
  });
}
```

```javascript
// Option B — embed page onAction handler
SIR('addWidget', '#sr-vs-widget', 'virtualStadium', {
  onAction: function(action) {
    if (action.type === 'ticketsFetchMore') {
      loadMoreTickets(action.data?.cursor);
    }
  }
});
```

***

##### Response fields (callback payload)

Deliver data on the **same** `callback` passed to `tickets(args, callback)`. Do not call `tickets()` again for page 2+.

| Field                               | Option A                                  | Option B                         | Verified                  |
| ----------------------------------- | ----------------------------------------- | -------------------------------- | ------------------------- |
| `tickets`                           | Single emission with the full list        | First page only                  | Yes (Option A tested)     |
| `newTickets`                        | Not used — return everything in `tickets` | Next pagination page             | Option B: yes (VS tested) |
| `pageSize`, `hasMore`, `nextCursor` | Not used                                  | First-page pagination signalling | Option B: yes             |

```javascript
// Option B — next page (verified in VS)
callback(undefined, { newTickets: [/* page 2 */], hasMore: false });
```

***

##### Selection context enrichment

If a [`TicketSelection`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselection) omits `context` (`marketName`, `outcomeName`, `eventName`), the widget attempts to resolve display names via your `event` and `eventMarkets` adapter endpoints. Tickets that cannot be resolved may be hidden from the share picker.

> **Tip**
>
> Provide [`TicketSelectionContext`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselectioncontext) on every selection so tickets remain readable after market data ages out. See the [`TicketSelection`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselection) section for field details.

### MatchEventSuggestedSelection Function

Retrieves suggested selections for a specific match event (incident).

**Used by:** `virtualStadium`

| Argument | Type                                                                                                                                                                                                                                                  | Required | Description                                                                             |
| -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------- |
| args     | [`MatchEventSuggestedSelectionRequest`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#matcheventsuggestedselectionrequest)                                                                                                   | yes      | Request parameters including match event, event selection, and optional suggestion hint |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`MatchEventSuggestedSelectionResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#matcheventsuggestedselectionresponse)> | yes      | Function to receive suggested 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.matchEventSuggestedSelection = (args, callback) => {
  // args example:
  // {
  //   matchEvent: { type: "GOAL", metadata: { goal_number: "2" } },
  //   event: { event: "sr:match:12345", type: "uf" },
  //   widget: "liveMatchTracker",
  //   suggestion: {
  //     type: "Outcome",
  //     selections: [
  //       { event: "sr:match:12345", market: "1", outcome: "1", type: "uf" }
  //     ]
  //   },
  //   channelId: "euro-league",
  //   channelOriginId: "channel-child-id"
  // }

  // Your implementation here - fetch suggested selections for the match event
  // Then call callback with the result
  callback(undefined, {
    selections: [
      { event: "sr:match:12345", market: "1", outcome: "1", type: "uf" }
    ]
  });

  // Return optional unsubscribe function
  return () => {
    // Cleanup subscriptions if needed
  };
};
```

### RecommendedSelections Function

Retrieves recommended selections for a given event.

**Used by:** `betConcierge`

| Argument | Type                                                                                                                                                                                                                                    | Required | Description                                         |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------- |
| args     | [`RecommendedSelectionsRequest`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#recommendedselectionsrequest)                                                                                                   | yes      | Request parameters including event selections       |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`RecommendedSelectionsResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#recommendedselectionsresponse)> | yes      | Function to receive recommended 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.recommendedSelections = (args, callback) => {
  // args example:
  // {
  //   events: [
  //     { event: "sr:match:12345", type: "uf" }
  //   ]
  // }

  // Your implementation here - fetch recommended selections for the given events
  // Then call callback with the result
  callback(undefined, {
    selection: [
      { event: "sr:match:12345", market: "1", outcome: "1", type: "uf" }
    ]
  });

  // Return optional unsubscribe function
  return () => {
    // Cleanup subscriptions if needed
  };
};
```

### CalculateCustomBetXML Function

Calculates custom bet XML for given markets and match.

**Used by:** `betConcierge`

| Argument | Type                                                                                                                                                                                                                                    | Required | Description                                         |
| -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------- |
| args     | [`CalculateCustomBetXmlRequest`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#calculatecustombetxmlrequest)                                                                                                   | yes      | Request parameters containing the calculate payload |
| callback | [`Callback`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)<[`CalculateCustomBetXmlResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#calculatecustombetxmlresponse)> | yes      | Function to receive the resulting payload 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.calculateCustomBetXML = (args, callback) => {
  // args example:
  // {
  //   calculatePayload: "<filterSelections>...</filterSelections>"
  // }

  // Your implementation here - calculate custom bet XML and return result
  // Then call callback with the result
  callback(undefined, {
    payload: "<filtered_calculation_response>...</filtered_calculation_response>"
  });

  // Return optional unsubscribe function
  return () => {
    // Cleanup subscriptions if needed
  };
};
```

## Utility Types

### Callback\<T>

Error-first callback function pattern used by all adapter endpoints.

| Property | Type                 | Required | Description                                                      |
| -------- | -------------------- | -------- | ---------------------------------------------------------------- |
| error    | `Error \| undefined` | yes      | Error object if the operation failed, or undefined if successful |
| data     | `T \| undefined`     |          | Response data if successful, or undefined if an error occurred   |

**Type Parameters:**

- `T` - The type of data returned on success

```javascript
// Type-specific example with BetSlipSelectionResponse
betSlipSelection(args, callback) {
  // other code

  if (error) {
    // something went wrong, return error
    callback(error)
    return;
  }
  // Operation successful, return BetSlipSelectionResponse
  callback(undefined, { selection: { event: "sr:match:12345", market: "18", outcome: "1", odds: { type: "fractional", value: "3.2", numerator: "6", denominator: "4" }} })

  // rest of code
}

```

### UnsubscribeFunction

Optional cleanup function returned by adapter endpoints to stop receiving updates.

**Type:** `(() => void) | undefined`

When an adapter endpoint returns an `UnsubscribeFunction`, you can call it to stop receiving further callback invocations. This is useful for:

- Cleaning up subscriptions when a component unmounts
- Stopping live data updates when they are no longer needed
- Managing memory and preventing memory leaks

```javascript
endpoint(args, callback) {
  // code
  return () => {
    // Implement unsubscribe logic, e.g., remove event listener, cancel subscription
    subscription.unsubscribe();
  }
}
```

**See Also:** [`Callback<T>`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#callbackt)

## Request Types

### EventRequest

Request parameters for fetching event data.

| Property          | Type                                                                                                      | Required | Description                                                                  |
| ----------------- | --------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------- |
| selection         | [`SelectionEvent`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent) | yes      | Event identifier in UF or external format                                    |
| language          | `string`                                                                                                  |          | Language code for localized content (e.g., "en", "de")                       |
| displayedTimezone | `string`                                                                                                  |          | Timezone for displaying event times (e.g., "Europe:Berlin", "Europe/London") |

```javascript
// Example usage
const eventRequest = {
  selection: { event: "sr:match:12345", type: "uf" },
  language: "en",
  displayedTimezone: "Europe:Berlin"
};

// With minimal properties
const minimalRequest = {
  selection: { event: "sr:match:67890", type: "uf" }
};
```

### EventMarketsRequest

Request parameters for fetching all markets data for a specific event.

| Property  | Type                                                                                                      | Required | Description                                                                                                     |
| --------- | --------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| selection | [`SelectionEvent`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent) | yes      | Event identifier in UF or external format                                                                       |
| language  | `string`                                                                                                  |          | Language code for localized content (e.g., "en", "de")                                                          |
| oddsType  | `string`                                                                                                  |          | Type of odds to display. Valid values: 'decimal', 'fractional', 'moneyline', 'hong-kong', 'indonesian', 'malay' |

```javascript
// Example usage
const eventMarketsRequest = {
  selection: { event: "sr:match:12345", type: "uf" },
  language: "en",
  oddsType: "decimal"
};

// With minimal properties
const minimalRequest = {
  selection: { event: "sr:match:67890", type: "uf" }
};
```

### MarketRequest

Request parameters for fetching a specific market data for an event.

| Property  | Type                                                                                                                                                                                                                         | Required | Description                                                                                                     |
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------- |
| selection | [`SelectionMarket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionmarket) \| [`SelectionOutcome`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionoutcome) | yes      | Market or outcome identifier to fetch                                                                           |
| language  | `string`                                                                                                                                                                                                                     | yes      | Language code for localized content (e.g., "en", "de")                                                          |
| oddsType  | `string`                                                                                                                                                                                                                     | yes      | Type of odds to display. Valid values: 'decimal', 'fractional', 'moneyline', 'hong-kong', 'indonesian', 'malay' |

```javascript
// Example usage with market selection
const marketRequest = {
  selection: { event: "sr:match:12345", market: "1", type: "uf" },
  language: "en",
  oddsType: "decimal"
};

// Example with outcome selection
const outcomeRequest = {
  selection: { event: "sr:match:12345", market: "1", outcome: "1", type: "uf" },
  language: "en",
  oddsType: "moneyline"
};
```

### AvailableMarketsForEventRequest

Request parameters for fetching all available markets for a specific event.

| Property  | Type                                                                                                      | Required | Description                               |
| --------- | --------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------- |
| selection | [`SelectionEvent`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent) | yes      | Event identifier in UF or external format |

```javascript
// Example usage
const availableMarketsRequest = {
  selection: { event: "sr:match:12345", type: "uf" }
};
```

### FilterMarketsRequest

Request parameters for filtering markets based on widget configuration.

| Property  | Type                                                                                                          | Required | Description                                                                                    |
| --------- | ------------------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------- |
| widget    | `string`                                                                                                      | yes      | Widget identifier to determine which markets to filter (e.g., "swipeBet", "betRecommendation") |
| selection | [`SelectionMarket[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionmarket) |          | Optional array of market identifiers to filter markets                                         |

```javascript
// Example usage with events
const filterMarketsRequest = {
  widget: "swipeBet",
  selection: [
    { event: "sr:match:12345", type: "uf", market: "1" },
    { event: "sr:match:67890", type: "uf", market: "18", specifiers: "total=2.5" }
  ]
};

// Example with widget only
const simpleRequest = {
  widget: "betRecommendation"
};
```

### TicketsRequest

Request parameters for fetching tickets.

| Property      | Type                                                                                                        | Required | Description                                                              |
| ------------- | ----------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------ |
| endCustomerId | `string`                                                                                                    | yes      | End user/customer identifier                                             |
| events        | [`SelectionEvent[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent) |          | Optional array of event identifiers to filter tickets by specific events |
| channelId     | `string`                                                                                                    |          | Optional channel identifier (used by Virtual Stadium bet-share flows)    |

```javascript
// Example usage with all properties
const ticketsRequest = {
  endCustomerId: "customer456",
  events: [
    { event: "sr:match:12345", type: "uf" }
  ],
  channelId: "euro-league"
};

// Example with minimal properties
const minimalRequest = {
  endCustomerId: "customer456"
};
```

### MatchEventSuggestedSelectionRequest

Request parameters for fetching suggested selections for a specific match event (incident).

| Property            | Type                                                                                                                                                                                                                             | Required | Description                                                                                                                                                                   |
| ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| matchEvent          | [`MatchEvent`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#matchevent)                                                                                                                                | yes      | Match event (incident) information                                                                                                                                            |
| event               | [`SelectionEvent`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent)                                                                                                                        | yes      | Event identifier in UF or external format                                                                                                                                     |
| widget              | `string`                                                                                                                                                                                                                         | yes      | Widget making this request                                                                                                                                                    |
| type                | `'outcome'` \| `'market'`                                                                                                                                                                                                        |          | Optional instruction indicating the selection form the client expects. When provided, the adapter is expected to return selections of the requested form (see details below). |
| suggestedSelections | [`SelectionOutcome[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionoutcome) \| [`SelectionMarket[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionmarket) |          | Optional suggested selections for the match event. Use outcome array when `type` is `'outcome'`, market array when `type` is `'market'`.                                      |
| channelId           | `string`                                                                                                                                                                                                                         |          | Current viewing channel identifier                                                                                                                                            |
| channelOriginId     | `string`                                                                                                                                                                                                                         |          | Channel from which the match event originated (e.g., when the widget is opened on a tournament channel that received the event from a child channel)                          |

#### `type` and `suggestedSelections`

The `type` field is an optional instruction indicating which selection form the client expects. When provided, the adapter is expected to return selections matching that form:

- `'outcome'`: response should contain outcome-level selections (`SelectionOutcome[]`).
- `'market'`: response should contain market-level selections (`SelectionMarket[]`).

The `suggestedSelections` property carries the actual suggested selections and should match the `type` when both are provided.

```javascript
// Example usage preferring outcome-level selections
const requestWithOutcomeSuggestion = {
  matchEvent: { type: "GOAL", metadata: { goal_number: "2" } },
  event: { event: "sr:match:12345", type: "uf" },
  widget: "flashBet",
  type: "outcome",
  suggestedSelections: [
    { event: "sr:match:12345", market: "1", outcome: "1", type: "uf" }
  ],
  channelId: "euro-league",
  channelOriginId: "channel-child-id"
};

// Example usage preferring market-level selections
const requestWithMarketSuggestion = {
  matchEvent: { type: "GOAL", metadata: { goal_number: "2" } },
  event: { event: "sr:match:12345", type: "uf" },
  widget: "flashBet",
  type: "market",
  suggestedSelections: [
    { event: "sr:match:12345", market: "1", type: "uf" }
  ]
};

// Example with minimal properties (no suggestion)
const minimalRequest = {
  matchEvent: { type: "GOAL" },
  event: { event: "sr:match:12345", type: "uf" },
  widget: "flashBet"
};
```

### RecommendedSelectionsRequest

Request parameters for fetching recommended selections for given events.

| Property | Type                                                                                                        | Required | Description                                                             |
| -------- | ----------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------- |
| events   | [`SelectionEvent[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent) | yes      | Array of event identifiers for which to retrieve recommended selections |

```javascript
// Example usage
const recommendedSelectionsRequest = {
  events: [
    { event: "sr:match:12345", type: "uf" },
    { event: "sr:match:67890", type: "uf" }
  ]
};
```

### CalculateCustomBetXmlRequest

Request parameters for calculating custom bet XML.

| Property         | Type     | Required | Description                                                     |
| ---------------- | -------- | -------- | --------------------------------------------------------------- |
| calculatePayload | `string` | yes      | XML payload string used as input for the custom bet calculation |

```javascript
// Example usage
const calculateCustomBetXmlRequest = {
  calculatePayload: `<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>`
};
```

## Response Types

### EventResponse

Response data containing event information.

| Property | Type                                                                                    | Required | Description                                                               |
| -------- | --------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------- |
| event    | [`Event`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#event) | yes      | Complete event data including details, status, participants, and metadata |

```javascript
// Example response structure
const eventResponse = {
  event: {
    id: "sr:match:12345",
    sport: { id: "1", name: "Soccer" },
    category: { id: "1", name: "England" },
    tournament: { id: "17", name: "Premier League" },
    teams: [
      { id: "sr:competitor:1", name: "Manchester United" },
      { id: "sr:competitor:2", name: "Liverpool" }
    ],
    isLive: false,
    // ... additional event properties
  }
};
```

### EventMarketsResponse

Response data containing all markets for an event.

| Property | Type                                                                                        | Required | Description                                      |
| -------- | ------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------ |
| markets  | [`Market`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#market)[] | yes      | Array of market data for the event               |
| event    | `string`                                                                                    | yes      | Event identifier string (e.g., "sr:match:12345") |

```javascript
// Example response structure
const eventMarketsResponse = {
  markets: [
     {
      id: "18",
      name: "Total Goals",
      specifiers: "total=2.5",
      outcomes: [
        { id: "12", name: "Over 2.5", status: "active", odds: { type: "decimal", value: "1.85" } },
        { id: "13", name: "Under 2.5", status: "active", odds: { type: "decimal", value: "2.05" } }
      ],
      status: "active"
    },
    // ... additional markets
  ],
  event: "sr:match:12345"
};
```

### MarketResponse

Response data containing a specific market and event information.

| Property | Type                                                                                      | Required | Description                                      |
| -------- | ----------------------------------------------------------------------------------------- | -------- | ------------------------------------------------ |
| market   | [`Market`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#market) | yes      | Market data including outcomes and odds          |
| event    | `string`                                                                                  | yes      | Event identifier string (e.g., "sr:match:12345") |

```javascript
// Example response structure
const marketResponse = {
  market: {
    id: "sr:market:1",
    name: "Match Winner",
    outcomes: [
      { id: "1", name: "Home", odds: 2.5 },
      { id: "X", name: "Draw", odds: 3.0 },
      { id: "2", name: "Away", odds: 3.2 }
    ]
  },
  event: "sr:match:12345"
};
```

### AvailableMarketsForEventResponse

Response data containing all available market offering as selections for an event.

| Property  | Type                                                                                                          | Required | Description                                                   |
| --------- | ------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------- |
| selection | [`SelectionMarket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionmarket)[] | yes      | Array of market selection identifiers available for the event |

```javascript
// Example response structure
const availableMarketsResponse = {
  selection: [
    { event: "sr:event:1", market: "1" },
    { event: "sr:event:1", market: "18", specifiers: "total=2.5" },
    { event: "sr:event:1", market: "10" }
  ]
};
```

### FilterMarketsResponse

Response data containing filtered market selections based on the widget identifier and input selections.

| Property  | Type                                                                                                          | Required | Description                                                        |
| --------- | ------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------ |
| selection | [`SelectionMarket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionmarket)[] | yes      | Array of event or market selections that match the filter criteria |

```javascript
// Example response structure
const filterMarketsResponse = {
  selection: [
    { event: "sr:match:12345", type: "uf", market: "1" },
    { event: "sr:match:12345", type: "uf", market: "18", specifiers: "total=2.5" }
  ]
};
```

### BetSlipSelectionResponse

Response data containing currently selected outcomes in the bet slip.

| Property  | Type                                                                                                            | Required | Description                                           |
| --------- | --------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------- |
| selection | [`SelectionOutcome`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionoutcome)[] | yes      | Array of outcome selections currently in the bet slip |

```javascript
// Example response structure
const betSlipSelectionResponse = {
  selection: [
    { event: "sr:match:12345", market: "1", outcome: "2", odds: { type: "decimal", value: "1.95" } },
      { event: "sr:match:12345", market: "18", outcome: "1", odds: { type: "fractional", value: "3.2", numerator: "6", denominator: "4" }}
  ]
};
```

### CashBackSelectionsRequest

Request parameters for fetching cash back selections.

| Property  | Type                                                                                                        | Required | Description                                                         |
| --------- | ----------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------- |
| widget    | `string`                                                                                                    | yes      | Widget identifier to determine the context of the cash back request |
| selection | [`SelectionEvent[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent) | yes      | Array of event selections to check for cash back eligibility        |

```javascript
// Example usage
const cashBackSelectionsRequest = {
  widget: "cashBack",
  selection: [
    { event: "sr:match:12345", type: "uf" },
    { event: "sr:match:67890", type: "uf" }
  ]
};
```

### CashBackSelectionsResponse

Response data containing events eligible for cash back.

| Property | Type                                                                                                        | Required | Description                                                          |
| -------- | ----------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------- |
| events   | [`SelectionEvent`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent)[] | yes      | Array of event selections that are eligible for cash back promotions |

```javascript
// Example response structure
const cashBackSelectionsResponse = {
  events: [
    { event: "sr:match:12345", type: "uf" },
    { event: "sr:match:67890", type: "uf" }
  ]
};
```

### TicketsResponse

Union type for the `tickets` endpoint callback result. Return **either** [`TicketResponseV2`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketresponsev2) (recommended) **or** deprecated [`BetShareResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betshareresponse-deprecated). The shapes are mutually exclusive: provide `tickets` or `bets`, never both.

| Shape                                                                                                                    | Discriminator                                         | Description                                             |
| ------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | ------------------------------------------------------- |
| [`TicketResponseV2`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketresponsev2)            | `tickets`, `newTickets`, or pagination fields present | Current ticket format based on the v2 ticket schema     |
| [`BetShareResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betshareresponse-deprecated) | `bets` present                                        | **Deprecated.** Legacy Virtual Stadium bet-share format |

**See Also:** [`Tickets Function`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#tickets-function), [`TicketResponseV2`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketresponsev2), [`BetShareResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betshareresponse-deprecated)

### TicketResponseV2

Current response shape for the `tickets` endpoint. See [Two ways to implement the tickets endpoint](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#tickets-function) for the full non-paginated vs paginated flow.

| Property   | Type                                                                                        | Required            | Used in  | Description                                                                                                                                                                               |
| ---------- | ------------------------------------------------------------------------------------------- | ------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| tickets    | [`Ticket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticket)[] | On first emission   | Both     | Full ticket list (Option A) or first page (Option B). Omit on subsequent paginated emissions — use `newTickets` instead.                                                                  |
| pageSize   | `number`                                                                                    | When paginating     | Option B | Page size signalled to the widget (for example `20`). Presence of `pageSize` or `hasMore` switches the widget into paginated mode.                                                        |
| hasMore    | `boolean`                                                                                   | When paginating     | Option B | `true` when more batches are available; `false` on the final page.                                                                                                                        |
| nextCursor | `string`                                                                                    | When paginating     | Option B | Opaque cursor your backend uses to fetch the next batch. Passed back via `onAction` `ticketsFetchMore`.                                                                                   |
| newTickets | [`Ticket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticket)[] | On subsequent pages | Option B | Next pagination batch after `onAction` `ticketsFetchMore`. Omit on the first response — use `tickets` for page 1.                                                                         |
| bets       | —                                                                                           | no                  | —        | Must not be present. Reserved so this shape cannot be mixed with [`BetShareResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betshareresponse-deprecated) |

```javascript
// Option A — non-paginated: return the full list once
const nonPaginatedResponse = {
  tickets: [
    {
      ticketId: "ticket_123456",
      bets: [
        {
          betId: "bet_001",
          selections: [
            {
              type: "uf",
              productId: "1",
              eventId: "sr:match:12345",
              marketId: "1",
              outcomeId: "1",
              odds: { type: "decimal", value: "2.10" },
              context: {
                eventName: "Manchester United vs Liverpool",
                marketName: "1x2",
                outcomeName: "Home",
                tournament: "Premier League",
                sportName: "Soccer",
                categoryName: "England",
                isLive: false,
                eventStartTime: "1738519200000",
                sportId: "1"
              }
            }
          ],
          odds: { type: "decimal", value: "2.10" },
          stake: [{ type: "cash", currency: "USD", amount: "10.00", mode: "total" }],
          payout: [{ type: "cash", currency: "USD", amount: "21.00" }]
        }
      ],
      version: "2.0"
    }
  ]
};

// Option B — paginated: first page
const paginatedFirstPage = {
  tickets: [/* first batch of Ticket objects */],
  pageSize: 20,
  hasMore: true,
  nextCursor: "cursor-page-2"
};

// Option B — paginated: subsequent page (stored callback from the initial tickets() call)
const paginatedNextPage = {
  newTickets: [/* next batch of Ticket objects */],
  hasMore: false
};
```

**See Also:** [`Ticket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticket), [`TicketsResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketsresponse), [`Tickets Function`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#tickets-function)

### BetShareResponse (Deprecated)

**Deprecated.** Legacy Virtual Stadium bet-share response. New implementations should return [`TicketResponseV2`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketresponsev2) instead.

| Property | Type                                                                                                     | Required | Description                                                                                                                                                                    |
| -------- | -------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| bets     | [`BetSlip`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betslip-deprecated)[] | yes      | Array of deprecated bet-slip objects (one per shared ticket)                                                                                                                   |
| tickets  | —                                                                                                        | no       | Must not be present. Reserved so this shape cannot be mixed with [`TicketResponseV2`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketresponsev2) |

```javascript
// Example response structure (deprecated)
const betShareResponse = {
  bets: [
    {
      id: "ticket_123456",
      betSlipId: "654321",
      betType: "single",
      currency: "USD",
      combinedOdds: {
        decimalValue: 4.33,
        displayValue: "10/3"
      },
      stake: {
        value: "50.00"
      },
      payout: {
        value: "127.50"
      },
      bets: [
        {
          id: "bet_001",
          betType: "",
          markets: [
            {
              id: "1",
              name: "1X2",
              outcomes: [
                {
                  id: "1",
                  name: "Home",
                  odds: 4.33
                }
              ]
            }
          ],
          odds: {
            decimalValue: 4.33,
            displayValue: "10/3"
          },
          event: {
            id: "sr:match:12356",
            name: "Liga La Liga Match 1"
          }
        }
      ]
    }
    // ... additional tickets
  ]
};
```

**See Also:** [`BetSlip (Deprecated)`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betslip-deprecated), [`TicketsResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketsresponse), [`Tickets Function`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#tickets-function)

### MatchEventSuggestedSelectionResponse

Response data containing suggested selections for the match event.

| Property   | Type                                                                                                                                                                                                                             | Required | Description                                                         |
| ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------- |
| selections | ([`SelectionMarket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionmarket) \| [`SelectionOutcome`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionoutcome))[] | yes      | Array of suggested market or outcome selections for the match event |

```javascript
// Example response structure
const matchEventSuggestedSelectionResponse = {
  selections: [
    { event: "sr:match:12345", market: "1", outcome: "1", type: "uf" },
    { event: "sr:match:12345", market: "18", specifiers: "total=2.5", type: "uf" }
  ]
};
```

### RecommendedSelectionsResponse

Response data containing recommended selections for the requested events.

| Property  | Type                                                                                                            | Required | Description                             |
| --------- | --------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------- |
| selection | [`SelectionOutcome[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionoutcome) | yes      | Array of recommended outcome selections |

```javascript
// Example response structure
const recommendedSelectionsResponse = {
  selection: [
    { event: "sr:match:12345", market: "1", outcome: "1", type: "uf" },
    { event: "sr:match:67890", market: "18", specifiers: "total=2.5", outcome: "13", type: "uf" }
  ]
};
```

### CalculateCustomBetXmlResponse

Response data containing the calculated custom bet XML payload.

| Property | Type     | Required | Description                                                  |
| -------- | -------- | -------- | ------------------------------------------------------------ |
| payload  | `string` | yes      | Resulting XML payload string from the custom bet calculation |

```javascript
// Example response structure
const calculateCustomBetXmlResponse = {
  payload: `<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>`
};
```

## Adapter Data Types

### SelectionEvent

Discriminated union type for identifying betting events. The `type` field discriminates between UF (Unified Feed) and external formats.

#### When `type: 'uf'`

Use this format when referencing events from the Sportradar Unified Feed (UOF).

| Property | Type     | Required | Description                                                                              |
| -------- | -------- | -------- | ---------------------------------------------------------------------------------------- |
| type     | `'uf'`   | yes      | Indicates Unified Feed format                                                            |
| event    | `string` | yes      | SR entity identifier following UOF schema (e.g., `"sr:match:12345"`, `"sr:stage:67890"`) |

#### When `type: 'external'`

Use this format when referencing events using your own client-defined identifiers.

| Property | Type         | Required | Description                                                                                                     |
| -------- | ------------ | -------- | --------------------------------------------------------------------------------------------------------------- |
| type     | `'external'` | yes      | Indicates external client-defined format                                                                        |
| event    | `string`     | yes      | Client-defined unique event identifier. Format is determined by your system (e.g., `"736977"`, `"event_12345"`) |

```javascript
// UF format - referencing a Sportradar match
const ufSelection = {
  type: "uf",
  event: "sr:match:12345"
};

// External format - referencing a client-defined event
const externalSelection = {
  type: "external",
  event: "ext:match:736977"
};
```

**See Also:** [`SelectionMarket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionmarket), [`SelectionOutcome`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionoutcome)

### SelectionMarket

Discriminated union type for identifying betting markets within events. Extends [`SelectionEvent`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent) with market-specific properties. The `type` field discriminates between UF (Unified Feed) and external formats.

#### When `type: 'uf'`

Use this format when referencing markets from the Sportradar Unified Feed (UOF).

| Property   | Type     | Required | Description                                                                                                                                                                                               |
| ---------- | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type       | `'uf'`   | yes      | Indicates Unified Feed format                                                                                                                                                                             |
| event      | `string` | yes      | SR entity identifier following UOF schema (e.g., `"sr:match:12345"`)                                                                                                                                      |
| market     | `string` | yes      | Betting market identifier as defined by UOF. Retrieved from the UOF feed (e.g., `"1"` for 1x2)                                                                                                            |
| specifiers | `string` |          | Additional market data as defined by UOF. Although optional in schema, must be provided when the UOF market requires specifiers (e.g., for "Total 1.5" vs "Total 2.5", specifiers would be `"total=1.5"`) |

#### When `type: 'external'`

Use this format when referencing markets using your own client-defined identifiers.

| Property | Type         | Required | Description                                                                                   |
| -------- | ------------ | -------- | --------------------------------------------------------------------------------------------- |
| type     | `'external'` | yes      | Indicates external client-defined format                                                      |
| event    | `string`     | yes      | Client-defined unique event identifier                                                        |
| market   | `string`     | yes      | Client-defined market identifier. If not available in your system, use the outcome identifier |

```javascript
// UF format - referencing a Sportradar market
const ufMarket = {
  type: "uf",
  event: "sr:match:12345",
  market: "1"
};

// UF format with specifiers - market with line (e.g., Total goals)
const ufMarketWithSpecifiers = {
  type: "uf",
  event: "sr:match:12345",
  market: "18",
  specifiers: "total=2.5"
};

// External format - client-defined market
const externalMarket = {
  type: "external",
  event: "event_12345",
  market: "match_winner"
};
```

**See Also:** [`SelectionEvent`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent), [`SelectionOutcome`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionoutcome)

### SelectionOutcome

Discriminated union type for identifying specific betting outcomes within markets. Extends [`SelectionMarket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionmarket) with outcome-specific properties. The `type` field discriminates between UF (Unified Feed) and external formats.

#### When `type: 'uf'`

Use this format when referencing outcomes from the Sportradar Unified Feed (UOF).

| Property   | Type                                                                                  | Required | Description                                                                                                       |
| ---------- | ------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |
| type       | `'uf'`                                                                                | yes      | Indicates Unified Feed format                                                                                     |
| event      | `string`                                                                              | yes      | SR entity identifier following UOF schema (e.g., `"sr:match:12345"`)                                              |
| market     | `string`                                                                              | yes      | Betting market identifier as defined by UOF                                                                       |
| specifiers | `string`                                                                              |          | Additional market data as defined by UOF. Required when market uses specifiers                                    |
| outcome    | `string`                                                                              | yes      | Market outcome identifier as defined by UOF. Retrieved from the UOF feed (e.g., `"1"` for home win in 1x2 market) |
| odds       | [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds) |          | Odds information for this outcome                                                                                 |

#### When `type: 'external'`

Use this format when referencing outcomes using your own client-defined identifiers.

| Property | Type                                                                                  | Required | Description                                                      |
| -------- | ------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------- |
| type     | `'external'`                                                                          | yes      | Indicates external client-defined format                         |
| event    | `string`                                                                              | yes      | Client-defined unique event identifier                           |
| market   | `string`                                                                              | yes      | Client-defined market identifier                                 |
| outcome  | `string`                                                                              | yes      | Client-defined unique market outcome identifier                  |
| odds     | [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds) | yes      | Odds information for this outcome (required for external format) |

```javascript
// UF format - referencing a Sportradar outcome
const ufOutcome = {
  type: "uf",
  event: "sr:match:12345",
  market: "1",
  outcome: "1",
  odds: {
    type: "decimal",
    value: "2.50"
  }
};

// UF format with specifiers
const ufOutcomeWithSpecifiers = {
  type: "uf",
  event: "sr:match:12345",
  market: "18",
  specifiers: "total=2.5",
  outcome: "12",
  odds: {
    type: "decimal",
    value: "1.85"
  }
};

// External format - client-defined outcome
const externalOutcome = {
  type: "external",
  event: "event_12345",
  market: "match_winner",
  outcome: "home",
  odds: {
    type: "decimal",
    value: "2.10"
  }
};
```

**See Also:** [`SelectionEvent`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent), [`SelectionMarket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionmarket), [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds)

### Odds

Represents betting odds in various formats with optional custom display values.

| Property           | Type     | Required | Description                                                                                                                                                                                                                     |
| ------------------ | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type               | `string` | yes      | Odds format. Valid values: `'decimal'`, `'fractional'`, `'moneyline'`, `'hong-kong'`, `'indonesian'`, `'malay'`                                                                                                                 |
| value              | `string` | yes      | Odds value submitted by the client. Pattern: optional leading `+` or `-` (moneyline odds), then 1-8 digits (first cannot be 0), optionally followed by decimal point and 1-8 digits. Regex: `^([+-])?[1-9]\d{0,7}(\.\d{1,8})?$` |
| numerator          | `string` |          | Numerator of fractional odds. Only present when `type` is `'fractional'`. Regex: `^[1-9]\d{0,7}$`                                                                                                                               |
| denominator        | `string` |          | Denominator of fractional odds. Only present when `type` is `'fractional'`. Regex: `^[1-9]\d{0,7}$`                                                                                                                             |
| customDisplayValue | `string` |          | Custom display value for odds, used as-is for display purposes. Only provide if you want to handle custom formatting                                                                                                            |

```javascript
// Decimal odds
const decimalOdds = {
  type: "decimal",
  value: "2.50"
};

// Fractional odds
const fractionalOdds = {
  type: "fractional",
  value: "3.2",
  numerator: "6",
  denominator: "4"
};

// Moneyline odds
const moneylineOdds = {
  type: "moneyline",
  value: "-150"
};

// With custom display value
const customOdds = {
  type: "decimal",
  value: "2.50",
  customDisplayValue: "5/2"
};
```

### Outcome

Represents a single betting outcome within a market.

| Property   | Type                                                                                  | Required | Description                                                                                                                                                                                              |
| ---------- | ------------------------------------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id         | `string`                                                                              | yes      | Unique identifier for the outcome, used to reference it in bets                                                                                                                                          |
| name       | `string`                                                                              | yes      | Translated name of the outcome, used for display purposes                                                                                                                                                |
| competitor | `string`                                                                              |          | Name or identifier of the team or player associated with this outcome. Useful for markets where each outcome is tied to a specific competitor (e.g., for 1x2 market, outcome: 1, competitor: "FC Barca") |
| odds       | [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds) |          | Odds information for this outcome                                                                                                                                                                        |
| status     | `string`                                                                              | yes      | Outcome status. Valid values: 'active', 'inactive'                                                                                                                                                       |

```javascript
// Active outcome with odds
const outcome = {
  id: "1",
  name: "Home Win",
  competitor: "FC Barcelona",
  odds: {
    type: "decimal",
    value: "2.50"
  },
  status: "active"
};

// Inactive outcome
const inactiveOutcome = {
  id: "X",
  name: "Draw",
  status: "inactive"
};
```

**See Also:** [`Market`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#market), [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds)

### Market

Represents a betting market with multiple outcomes.

| Property   | Type                                                                                          | Required | Description                                                                                                                                                                                |
| ---------- | --------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| id         | `string`                                                                                      | yes      | Unique identifier for the market, used to reference it in bets                                                                                                                             |
| name       | `string`                                                                                      | yes      | Translated name of the market, used for display purposes                                                                                                                                   |
| outcomes   | [`Outcome[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#outcome) | yes      | All outcomes associated with this market                                                                                                                                                   |
| status     | `string`                                                                                      | yes      | Market status. Valid values: 'active', 'deactivated', 'suspended', 'settled', 'cancelled'                                                                                                  |
| specifiers | `string`                                                                                      |          | Additional market data as defined by UOF (e.g., for markets with lines like Total 1.5 vs Total 2.5). Although optional in schema, must be provided when the UOF market requires specifiers |

**Market Status Values:**

- **active**: Odds are provided and you can accept bets on the market
- **deactivated**: Odds are no longer provided for this market. Can go back to active (e.g., when a different total line becomes most balanced)
- **suspended**: Odds continue to be provided but you should not accept bets temporarily (e.g., "bet stop" before/during goal confirmation)
- **settled**: Bet settlement messages have been sent for this market, no further odds will be provided. In rare cases, settled markets may be moved to cancelled
- **cancelled**: This market has been cancelled. No further odds will be provided

```javascript
// Active market with outcomes
const market = {
  id: "1",
  name: "Match Winner (1X2)",
  outcomes: [
    { id: "1", name: "Home", status: "active", odds: { type: "decimal", value: "2.10" } },
    { id: "X", name: "Draw", status: "active", odds: { type: "decimal", value: "3.40" } },
    { id: "2", name: "Away", status: "active", odds: { type: "decimal", value: "3.50" } }
  ],
  status: "active"
};

// Market with specifiers (Total goals)
const totalMarket = {
  id: "18",
  name: "Total Goals",
  specifiers: "total=2.5",
  outcomes: [
    { id: "12", name: "Over 2.5", status: "active", odds: { type: "decimal", value: "1.85" } },
    { id: "13", name: "Under 2.5", status: "active", odds: { type: "decimal", value: "2.05" } }
  ],
  status: "active"
};
```

**See Also:** [`Outcome`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#outcome), [`Event`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#event)

### Event

Represents a sporting event with teams, tournament information, and match details.

| Property          | Type                                                                                                                                                                           | Required | Description                                                      |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | ---------------------------------------------------------------- |
| id                | `string`                                                                                                                                                                       | yes      | Event identifier as defined by UOF. Retrieved from the MAPI feed |
| sport             | [`Sport`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#sport)                                                                                        | yes      | Sport information (imported from adapter types)                  |
| category          | [`Category`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#category)                                                                                  | yes      | Category information (e.g., country, region)                     |
| tournament        | [`Tournament`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#tournament)                                                                              | yes      | Tournament information                                           |
| teams             | [[`Team`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#team), [`Team`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#team)] | yes      | Array of exactly two teams (home and away)                       |
| isLive            | `boolean`                                                                                                                                                                      | yes      | Indicates whether the event is currently live                    |
| date              | [`EventDate`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#eventdate)                                                                                |          | Date information for the event                                   |
| date.displayValue | `string`                                                                                                                                                                       |          | Formatted date string for display                                |
| date.startTime    | `string`                                                                                                                                                                       |          | Event start time (ISO format)                                    |
| liveCurrentTime   | `string`                                                                                                                                                                       |          | Current match time for live events (e.g., "45:00", "HT")         |
| result1           | [`Result`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#result)                                                                                      |          | Primary result/score information                                 |
| result2           | [`Result`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#result)                                                                                      |          | Secondary result information (e.g., half-time score)             |
| result3           | [`Result`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#result)                                                                                      |          | Tertiary result information (e.g., period scores)                |

```javascript
// Pre-match event
const prematchEvent = {
  id: "sr:match:12345",
  sport: { id: "1", name: "Soccer" },
  category: { id: "1", name: "England" },
  tournament: { id: "17", name: "Premier League" },
  teams: [
    { id: "sr:competitor:1", name: "Manchester United" },
    { id: "sr:competitor:2", name: "Liverpool" }
  ],
  isLive: false,
  date: {
    displayValue: "Jan 7, 2026",
    startTime: "2026-01-07T20:00:00Z"
  }
};

// Live event with score
const liveEvent = {
  id: "sr:match:67890",
  sport: { id: "1", name: "Soccer" },
  category: { id: "1", name: "England" },
  tournament: { id: "17", name: "Premier League" },
  teams: [
    { id: "sr:competitor:3", name: "Chelsea" },
    { id: "sr:competitor:4", name: "Arsenal" }
  ],
  isLive: true,
  liveCurrentTime: "72:15",
  result1: { home: 2, away: 1 }
};
```

**See Also:** [`Market`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#market), [`SelectionEvent`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#selectionevent)

### EventDate

Represents date and time information for an event.

| Property     | Type     | Required | Description                                                   |
| ------------ | -------- | -------- | ------------------------------------------------------------- |
| displayValue | `string` |          | Formatted date string for display purposes                    |
| startTime    | `string` |          | Event start time in ISO format (e.g., "2026-01-07T20:00:00Z") |

```javascript
// Example date object
const eventDate = {
  displayValue: "Jan 7, 2026",
  startTime: "2026-01-07T20:00:00Z"
};
```

**See Also:** [`Event`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#event)

### Ticket

Represents a betting ticket containing one or more bets. In the Bet Component UI a ticket is the full card (**header** / **body** / **footer**). Selections live in the body; some selection types also change the header (see [`TicketSelection`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselection)).

| Property | Type                                                                                  | Required | Description                                                                                                                          |
| -------- | ------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| ticketId | `string`                                                                              | yes      | Client defined string to identify the ticket (unique in the client's system), minimal string length = 1, maximum string length = 128 |
| bets     | [`Bet[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#bet) | yes      | Array of bets included in this ticket                                                                                                |
| version  | `string`                                                                              | yes      | Version of the ticket schema (for example `"2.0"`)                                                                                   |

```javascript
const ticket = {
  ticketId: "ticket_123456",
  bets: [
    {
      betId: "bet_001",
      selections: [
        {
          type: "uf",
          productId: "1",
          eventId: "sr:match:12345",
          marketId: "1",
          outcomeId: "1",
          odds: { type: "decimal", value: "2.10" },
          context: {
            eventName: "Manchester United vs Liverpool",
            marketName: "1x2",
            outcomeName: "Home",
            tournament: "Premier League",
            sportName: "Soccer",
            categoryName: "England",
            isLive: false,
            eventStartTime: "1738519200000",
            sportId: "1"
          }
        }
      ],
      odds: { type: "decimal", value: "2.10" },
      stake: [{
        type: "cash",
        currency: "USD",
        amount: "10.00",
        mode: "total"
      }],
      payout: [{ type: "cash", currency: "USD", amount: "21.00" }]
    }
  ],
  version: "2.0"
};
```

**See Also:** [`Bet`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#bet), [`TicketResponseV2`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketresponsev2), [`TicketsResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketsresponse)

### Bet

Represents one bet within a ticket, containing selections and stake information. A bet with one selection is a **single**; a bet with multiple selections is an **accumulator**. Selections may mix different [`TicketSelection`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselection) types.

| Property   | Type                                                                                                            | Required | Description                                                                                                  |
| ---------- | --------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------ |
| betId      | `string`                                                                                                        | yes      | Unique bet id (in the client's system), minimal string length = 1, maximum length = 128                      |
| selections | [`TicketSelection[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselection)   | yes      | Array of bet selections included in this bet, minimal number of selections per bet = 1, maximum number = 100 |
| stake      | [`Stake[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#stake)                       | yes      | Array of bet stakes, minimal number of stake per bet = 1, maximum number = 5                                 |
| odds       | [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds)                           | yes      | The odds for this bet                                                                                        |
| payout     | [`Payout[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#payout)                     |          | Optional potential payout for this bet. If omitted, it may be calculated and rounded based on internal logic |
| cashout    | [`PayoutWithSource[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#payoutwithsource) |          | Optional cashout amounts for display or use cases where cashout is available                                 |

```javascript
// Single bet
const singleBet = {
  betId: "bet_001",
  selections: [
    {
      type: "uf",
      eventId: "sr:match:12345",
      marketId: "1",
      outcomeId: "1",
      odds: { type: "decimal", value: "2.10" }
    }
  ],
  odds: { type: "decimal", value: "2.10" },
  stake: [{
    type: "cash",
    currency: "USD",
    amount: "10.00"
  }]
};

// Accumulator bet
const accumulatorBet = {
  betId: "bet_002",
  selections: [
    {
      type: "uf",
      eventId: "sr:match:12345",
      marketId: "1",
      outcomeId: "1",
      odds: { type: "decimal", value: "2.10" }
    },
    {
      type: "uf",
      eventId: "sr:match:67890",
      marketId: "1",
      outcomeId: "1",
      odds: { type: "decimal", value: "1.85" }
    }
  ],
  stake: [{
    type: "cash",
    currency: "USD",
    amount: "5.00"
  }],
  odds: { type: "decimal", value: "3.89" }
};

// Custom bet using TicketSelection
const customBet = {
  betId: "bet_003",
  selections: [
    {
      type: "uf-custom-bet",
      selections: [
        {
          type: "uf",
          eventId: "sr:match:12345",
          marketId: "1",
          outcomeId: "1",
          odds: { type: "decimal", value: "2.10" }
        },
        {
          type: "uf",
          eventId: "sr:match:12345",
          marketId: "18",
          specifiers: "total=2.5",
          outcomeId: "12",
          odds: { type: "decimal", value: "1.85" }
        }
      ],
      odds: { type: "decimal", value: "3.89" }
    }
  ],
  odds: { type: "decimal", value: "3.89" },
  stake: [{
    type: "cash",
    currency: "EUR",
    amount: "10.00"
  }]
};

```

**See Also:** [`Ticket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticket), [`TicketSelection`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselection), [`Stake`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#stake), [`Payout`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#payout)

### Payout

Represents a cash payout amount for a bet.

| Property | Type     | Required | Description                                           |
| -------- | -------- | -------- | ----------------------------------------------------- |
| type     | `'cash'` | yes      | Payout type. Currently only `'cash'` is supported     |
| currency | `string` | yes      | Currency code (e.g., `"USD"`, `"EUR"`, `"GBP"`)       |
| amount   | `string` | yes      | Payout amount as a string to allow for decimal values |

```javascript
const payout = {
  type: "cash",
  currency: "USD",
  amount: "21.00"
};
```

**See Also:** [`Bet`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#bet), [`PayoutWithSource`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#payoutwithsource)

### PayoutWithSource

Extends [`Stake`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#stake) with an optional source describing where the payout originated. Used for optional `cashout` amounts on a [`Bet`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#bet).

| Property | Type                                                                                                                    | Required | Description                                     |
| -------- | ----------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------- |
| type     | `'cash' \| 'bonus'`                                                                                                     | yes      | Stake/payout type                               |
| currency | `string`                                                                                                                | yes      | Currency code (e.g., `"USD"`, `"EUR"`, `"GBP"`) |
| amount   | `string`                                                                                                                | yes      | Amount as a string to allow for decimal values  |
| mode     | `'unit' \| 'total'`                                                                                                     |          | Stake mode. Defaults to `'total'`               |
| source   | `'cash' \| 'bonus' \| 'odds-boost' \| 'cancel' \| 'cashout' \| 'ext-settlement' \| 'manual-cancel' \| 'manual-cashout'` |          | Optional origin of the payout amount            |

```javascript
const cashout = {
  type: "cash",
  currency: "USD",
  amount: "15.50",
  source: "cashout"
};
```

**See Also:** [`Bet`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#bet), [`Payout`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#payout), [`Stake`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#stake)

### Stake

Represents stake information for a bet.

| Property | Type     | Required | Description                                                                                                                                                          |
| -------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type     | `string` | yes      | Stake type. Valid values: 'cash' (used for stake and payout), 'bonus' (amount added on top of winnings if bet is won)                                                |
| currency | `string` | yes      | Currency code (e.g., "USD", "EUR", "GBP")                                                                                                                            |
| amount   | `string` | yes      | Stake amount as a string to allow for decimal values                                                                                                                 |
| mode     | `string` |          | Stake mode (default: 'total'). Valid values: 'unit' (stake relates to each sub-bet in system bets), 'total' (stake relates to all sub-bets, each receives a portion) |

```javascript
// Cash stake with total mode
const cashStake = {
  type: "cash",
  currency: "USD",
  amount: "10.00",
  mode: "total"
};

// Bonus stake
const bonusStake = {
  type: "bonus",
  currency: "EUR",
  amount: "5.00"
};

// Unit stake for system bet
const unitStake = {
  type: "cash",
  currency: "GBP",
  amount: "2.00",
  mode: "unit"
};
```

**See Also:** [`Bet`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#bet)

### TicketSelection

Discriminated union type for entries in a bet's `selections` array. The `type` field discriminates between UOF, external, custom bet, system, odds-boost, ways, and payout-modifier formats.

Do not confuse **Ticket** with **TicketSelection** in the UI:

| Concept               | Adapter type                                                                              | What the UI shows                                                                                                                                             |
| --------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Ticket                | [`Ticket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticket) | The whole card: **header** (bet kind / modifiers / total odds), **body** (one or more selections), **footer** (stake / to return)                             |
| TicketSelection       | this type                                                                                 | Data that drives a **body** row or group. Some types also change the **ticket header** (for example `odds-boost` → `BOOSTED ODD`, `payout-modifier` → `2 UP`) |
| Single vs accumulator | [`Bet`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#bet)       | A **single** has one selection; an **accumulator** (multi bet) has multiple. Selection `type`s can be mixed                                                   |

Example **accumulator ticket** (header / body / footer). Body rows are TicketSelections; stake and return belong to the ticket bet, not to a selection:

![Accumulator ticket anatomy](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/anatomy.png)

How each selection `type` appears on a ticket (screenshots are full tickets; note header vs body):

| Adapter `type`                  | Ticket UI role                                                                                                             | Example ticket                                                                                                             |
| ------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `uf` or `external`              | Standard pick in the **body**. Ticket header is usually `SINGLE` / `MULTI BET`                                             | ![Standard selection ticket](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/selection.png)    |
| `uf-custom-bet` or `custom-bet` | Bet-builder **body** group; header often shows `BET BUILDER` and combined odds                                             | ![Bet builder ticket](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/bet-builder.png)         |
| `system`                        | System **body** group; header shows size and odds (for example `2/4`)                                                      | ![System ticket](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/system-bet.png)               |
| `odds-boost`                    | **Header** shows `BOOSTED ODD` and boosted odds; **body** still shows the nested `uf` / `external` pick with original odds | ![Boosted odds ticket](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/boosted-odds.png)       |
| `ways`                          | Ways **body** group; header shows `WAYS` and odds                                                                          | ![Ways ticket](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/ways.png)                       |
| `payout-modifier`               | **Header** shows the promo label (for example `2 UP`); **body** shows the nested pick                                      | ![Payout modifier ticket](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/payout-modifier.png) |

Examples below are complete [`Ticket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticket) objects (`version: "2.0"`) as returned inside [`TicketResponseV2`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketresponsev2).

#### When `type: 'uf'`

Use when outcomes, markets, events, and specifiers originate from UOF. Example **single ticket** whose body is one standard selection:

![Ticket with standard selection](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/selection.png)

| Property   | Type                                                                                                                      | Required | Description                                                                                                                             |
| ---------- | ------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| type       | `'uf'`                                                                                                                    | yes      | Indicates Unified Feed format                                                                                                           |
| eventId    | `string`                                                                                                                  | yes      | Betting event as defined by UOF. Minimal length = 1, maximum = 100                                                                      |
| marketId   | `string`                                                                                                                  | yes      | Betting market as defined by UOF. Minimal length = 1, maximum = 100                                                                     |
| outcomeId  | `string`                                                                                                                  | yes      | Market outcome as defined by UOF. Minimal length = 1, maximum = 1000                                                                    |
| odds       | [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds)                                     | yes      | Odds for the selection                                                                                                                  |
| productId  | `string`                                                                                                                  |          | UOF producer id (e.g., `"1"` for LiveOdds, `"5"` for Premium Cricket). Minimal length = 1, maximum = 5                                  |
| specifiers | `string`                                                                                                                  |          | Additional market data as defined by UOF (e.g., `"total=2.5"`). Minimal length = 1, maximum = 1000                                      |
| context    | [`TicketSelectionContext`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselectioncontext) |          | Optional historical display context for this selection. Prefer providing it so tickets remain readable after market/event data ages out |

```javascript
const ticketUfSingle = {
  ticketId: "ticket_uf_single",
  bets: [
    {
      betId: "bet_uf",
      selections: [
        {
          type: "uf",
          productId: "1",
          eventId: "sr:match:12345",
          marketId: "1",
          outcomeId: "1",
          odds: { type: "decimal", value: "2.10" },
          context: {
            marketName: "1x2",
            outcomeName: "Home",
            eventName: "Manchester United vs Liverpool",
            tournament: "Premier League",
            sportName: "Soccer",
            categoryName: "England",
            isLive: false,
            eventStartTime: "1738519200000",
            sportId: "1"
          }
        }
      ],
      odds: { type: "decimal", value: "2.10" },
      stake: [{ type: "cash", currency: "USD", amount: "10.00", mode: "total" }],
      payout: [{ type: "cash", currency: "USD", amount: "21.00" }]
    }
  ],
  version: "2.0"
};
```

#### When `type: 'external'`

Use when outcomes, events, odds, and settlements are managed by the client. Example **single ticket** whose body is one standard selection:

![Ticket with standard selection](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/selection.png)

| Property      | Type                                                                                                                      | Required | Description                                                                                                                             |
| ------------- | ------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| type          | `'external'`                                                                                                              | yes      | Indicates external client-defined format                                                                                                |
| event         | `string`                                                                                                                  | yes      | Unique event identifier as defined by the client. Minimal length = 1, maximum = 100                                                     |
| outcome       | `string`                                                                                                                  | yes      | Unique outcome identifier as defined by the client (should uniquely designate market and selection). Minimal length = 1, maximum = 1000 |
| odds          | [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds)                                     | yes      | Odds for the selection                                                                                                                  |
| expSettleTime | `string`                                                                                                                  |          | Expected settlement time (Unix time milliseconds). Widgets may use this to filter, update status, or prevent copying                    |
| context       | [`TicketSelectionContext`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselectioncontext) |          | Optional historical display context for this selection. Prefer providing it so tickets remain readable after market/event data ages out |

```javascript
const ticketExternalSingle = {
  ticketId: "ticket_external_single",
  bets: [
    {
      betId: "bet_external",
      selections: [
        {
          type: "external",
          event: "ext:match:736977",
          outcome: "ext:outcome:111",
          expSettleTime: "1738530000000",
          odds: { type: "decimal", value: "3.50" },
          context: {
            marketName: "Total Points (incl. OT)",
            outcomeName: "Over 210.5",
            eventName: "Lakers vs Celtics",
            tournament: "NBA",
            sportName: "Basketball",
            isLive: false,
            eventStartTime: "1738540800000",
            sportId: "1"
          }
        }
      ],
      odds: { type: "decimal", value: "3.50" },
      stake: [{ type: "cash", currency: "USD", amount: "10.00", mode: "total" }],
      payout: [{ type: "cash", currency: "USD", amount: "35.00" }],
      cashout: [{ type: "cash", currency: "USD", amount: "35.00", mode: "total", source: "odds-boost" }]
    }
  ],
  version: "2.0"
};
```

#### When `type: 'uf-custom-bet'`

Custom bet (bet builder) composed of uf selections. Corresponds to Bet Builder in the UI. Example ticket: header shows `BET BUILDER`; body is the custom-bet group:

![Ticket with bet-builder selection](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/bet-builder.png)

| Property    | Type                                                                                                                                        | Required | Description                                                                   |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------- |
| type        | `'uf-custom-bet'`                                                                                                                           | yes      | Indicates a UOF custom bet                                                    |
| selections  | TicketSelectionUf[]                                                                                                                         | yes      | Nested selections; only `type: 'uf'` is allowed                               |
| odds        | [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds)                                                       | yes      | Odds for the custom bet                                                       |
| useHarmOdds | `boolean`                                                                                                                                   |          | When true, instruct the UOF CB API to use harmonized odds. Default is `false` |
| context     | [`TicketSelectionCustomBetContext`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselectioncustombetcontext) |          | Optional historical display context for the custom bet as a whole             |

```javascript
const ticketCustomBetUf = {
  ticketId: "ticket_custom_bet_uf",
  bets: [
    {
      betId: "bet_custom_uf",
      selections: [
        {
          type: "uf-custom-bet",
          selections: [
            {
              type: "uf",
              productId: "1",
              eventId: "sr:match:12345",
              marketId: "1",
              outcomeId: "1",
              odds: { type: "decimal", value: "2.10" },
              context: {
                marketName: "1x2",
                outcomeName: "Home",
                eventName: "Manchester United vs Liverpool",
                tournament: "Premier League",
                sportName: "Soccer",
                categoryName: "England",
                isLive: false,
                eventStartTime: "1738519200000",
                sportId: "1"
              }
            },
            {
              type: "uf",
              productId: "1",
              eventId: "sr:match:67890",
              marketId: "18",
              outcomeId: "12",
              specifiers: "total=2.5",
              odds: { type: "decimal", value: "1.95" },
              context: {
                marketName: "Total Goals",
                outcomeName: "Over 2.5",
                eventName: "Arsenal vs Chelsea",
                tournament: "Premier League",
                sportName: "Soccer",
                isLive: true,
                eventStartTime: "1738515600000",
                sportId: "1"
              }
            }
          ],
          odds: { type: "decimal", value: "5.80" },
          useHarmOdds: false,
          context: { eventName: "Manchester United vs Liverpool & Arsenal vs Chelsea" }
        }
      ],
      odds: { type: "decimal", value: "5.80" },
      stake: [{ type: "cash", currency: "USD", amount: "10.00", mode: "total" }]
    }
  ],
  version: "2.0"
};
```

#### When `type: 'custom-bet'`

Custom bet composed of external selections. Example ticket: header shows `BET BUILDER`; body is the custom-bet group:

![Ticket with bet-builder selection](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/bet-builder.png)

| Property   | Type                                                                                                                                        | Required | Description                                                       |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------- |
| type       | `'custom-bet'`                                                                                                                              | yes      | Indicates an external custom bet                                  |
| selections | TicketSelectionExternal[]                                                                                                                   | yes      | Nested selections; only `type: 'external'` is allowed             |
| odds       | [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds)                                                       | yes      | Odds for the custom bet                                           |
| context    | [`TicketSelectionCustomBetContext`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselectioncustombetcontext) |          | Optional historical display context for the custom bet as a whole |

```javascript
const ticketCustomBetExternal = {
  ticketId: "ticket_custom_bet_external",
  bets: [
    {
      betId: "bet_custom_ext",
      selections: [
        {
          type: "custom-bet",
          selections: [
            {
              type: "external",
              event: "ext:match:736977",
              outcome: "ext:outcome:111",
              expSettleTime: "1738530000000",
              odds: { type: "decimal", value: "3.50" },
              context: {
                marketName: "Total Points (incl. OT)",
                outcomeName: "Over 210.5",
                eventName: "Lakers vs Celtics",
                tournament: "NBA",
                sportName: "Basketball",
                isLive: false,
                eventStartTime: "1738540800000",
                sportId: "1"
              }
            },
            {
              type: "external",
              event: "ext:match:736978",
              outcome: "ext:outcome:222",
              odds: { type: "decimal", value: "1.80", customDisplayValue: "1.80 (fav)" },
              expSettleTime: "1738544400000",
              context: {
                marketName: "Moneyline",
                outcomeName: "Warriors",
                eventName: "Warriors vs Bucks",
                isLive: true,
                eventStartTime: "1738537200000",
                sportId: "1"
              }
            }
          ],
          odds: { type: "decimal", value: "6.30" },
          context: { eventName: "Lakers vs Celtics & Warriors vs Bucks" }
        }
      ],
      odds: { type: "decimal", value: "6.30" },
      stake: [{ type: "cash", currency: "USD", amount: "10.00", mode: "total" }]
    }
  ],
  version: "2.0"
};
```

#### When `type: 'system'`

Multiple selections that form a system bet. Example ticket: header shows system size and odds; body is the system group:

![Ticket with system selection](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/system-bet.png)

| Property   | Type                                                                                                                                  | Required | Description                                                                           |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------- |
| type       | `'system'`                                                                                                                            | yes      | Indicates a system bet                                                                |
| selections | TicketSelectionUf[] \| TicketSelectionExternal[]                                                                                      | yes      | Nested selections; all must be the same type (`uf` or `external`)                     |
| size       | `number[]`                                                                                                                            | yes      | Unique system sizes (e.g., `[2, 3]` for 2/4 and 3/4). Minimal items = 1, maximum = 30 |
| context    | [`TicketSelectionSystemContext`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketselectionsystemcontext) |          | Optional system-bet display context                                                   |

```javascript
const ticketSystemUfTrixie = {
  ticketId: "ticket_system_uf_trixie",
  bets: [
    {
      betId: "bet_system_uf_trixie",
      selections: [
        {
          type: "system",
          selections: [
            {
              type: "uf",
              productId: "1",
              eventId: "sr:match:12345",
              marketId: "1",
              outcomeId: "1",
              odds: { type: "decimal", value: "2.10" },
              context: {
                marketName: "1x2",
                outcomeName: "Home",
                eventName: "Manchester United vs Liverpool",
                tournament: "Premier League",
                sportName: "Soccer",
                categoryName: "England",
                isLive: false,
                eventStartTime: "1738519200000",
                sportId: "1"
              }
            },
            {
              type: "uf",
              productId: "1",
              eventId: "sr:match:67890",
              marketId: "18",
              outcomeId: "12",
              specifiers: "total=2.5",
              odds: { type: "decimal", value: "1.95" },
              context: {
                marketName: "Total Goals",
                outcomeName: "Over 2.5",
                eventName: "Arsenal vs Chelsea",
                tournament: "Premier League",
                sportName: "Soccer",
                isLive: true,
                eventStartTime: "1738515600000",
                sportId: "1"
              }
            },
            {
              type: "uf",
              productId: "1",
              eventId: "sr:match:11111",
              marketId: "1",
              outcomeId: "2",
              odds: { type: "decimal", value: "4.20" },
              context: {
                marketName: "1x2",
                outcomeName: "Away",
                eventName: "Tottenham vs Newcastle",
                tournament: "Premier League",
                sportName: "Soccer",
                isLive: false,
                eventStartTime: "1738605600000",
                sportId: "1"
              }
            }
          ],
          size: [2, 3],
          context: { systemName: "Trixie" }
        }
      ],
      odds: { type: "decimal", value: "8.62" },
      stake: [{ type: "cash", currency: "USD", amount: "40.00", mode: "unit" }]
    }
  ],
  version: "2.0"
};
```

#### When `type: 'odds-boost'`

A uf or external selection with boosted odds. Example ticket: **header** shows `BOOSTED ODD` and the boosted value; **body** shows the nested pick with original odds:

![Ticket with odds-boost selection](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/boosted-odds.png)

| Property  | Type                                                                                  | Required | Description                           |
| --------- | ------------------------------------------------------------------------------------- | -------- | ------------------------------------- |
| type      | `'odds-boost'`                                                                        | yes      | Indicates boosted odds                |
| selection | TicketSelectionUf \| TicketSelectionExternal                                          | yes      | Nested selection (`uf` or `external`) |
| odds      | [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds) | yes      | Boosted odds for the selection        |

```javascript
const ticketOddsBoost = {
  ticketId: "ticket_odds_boost",
  bets: [
    {
      betId: "bet_odds_boost",
      selections: [
        {
          type: "odds-boost",
          selection: {
            type: "uf",
            productId: "1",
            eventId: "sr:match:12345",
            marketId: "1",
            outcomeId: "1",
            odds: { type: "decimal", value: "2.10" },
            context: {
              marketName: "1x2",
              outcomeName: "Home",
              eventName: "Manchester United vs Liverpool",
              tournament: "Premier League",
              sportName: "Soccer",
              categoryName: "England",
              isLive: false,
              eventStartTime: "1738519200000",
              sportId: "1"
            }
          },
          odds: { type: "decimal", value: "3.00" }
        }
      ],
      odds: { type: "decimal", value: "3.00" },
      stake: [{ type: "cash", currency: "USD", amount: "10.00", mode: "total" }]
    }
  ],
  version: "2.0"
};
```

#### When `type: 'ways'`

One or more selections related to an event (or market) already included elsewhere in the same bet. Example ticket: header shows `WAYS`; body is the ways group:

![Ticket with ways selection](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/ways.png)

| Property   | Type                                                                           | Required | Description                                                                      |
| ---------- | ------------------------------------------------------------------------------ | -------- | -------------------------------------------------------------------------------- |
| type       | `'ways'`                                                                       | yes      | Indicates ways selections                                                        |
| selections | TicketSelectionUf[] \| TicketSelectionExternal[] \| TicketSelectionOddsBoost[] | yes      | Nested selections (`uf`, `external`, or `odds-boost`). Minimal = 2, maximum = 30 |

```javascript
const ticketWays = {
  ticketId: "ticket_ways",
  bets: [
    {
      betId: "bet_ways",
      selections: [
        {
          type: "ways",
          selections: [
            {
              type: "uf",
              productId: "1",
              eventId: "sr:match:12345",
              marketId: "1",
              outcomeId: "1",
              odds: { type: "decimal", value: "2.10" },
              context: {
                marketName: "1x2",
                outcomeName: "Home",
                eventName: "Manchester United vs Liverpool",
                tournament: "Premier League",
                sportName: "Soccer",
                categoryName: "England",
                isLive: false,
                eventStartTime: "1738519200000",
                sportId: "1"
              }
            },
            {
              type: "uf",
              productId: "1",
              eventId: "sr:match:67890",
              marketId: "18",
              outcomeId: "12",
              specifiers: "total=2.5",
              odds: { type: "decimal", value: "1.95" },
              context: {
                marketName: "Total Goals",
                outcomeName: "Over 2.5",
                eventName: "Arsenal vs Chelsea",
                tournament: "Premier League",
                sportName: "Soccer",
                isLive: true,
                eventStartTime: "1738515600000",
                sportId: "1"
              }
            }
          ]
        }
      ],
      odds: { type: "decimal", value: "4.10" },
      stake: [{ type: "cash", currency: "USD", amount: "10.00", mode: "total" }]
    }
  ],
  version: "2.0"
};
```

#### When `type: 'payout-modifier'`

A selection eligible for payout modification / promotion settlement (for example Supersub or Early Payout). Example ticket: **header** shows the promo label (for example `2 UP`); **body** shows the nested pick:

| Property    | Type                                         | Required | Description                                                                                                    |
| ----------- | -------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------- |
| type        | `'payout-modifier'`                          | yes      | Indicates a payout modifier                                                                                    |
| reference   | `string`                                     | yes      | Unique promotion identifier used in settlement messages                                                        |
| description | `string`                                     | yes      | Promotion type description (e.g., `"Early Payout"`, `"2 Up"`, `"Supersub"`). Minimal length = 1, maximum = 512 |
| selections  | TicketSelectionUf \| TicketSelectionExternal | yes      | Nested selection (`uf` or `external`)                                                                          |

![Ticket with payout-modifier selection](https://apidocs.sportradar.com/resources/widgets/static/img/adapter/tickets/payout-modifier.png)

```javascript
const ticketPayoutModifier = {
  ticketId: "ticket_payout_modifier",
  bets: [
    {
      betId: "bet_payout_mod",
      selections: [
        {
          type: "payout-modifier",
          reference: "promo_2up_001",
          description: "2 Up",
          selections: {
            type: "external",
            event: "ext:match:736977",
            outcome: "ext:outcome:111",
            expSettleTime: "1738530000000",
            odds: { type: "decimal", value: "3.50" },
            context: {
              marketName: "Total Points (incl. OT)",
              outcomeName: "Over 210.5",
              eventName: "Lakers vs Celtics",
              tournament: "NBA",
              sportName: "Basketball",
              isLive: false,
              eventStartTime: "1738540800000",
              sportId: "1"
            }
          }
        }
      ],
      odds: { type: "decimal", value: "3.50" },
      stake: [{ type: "cash", currency: "USD", amount: "10.00", mode: "total" }]
    }
  ],
  version: "2.0"
};
```

#### TicketSelectionContext

Historical display metadata for `uf` and `external` ticket selections. Extends with additional custom fields (`Record<string, unknown>`): you may include extra keys beyond the predefined ones below.

**Why it exists:** Widgets need human-readable names (event, market, outcome) to render a ticket. If `context` is missing, the widget may call endpoints such as [`event`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#event-function) or [`eventMarkets`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#eventmarkets-function) to resolve those names from the selection IDs. That works for recent data, but months later the same IDs may no longer be available from those endpoints. Provide `context` on the ticket selection so names and related display fields can be read from the ticket itself and remain usable for historical tickets.

| Property       | Type      | Required | Description                                                                                                       |
| -------------- | --------- | -------- | ----------------------------------------------------------------------------------------------------------------- |
| eventName      | `string`  |          | Event display name (e.g., `"Manchester United vs Liverpool"`)                                                     |
| marketName     | `string`  |          | Market display name (e.g., `"1x2"`, `"Total Points (incl. OT)"`)                                                  |
| outcomeName    | `string`  |          | Outcome display name (e.g., `"Home"`, `"Over 210.5"`)                                                             |
| tournament     | `string`  |          | Tournament name (e.g., `"Premier League"`, `"NBA"`)                                                               |
| sportName      | `string`  |          | Sport name (e.g., `"Soccer"`, `"Basketball"`)                                                                     |
| sportId        | `string`  |          | Sport identifier (e.g., `"1"`)                                                                                    |
| categoryName   | `string`  |          | Geographic or organizational grouping (e.g., `"England"`, `"USA"`)                                                |
| isLive         | `boolean` |          | Whether the event is currently live. Helps widgets show a Live badge or prioritize the selection                  |
| eventStartTime | `string`  |          | Expected event start time in Unix milliseconds. Widgets may use this to filter, update status, or prevent copying |

```javascript
const context = {
  eventName: "Manchester United vs Liverpool",
  marketName: "1x2",
  outcomeName: "Home",
  tournament: "Premier League",
  sportName: "Soccer",
  categoryName: "England",
  isLive: false,
  eventStartTime: "1738519200000",
  sportId: "1"
};
```

#### TicketSelectionCustomBetContext

Historical display metadata for `uf-custom-bet` and `custom-bet` selections. Extends with additional custom fields (`Record<string, unknown>`).

| Property  | Type     | Required | Description                                                                 |
| --------- | -------- | -------- | --------------------------------------------------------------------------- |
| eventName | `string` |          | Event or custom-bet display name (e.g., `"Manchester United vs Liverpool"`) |

```javascript
const customBetContext = {
  eventName: "Manchester United vs Liverpool & Arsenal vs Chelsea"
};
```

#### TicketSelectionSystemContext

Optional display metadata for `system` selections.

| Property   | Type     | Required | Description                                                                              |
| ---------- | -------- | -------- | ---------------------------------------------------------------------------------------- |
| systemName | `string` |          | Human-readable system bet name (e.g., `"Trixie"`, `"Yankee"`, `"Lucky 15"`, `"Doubles"`) |

```javascript
const systemContext = {
  systemName: "Trixie"
};
```

**See Also:** [`Bet`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#bet), [`Odds`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#odds), [`Ticket`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticket), [`TicketResponseV2`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketresponsev2)

### Sport

Represents information about a sport.

| Property | Type     | Required | Description                            |
| -------- | -------- | -------- | -------------------------------------- |
| id       | `string` |          | The unique SR identifier for the sport |
| name     | `string` |          | The name of the sport                  |
| icon     | `string` |          | URL where the sport icon is located    |

```javascript
const soccer = {
  id: "1",
  name: "Soccer",
  icon: "https://example.com/icons/soccer.png"
};

const basketball = {
  id: "2",
  name: "Basketball"
};
```

**See Also:** [`Event`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#event), [`Category`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#category)

### Category

Represents information about a category (e.g., country, region).

| Property | Type     | Required | Description                                         |
| -------- | -------- | -------- | --------------------------------------------------- |
| id       | `string` |          | The unique identifier assigned to the category      |
| name     | `string` |          | The name of the category                            |
| cc       | `object` |          | Country code information                            |
| cc.a2    | `string` | yes      | Country code in A2 format (if cc object is present) |

```javascript
const england = {
  id: "1",
  name: "England",
  cc: {
    a2: "GB"
  }
};

const spain = {
  id: "32",
  name: "Spain"
};
```

**See Also:** [`Event`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#event), [`Sport`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#sport)

### Tournament

Represents information about a tournament.

| Property   | Type               | Required | Description                                      |
| ---------- | ------------------ | -------- | ------------------------------------------------ |
| id         | `string`           |          | The unique identifier assigned to the tournament |
| externalId | `string \| number` |          | Your unique identifier for the tournament        |
| name       | `string`           |          | The name of the tournament                       |

```javascript
const premierLeague = {
  id: "17",
  externalId: "PL2025",
  name: "Premier League"
};

const championsLeague = {
  id: "7",
  name: "UEFA Champions League"
};
```

**See Also:** [`Event`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#event), [`Category`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#category)

### Team

Represents information about a team participating in an event.

| Property | Type     | Required | Description                                   |
| -------- | -------- | -------- | --------------------------------------------- |
| id       | `string` |          | The unique SR identifier assigned to the team |
| name     | `string` | yes      | The name of the team                          |

```javascript
const manchesterUnited = {
  id: "sr:competitor:1",
  name: "Manchester United"
};

const liverpool = {
  name: "Liverpool FC"
};
```

**See Also:** [`Event`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#event)

### Result

Represents result/score information for an event.

| Property | Type                      | Required | Description                                           |
| -------- | ------------------------- | -------- | ----------------------------------------------------- |
| result   | `Array<number \| string>` | yes      | The result of the event (e.g., scores, statistics)    |
| label    | `string`                  |          | Optional label describing what this result represents |

```javascript
// Match score
const finalScore = {
  result: [2, 1],
  label: "Final Score"
};

// Half-time score
const halftimeScore = {
  result: [1, 0],
  label: "Half-time"
};

// Period scores
const periodScores = {
  result: [25, 20, 30, 18],
  label: "Quarter Scores"
};
```

**See Also:** [`Event`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#event)

### BetSlip (Deprecated)

Represents a betting ticket containing one or more bets. Used only by deprecated [`BetShareResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betshareresponse-deprecated).

| Property  | Type                                                                                                            | Required | Description                                                                    |
| --------- | --------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------ |
| id        | `string`                                                                                                        | yes      | Client defined string to identify the ticket (unique in the client's system)   |
| betSlipId | `string`                                                                                                        |          | Client defined string to identify the bet slip (unique in the client's system) |
| betType   | `'single' \| 'multibet' \| 'sameGameMulti'`                                                                     | yes      | Valid values: `'single'`, `'multibet'`, `'sameGameMulti'`                      |
| currency  | `string`                                                                                                        | yes      | Currency as displayed                                                          |
| stake     | [`BetSlipOddsObject`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betslipoddsobject) |          | Stake for ticket                                                               |
| stake     | [`ValueObject`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#valueobject)             |          | Stake for ticket                                                               |
| payout    | [`ValueObject`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#valueobject)             |          | Payout for ticket                                                              |
| bets      | [`BetSlipBetObject`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betslipbetobject)   | yes      | Bets for ticket                                                                |

```javascript
const betSlip = {
  id: "ticket_123456",
  betSlipId: "654321",
  betType: "single",
  currency: "USD",
  combinedOdds: {
    decimalValue: 4.33,
    displayValue: "10/3"
  },
  stake: {
    value: "50.00"
  },
  payout: {
    value: "127.50"
  },
  bets: [
    {
      id: "bet_001",
      betType: "",
      markets: [
        {
          id: "1",
          name: "1X2",
          outcomes: [
            {
              id: "1",
              name: "Home",
              odds: 4.33
            }
          ]
        }
      ],
      odds: {
        decimalValue: 4.33,
        displayValue: "10/3"
      },
      event: {
        id: "sr:match:12356",
        name: "Liga La Liga Match 1"
      }
    }
  ]
};
```

#### ValueObject

| Property | Type     | Required | Description                       |
| -------- | -------- | -------- | --------------------------------- |
| value    | `string` | yes      | Displayed representation of value |

```javascript
const stake = {
      value: '50.00'
  };
```

#### BetSlipOddsObject

| Property     | Type     | Required | Description                                                      |
| ------------ | -------- | -------- | ---------------------------------------------------------------- |
| decimalValue | `number` | yes      | Decimal representation of odds used to display change indicators |
| displayValue | `string` | yes      | Displayed as is, representation of value                         |

```javascript
const combinedOdds: {
    decimalValue: 4.33
    displayValue: '10/3'
  };
```

#### BetSlipBetObject

| Property | Type                                                                                                                | Required | Description                                                               |
| -------- | ------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------- |
| id       | `string`                                                                                                            | yes      | Client defined string to identify the bet (unique in the client's system) |
| betType  | `'betBuilder' \| ''`                                                                                                |          | `'betBuilder'` for a bet builder bet; empty string for a regular bet      |
| event    | [`BetSlipEventObject`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betslipeventobject)   | yes      | Client defined string to identify the bet (unique in the client's system) |
| markets  | [`BetSlipMarketObject`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betslipmarketobject) | yes      | Client defined string to identify the bet (unique in the client's system) |
| odds     | [`BetSlipOddsObject`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betslipoddsobject)     |          | Odds for bet                                                              |

```javascript
const bet = {
    id: 'bet_001',
    betType: '',
    markets: [
        {
            id: '1',
            name: subTitle,
            outcomes: [
                {
                    id: '1',
                    name: title,
                    odds: 4.33
                }
            ]
        }
    ],
    odds: {
        decimalValue: 4.33,
        displayValue: '10/3'
    },
    event: {
        id: 'sr:match:12356',
        name: 'Liga La Liga Match 1'
    }
  };
```

#### BetSlipMarketObject

| Property          | Type                                                                                                                    | Required | Description                                                                   |
| ----------------- | ----------------------------------------------------------------------------------------------------------------------- | -------- | ----------------------------------------------------------------------------- |
| id                | `string \| number`                                                                                                      | yes      | The unique identifier of the market                                           |
| name              | `string`                                                                                                                | yes      | The name of the market                                                        |
| outcomes          | [`BetSlipOutcomeObject[]`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betslipoutcomeobject) | yes      | Array of outcomes for this market                                             |
| status            | `object`                                                                                                                |          | Market status                                                                 |
| status.isActive   | `boolean`                                                                                                               |          | **Deprecated.** Whether the market is active                                  |
| status.status     | `'active' \| 'deactivated' \| 'suspended' \| 'settled' \| 'cancelled'`                                                  |          | Market status string (preferred over `status.isActive`)                       |
| specifier         | `object`                                                                                                                |          | Market specifier information                                                  |
| specifier.value   | `string \| number`                                                                                                      |          | Specifier value (e.g., `"2.5"` for a Total market)                            |
| odds              | `object`                                                                                                                |          | Combined odds for the market                                                  |
| odds.decimalValue | `number`                                                                                                                |          | Numeric decimal representation of odds, used for displaying change indicators |
| odds.displayValue | `string`                                                                                                                |          | String representation of odds, displayed as-is with no formatting             |

```javascript
const market = {
  id: "sr:market:321",
  name: "Moneyline",
  outcomes: [
    {
      id: "sr:outcome:101",
      name: "PSG",
      odds: "1.48",
      status: { isActive: true }
    },
    {
      id: "sr:outcome:102",
      name: "Draw",
      odds: "4.83",
      status: { isActive: true }
    },
    {
      id: "sr:outcome:103",
      name: "Monaco",
      odds: "2.47",
      status: { isActive: true }
    }
  ],
  status: { status: "active" }
};
```

#### BetSlipOutcomeObject

| Property        | Type               | Required | Description                                                                   |
| --------------- | ------------------ | -------- | ----------------------------------------------------------------------------- |
| id              | `string \| number` | yes      | The unique identifier assigned to the market outcome                          |
| name            | `string`           | yes      | The name of the market outcome                                                |
| odds            | `number \| string` |          | Odds value displayed as-is — no formatting is applied                         |
| oddsDecimal     | `number`           |          | Numeric decimal representation of odds, used for displaying change indicators |
| competitor      | `string`           |          | Name or identifier of the competitor associated with this outcome             |
| status          | `object`           |          | Outcome status                                                                |
| status.isActive | `boolean`          |          | Whether the outcome is available for betting                                  |

```javascript
const outcome = {
  id: "sr:outcome:67898",
  name: "Denver Nuggets",
  oddsDecimal: 2.55,
  status: { isActive: true }
};
```

#### BetSlipEventObject

| Property        | Type                                                                                              | Required | Description                                                                                                                                                |
| --------------- | ------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id              | `string`                                                                                          | yes      | The unique identifier assigned to the event                                                                                                                |
| externalId      | `string \| number`                                                                                |          | Your unique identifier for the event                                                                                                                       |
| name            | `string`                                                                                          |          | Match name. If not provided, it is aggregated from teams as `"{teams[0].name} vs {teams[1].name}"`. If teams are also absent, the match name will be empty |
| teams           | `Array<{ id?: string; name: string }>`                                                            |          | Array of exactly two teams (home and away)                                                                                                                 |
| date            | `string`                                                                                          |          | Event date                                                                                                                                                 |
| sport           | [`Sport`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#sport)           |          | Sport information                                                                                                                                          |
| category        | [`Category`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#category)     |          | Category information (e.g., country, region)                                                                                                               |
| tournament      | [`Tournament`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#tournament) |          | Tournament information                                                                                                                                     |
| isLive          | `boolean`                                                                                         |          | Whether the event is currently live                                                                                                                        |
| liveCurrentTime | `string \| number`                                                                                |          | Current match time for live events (e.g., `"45:00"`, `"HT"`)                                                                                               |
| result1         | [`Result`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#result)         |          | Primary result/score information                                                                                                                           |
| result2         | [`Result`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#result)         |          | Secondary result information (e.g., half-time score)                                                                                                       |
| result3         | [`Result`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#result)         |          | Tertiary result information (e.g., period scores)                                                                                                          |

```javascript
const event = {
  id: "sr:event:98765",
  externalId: "123456",
  name: "Heat VS Nuggets",
  teams: [
    { id: "sr:competitor:113", name: "Miami Heat" },
    { id: "sr:competitor:118", name: "Denver Nuggets" }
  ]
};
```

**See Also:** [`BetShareResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#betshareresponse-deprecated), [`TicketsResponse`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#ticketsresponse)

### MatchEvent

Represents a match event (incident) that occurred during a sporting event, such as a goal, red card, or substitution.

| Property | Type             | Required | Description                                                                                                                                            |
| -------- | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| type     | `string`         | yes      | UPPER\_CASE event type identifier (see **Type Values** below)                                                                                          |
| metadata | `object \| null` |          | Additional data whose shape depends on `type` (see **Metadata by Type** below)                                                                         |
| tag      | `string`         |          | **Deprecated.** Channel identifier from which this match event originated. Prefer using `channelId`/`channelOriginId` passed separately in the request |

#### Type Values

**Soccer**

| Value                      | Description                                           |
| -------------------------- | ----------------------------------------------------- |
| `GOAL`                     | A goal was scored                                     |
| `YELLOW_CARD`              | A yellow card was issued                              |
| `RED_CARD`                 | A red card (or second yellow / direct red) was issued |
| `CORNER`                   | A corner kick was awarded                             |
| `PENALTY_KICK`             | A penalty kick was awarded                            |
| `PENALTY_SHOOTOUT`         | A penalty shoot-out event occurred                    |
| `OFFSIDE`                  | An offside was called                                 |
| `SECOND_HALF_STARTED`      | The second half began                                 |
| `OVERTIME_STARTED`         | Overtime began                                        |
| `PENALTY_SHOOTOUT_STARTED` | The penalty shoot-out phase began                     |

**Basketball**

| Value                | Description                           |
| -------------------- | ------------------------------------- |
| `ONE_POINT_SCORED`   | A free throw (1-point score) was made |
| `TWO_POINT_SCORED`   | A 2-point basket was scored           |
| `THREE_POINT_SCORED` | A 3-point basket was scored           |
| `TIMEOUT`            | A timeout was called                  |
| `PLAYER_EJECTED`     | A player was ejected (disqualified)   |
| `QUARTER_STARTED`    | A new quarter began                   |

**Tennis**

| Value               | Description                    |
| ------------------- | ------------------------------ |
| `GAME_WON`          | A game was won                 |
| `BREAK_WON`         | A break of serve was won       |
| `SET_WON`           | A set was won                  |
| `SET_STARTED`       | A new set began (set 2 onward) |
| `FIRST_SET_STARTED` | The first set began            |

**Cross-sport**

| Value                                    | Description                         |
| ---------------------------------------- | ----------------------------------- |
| `MATCH_STARTED`                          | The match began                     |
| `MATCH_ENDED`                            | The match ended                     |
| `TOURNAMENT_MATCH_START_IN_ONE_DAY`      | Scheduled match starts in 1 day     |
| `TOURNAMENT_MATCH_START_IN_ONE_HOUR`     | Scheduled match starts in 1 hour    |
| `TOURNAMENT_MATCH_START_IN_FIVE_MINUTES` | Scheduled match starts in 5 minutes |

#### Metadata by Type

| `type`            | `metadata` shape                       | Notes                                                           |
| ----------------- | -------------------------------------- | --------------------------------------------------------------- |
| `GOAL`            | `{ goal_number: string }`              | Total goals scored (home + away) at the time of the event       |
| `PENALTY_KICK`    | `{ team: "home" \| "away" }` or `null` | `null` when the team cannot be identified from the feed         |
| `TIMEOUT`         | `{ quarter_number: string }`           | Period number as a string; `"OT"` when in overtime (period > 4) |
| `QUARTER_STARTED` | `{ quarter_number: string }`           | Period number as a string; `"OT"` when in overtime (period > 4) |
| `GAME_WON`        | `{ set_number: string }`               | Current set number                                              |
| `BREAK_WON`       | `{ set_number: string }`               | Current set number                                              |
| `SET_STARTED`     | `{ set_number: string }`               | Current set number                                              |
| *(all others)*    | `null`                                 | —                                                               |

```javascript
// Soccer: 2nd goal scored
const goalEvent = {
  type: "GOAL",
  metadata: { goal_number: "2" }
};

// Soccer: penalty kick awarded to the home team
const penaltyEvent = {
  type: "PENALTY_KICK",
  metadata: { team: "home" }
};

// Basketball: timeout called in the 3rd quarter
const timeoutEvent = {
  type: "TIMEOUT",
  metadata: { quarter_number: "3" }
};

// Tennis: game won in the 2nd set
const gameWonEvent = {
  type: "GAME_WON",
  metadata: { set_number: "2" }
};

// Events with no metadata
const yellowCardEvent = { type: "YELLOW_CARD" };
const matchStartedEvent = { type: "MATCH_STARTED" };
```

## Adapter Config

### BrEventListConfig

Configuration for the bet recommendation event list widget. Note: The `allowedMarkets` and `blockedMarkets` properties are only applicable when using hosted Sportradar type with UOF (Unified Odds Feed) IDs.

| Property       | Type                                                                                                                      | Required | Description                                        |
| -------------- | ------------------------------------------------------------------------------------------------------------------------- | -------- | -------------------------------------------------- |
| layout         | [`EventListMarketsConfig`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#eventlistmarketsconfig) | yes      | Market layout configuration per sport              |
| allowedMarkets | [`SportMarketsMap`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#sportmarketsmap)               |          | Markets allowed for this widget, keyed by sport ID |
| blockedMarkets | [`SportMarketsMap`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#sportmarketsmap)               |          | Markets blocked for this widget, keyed by sport ID |

```javascript
const brEventListConfig = {
  layout: {
    "1": {  // Soccer
      sportId: 1,
      markets: [
        {
          title: "1X2",
          preMatchMarketId: 1,
          liveMarketId: 1,
          columns: ["1", "X", "2"]
        },
        {
          title: "Total",
          preMatchMarketId: 18,
          liveMarketId: 18,
          showSpecifier: true,
          columns: ["Over", "Under"]
        }
      ]
    }
  },
  allowedMarkets: {
    "1": {
      "1": true,                    // Allow 1X2 regardless of specifiers
      "10": false,                  // Allow Double Chance only when it has no specifiers
      "18": ["total=2.5"],          // Allow Total only with exact legacy specifier string
      "16": [{ hcp: ["0:1", "1:0"] }] // Allow Handicap for specific hcp values (any other keys forbidden)
    }
  }
};
```

**See Also:** [`EventListMarketsConfig`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#eventlistmarketsconfig), [`SportMarketsMap`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#sportmarketsmap)

### SportMarketsMap

A map of sport IDs to their market configurations with specifier filtering. Only applicable when using hosted Sportradar type with UOF (Unified Odds Feed) IDs.

| Property  | Type                         | Required | Description                                                                                   |
| --------- | ---------------------------- | -------- | --------------------------------------------------------------------------------------------- |
| [sportId] | `Record<string, Specifiers>` | yes      | Market configurations for a sport, where keys are market IDs and values are specifier filters |

**Specifiers Type** (`true | false | null | undefined | '' | SpecifierRule[]`):

| Value                                 | Meaning                                                                                    |
| ------------------------------------- | ------------------------------------------------------------------------------------------ |
| `true`                                | Allow/block this market id regardless of specifiers                                        |
| `false` / `null` / `undefined` / `''` | Allow/block only when the market has **no** specifiers                                     |
| `SpecifierRule[]`                     | Allow/block when **any** rule matches (OR). Rules are for markets **with** specifiers only |

**SpecifierRule** (array entry):

| Form               | Example                                | Meaning                                         |
| ------------------ | -------------------------------------- | ----------------------------------------------- |
| Legacy pipe string | `"total=2.5\|variant=sr:exact"`        | Exact key/value set (order of keys ignored)     |
| Structured object  | `{ total: true, variant: "sr:exact" }` | Exact key set; each key constrained (see below) |

**Per-key constraint** in a structured rule:

| Constraint | Meaning                                |
| ---------- | -------------------------------------- |
| `true`     | Any value for that key                 |
| `string`   | Exact value                            |
| `string[]` | Value must be one of the listed values |

Structured rules require the market to have **exactly** those specifier keys (no missing keys, no extra keys).

```javascript
const sportMarketsMap = {
  "1": {                                      // Soccer (sport ID 1)
    "1": true,                                // 1X2 - any / no specifiers
    "10": false,                              // Double Chance - no specifiers only
    "18": ["total=2.5", "total=3.5"],         // Total - exact legacy strings
    "16": [{ hcp: ["0:1", "1:0"] }],          // Handicap - hcp in set
    "14": [{ total: true, variant: "sr:exact" }] // any total + exact variant only
  },
  "2": {                                      // Basketball (sport ID 2)
    "219": true,                              // Money Line
    "225": [{ total: ["180.5", "200.5"] }]    // Total Points - specific lines
  }
};
```

### EventListMarketsConfig

Configuration for market layout display in event lists. This is a `Record<string, SportLayoutConfig>` where keys are sport IDs and values are layout configurations.

**Type:** `Record<string, SportLayoutConfig>`

#### SportLayoutConfig

| Property | Type                                                                                                                | Required | Description                           |
| -------- | ------------------------------------------------------------------------------------------------------------------- | -------- | ------------------------------------- |
| sportId  | `string \| number`                                                                                                  | yes      | Sport identifier                      |
| markets  | [`MarketLayoutConfig`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#marketlayoutconfig)[] | yes      | Array of market layout configurations |

#### MarketLayoutConfig

| Property         | Type                                                                                                                        | Required | Description                                                     |
| ---------------- | --------------------------------------------------------------------------------------------------------------------------- | -------- | --------------------------------------------------------------- |
| title            | `string`                                                                                                                    |          | Display title for the market column                             |
| preMatchMarketId | `string \| number`                                                                                                          |          | Market ID to use for pre-match events                           |
| liveMarketId     | `string \| number`                                                                                                          |          | Market ID to use for live events                                |
| showSpecifier    | `boolean`                                                                                                                   |          | Whether to display the market specifier (e.g., "2.5" for Total) |
| columns          | `Array<string \| ` [`ColumnConfig`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#columnconfig)`>` |          | Column definitions for outcome display                          |

#### ColumnConfig

| Property | Type     | Required | Description                          |
| -------- | -------- | -------- | ------------------------------------ |
| id       | `string` | yes      | Outcome ID to display in this column |
| title    | `string` |          | Custom column title                  |
| tKey     | `string` |          | Translation key for the column title |

```javascript
const eventListMarketsConfig = {
  "1": {  // Soccer
    sportId: 1,
    markets: [
      {
        title: "1X2",
        preMatchMarketId: 1,
        liveMarketId: 1,
        columns: ["1", "X", "2"]
      },
      {
        title: "Total",
        preMatchMarketId: 18,
        liveMarketId: 18,
        showSpecifier: true,
        columns: [
          { id: "12", title: "Over" },
          { id: "13", title: "Under" }
        ]
      }
    ]
  },
  "2": {  // Basketball
    sportId: 2,
    markets: [
      {
        title: "Money Line",
        preMatchMarketId: 219,
        liveMarketId: 219,
        columns: ["1", "2"]
      }
    ]
  }
};
```

**See Also:** [`BrEventListConfig`](https://apidocs.sportradar.com/resources/widgets/docs/adapter/Types.md#breventlistconfig)
