Every Sportradar betting widget that lets a punter pick an outcome, hands that
selection back to your application through a callback — onItemClick,
onAction, or the Data Adapter addToBetSlip function. Once you receive it, the
rest is yours: validating the selection and placing the bet.
This guide explains the shared data flow for all selection-emitting widgets and answers the questions integrators ask most often:
This is a conceptual, widget-agnostic guide. For the exact callback signature and payload of a specific widget, see that widget's API reference. The Per-widget callback reference table at the end maps each widget to its selection callback.
Prerequisites: familiarity with widget integration (see Getting Started) and your own bet slip / trading system.
Any widget that pushes a selection into a bet slip follows the same principles, regardless of the callback name:
onItemClickonItemClickonActiononAction / onItemClick (delegates to the composed widgets)onItemClickaddToBetSlipThe diagram below shows the lifecycle of a single selection, from the moment the widget receives odds to the moment your platform accepts or rejects the bet. The dashed boundary marks the hand-off: everything below it is your responsibility.
Generalized, the steps your integration must implement are:
The exact shape differs per widget, but every selection carries two things:
Selections use one of two identifier formats, discriminated by a type field:
type | Identifiers | Use when |
|---|---|---|
'uf' | event, market, outcome, optional specifiers (Sportradar identifiers, e.g. event: "sr:match:12345", market: "18", specifiers: "total=2.5") | The widget references outcomes by Sportradar's catalog. |
'external' | event, market, outcome (your own client-defined IDs) | The widget references outcomes by identifiers you mapped in your adapter. |
A representative selection object:
{
type: 'uf',
event: 'sr:match:12345', // event / match identifier
market: '18', // market identifier
specifiers: 'total=2.5', // optional, only for markets with a variant line
outcome: '12', // outcome identifier
odds: { // the SNAPSHOT shown at click time
type: 'eu', // 'eu' (decimal), 'uk' (fractional), 'us' (american)
value
For the full type definitions — SelectionOutcome, Odds, market and outcome
identifier rules — see the Adapter Types reference.
Treat the odds in the selection as indicative, not authoritative.
The odds value in the payload is a snapshot of what the user saw at the
instant they clicked. It exists so you can:
It is not a guaranteed price and must not be the price you settle the bet at. The single source of truth for the price you accept is always your own trading / pricing platform.
Accepting a ticket using the odds embedded in the selection — without re-pricing against your own system — exposes you to stale-price liability. Always re-price before acceptance.
The snapshot reflects the last update the widget received before the click — not necessarily the live market. Widgets refresh odds on a polling or streaming cadence that depends on the widget and its data source:
So: the snapshot is "as fresh as the last refresh," which is good enough to display, but you must re-fetch before you commit.
Use the identifiers in the selection to look up the authoritative price in your own system:
event / market / outcome (and specifiers). These are the
same identifiers your adapter already maps, so the lookup is straightforward.// Example: Handling a selection click from the widget
widget.onItemClick = async function(selection) {
// selection contains event, market, outcome, specifiers, and odds (the user's snapshot)
// Log the user's selection for debugging
console.log('Selection received:', selection);
// Fetch current/official odds from your backend or trading service
Keep the widget in sync with your bet slip via the adapter's
betSlipSelection endpoint. That subscription drives the widget's
selected-outcome indicators; it does not replace re-pricing at
acceptance. See Adapter Types.
Yes — always. Verification is a two-stage responsibility that belongs to your platform, not the widget:
When you receive a selection, run these checks before treating it as a placeable bet:
specifiers value still corresponds to an offered variant.When the current price is different from the originally displayed snapshot, you must follow a policy that aligns with your sportsbook's operational and regulatory requirements. Typically, this involves checking the current availability and price of the selection just before adding it to the bet slip. If the selection is no longer available (for example, if the market has closed or the outcome has been disabled), you should inform the user with a clear notification and prevent the addition.
If the odds have changed between the snapshot and the current price, you must decide how to handle this difference according to your site's policy. Options include: automatically accepting the better price if the odds have improved for the user, requiring the user to confirm any change in odds, or blocking the addition until the user explicitly acknowledges the new price. Regardless of which policy you implement, selections should always be added to the bet slip at the latest, authoritative price obtained from your own backend or trading system.
Common policies:
When you reject a selection, give the user an actionable, localized reason
rather than failing silently. Where a widget's callback supports a rejection
result (for example the Custom Bet Data Adapter addToBetSlip callback), return
the failure with a localized message so the widget can display it; otherwise show
the feedback in your own UI.
// Example: Custom Bet Data Adapter rejection
function addToBetSlip(args, callback) {
if (!isSelectionValid(args)) {
callback({
succeeded: false,
reason: localize('selection_unavailable'), // shown in the widget
});
return;
}
yourBetSlip.
A robust integration treats the widget as a fast, indicative source of intent and its own trading platform as the authoritative source of price and validity:
betSlipSelection.The widget shows odds; your platform owns odds. Never accept a ticket on the snapshot price — always re-price and re-validate against your own system before placement.
SelectionOutcome, Odds, and the betSlipSelection endpoint.addToBetSlip flow in detail.onItemClick + betSlipSelection example.| Widget | Callback | "Add to bet slip" signal |
|---|---|---|
| Bet Insights / Tournament Bet Insights | onItemClick(target, data) or onItemClick(args) | target === 'externalOutcome', or args.type === 'addSelectionsToBetSlip' |
| Bet Recommendation (Event List, Highlights, Leagues, Markets, My Combo, Swipe Bet) | onItemClick(target, data) | target === 'externalOutcome' (single) or 'externalOutcomes' (multiple) |
| Bet Concierge | onAction({ type, data }) | type === 'AddSelectionsToBetSlip' or 'CustomBetAddToBetSlip' |
| Custom Bet | Data Adapter addToBetSlip(args, callback) | function invoked on Add to bet slip click; return succeeded: true/false |