Personalize Bet Placement
ootb_sports_bet_placed is the required Sports event for Optimove Personalize. Send it each time an identified customer’s sports bet is accepted by the operator.
Personalize uses placed bets to build customer interests and aggregate popularity at the Selection, Market, Event, Type, Class and Category levels. It is the core Real-Time Event for standard Sports recommendation methods.
Send this event using the Server-Side Events API.
Before you begin
- The referenced Category, Class, Type, Event, Market and Selection must exist in Sports Inventory.
- Every event key must exactly match the corresponding Inventory key.
customermust be the stable identifier used when requesting recommendations for the same customer.- Send the event after the operator has accepted the bet. Do not report rejected bet attempts as placed bets.
- Send one event for each selection or leg. For a multi-selection bet, reuse the bet slip identifier and report the correct leg number on every event.
Example
{
"tenant": "your_tenant_id",
"timestamp": "2026-07-09T14:22:01Z",
"event": "ootb_sports_bet_placed",
"customer": "customer_12345",
"context": {
"ootb_betslip_key": "ticket_9001",
"ootb_bet_date_time": "2026-07-09T14:22:00Z",
"ootb_betslip_status": "open",
"ootb_bet_key": "bet_10001",
"ootb_bet_stake": 20,
"ootb_odds_decimal_price": 2.1,
"ootb_selection_key": "selection_man_utd",
"ootb_selection_name": "Manchester United",
"ootb_market_key": "market_match_result_7842",
"ootb_market_name": "Match Result",
"ootb_event_date_time": "2026-07-10T19:00:00Z",
"ootb_event_key": "event_7842",
"ootb_event_name": "Manchester United vs Liverpool",
"ootb_meeting_key": "type_premier_league",
"ootb_meeting_name": "Premier League",
"ootb_class_key": "class_england",
"ootb_class_name": "England",
"ootb_discipline_key": "category_football",
"ootb_discipline_name": "Football",
"ootb_leg_num": 1,
"ootb_bet_type": "Single",
"ootb_num_selections": 1,
"ootb_channel": "Desktop"
}
}Context fields
| Field | Required | Type | Personalize use | Notes |
|---|---|---|---|---|
ootb_betslip_key | Yes | String | Groups selections that belong to the same ticket or bet slip | Reuse it for every leg of the same multi-selection bet. Do not reuse it for an unrelated ticket. |
ootb_bet_date_time | Yes | String (date-time) | Determines when the customer interaction occurred and supports recency-based modelling | Send the accepted placement time as an ISO 8601 UTC timestamp. |
ootb_betslip_status | Yes | String | Records the ticket’s lifecycle state at placement | Use a stable status vocabulary. A newly accepted unresolved bet is commonly open. |
ootb_bet_key | Yes | String | Identifies the bet within the operator’s data and helps relate later updates | Use a stable unique identifier. Keep it consistent with the related settlement event. |
ootb_bet_stake | Yes | Number | Supplies bet value for stake-aware analysis and modelling | Must be zero or greater. Use a JSON number without a currency symbol. |
ootb_odds_decimal_price | Yes | Number | Supplies normalized decimal odds for ranking and modelling | Must be zero or greater. Send the decimal price for this selection. |
ootb_selection_key | Yes | String | Primary join to the Sports Inventory Selection and the item recommended by Personalize | Must exactly match Inventory selectionKey. |
ootb_selection_name | Yes | String | Supplies a readable outcome and supports name-based Sports models | Use the same name as Inventory where possible. The key remains the authoritative join. |
ootb_market_key | Yes | String | Joins the Selection to its Sports Inventory Market | Must exactly match Inventory marketKey. |
ootb_market_name | Yes | String | Supplies market meaning for modelling, filtering and diagnostics | Use the same name as Inventory where possible. |
ootb_event_date_time | Yes | String (date-time) | Distinguishes pre-event and in-play timing and joins activity to the fixture schedule | Send the scheduled event start as an ISO 8601 UTC timestamp. |
ootb_event_key | Yes | String | Joins the bet to its Sports Inventory Event or fixture | Must exactly match Inventory eventKey. |
ootb_event_name | Yes | String | Supplies fixture and participant context for Sports models | Use the same name as Inventory where possible. Keep team or participant naming consistent. |
ootb_meeting_key | Yes | String | Joins the bet to the Sports Inventory Type level | Despite the event field name, this maps to Inventory typeKey. |
ootb_meeting_name | Yes | String | Supplies readable competition, league or meeting context | Use the Inventory Type name. |
ootb_class_key | Yes | String | Joins the bet to the Sports Inventory Class level | Must exactly match Inventory classKey. |
ootb_class_name | Yes | String | Supplies readable Class context | Use the same name as Inventory where possible. |
ootb_discipline_key | Yes | String | Joins the bet to the Sports Inventory Category level | Despite the event field name, this maps to Inventory categoryKey. |
ootb_discipline_name | Yes | String | Supplies the readable sport or discipline | Use the Inventory Category name. |
ootb_leg_num | Yes | Number | Identifies this selection’s position in a multi-leg bet | Must be zero or greater. Send a whole number and use one consistent indexing convention. |
ootb_bet_type | Yes | String | Distinguishes structures such as Single, Multiple, System and Bet Builder | Use a stable vocabulary across placement and settlement events. |
ootb_num_selections | Yes | Number | Describes bet complexity and the number of expected leg events | Must be zero or greater. Send a whole number. |
ootb_platform | No | String | Accepted by the event schema but not currently retained by the Personalize Bet Placement mapper | Examples include iOS, Android and Web. |
ootb_channel | No | String | Supplies access-channel context | Examples include mobile, web and retail. |
ootb_license | No | String | Supplies regulatory or jurisdiction context where configured | Use a stable license identifier. |
ootb_betslip_stake | No | Number | Accepted by the event schema but not currently retained by the Personalize Bet Placement mapper | Must be zero or greater. Do not repeat the selection allocation here unless it equals the complete ticket total. |
ootb_bet_bonus | No | Number | Supplies the bonus-funded portion of the bet | Must be zero or greater. |
ootb_bet_sel_stake | No | Number | Supplies the stake allocated to this Selection | Must be zero or greater. Particularly useful for multi-selection value analysis. |
ootb_bet_sel_bonus | No | Number | Supplies the bonus amount allocated to this Selection | Must be zero or greater. |
ootb_is_live | No | Boolean or integer | Accepted by the event schema but not currently retained by the Personalize Bet Placement mapper | Prefer JSON true or false. If integers are used, use 1 for live and 0 otherwise. |
ootb_odds_number | No | Number | Supplies the numerator when fractional odds are also required | Send it together with ootb_odds_denominator. Decimal odds remain required. |
ootb_odds_denominator | No | Number | Supplies the denominator when fractional odds are also required | Send it together with ootb_odds_number. |
ootb_odds_american_price | No | Number | Accepted by the event schema but not currently retained by the Personalize Bet Placement mapper | Decimal odds remain the required normalized representation. |
ootb_leg_type | No | String | Adds semantic detail for the leg | Examples include To win, Handicap and Outright. |
ootb_each_way | No | Boolean or string | Describes an each-way leg where applicable | Prefer a Boolean. If strings are required by your source, use one stable vocabulary such as Yes and No. |
ootb_is_free | No | Boolean | Accepted by the event schema but not currently retained by the Personalize Bet Placement mapper | Send true only when no cash stake funded the bet. |
ootb_brand | No | String | Supplies downstream brand or skin context | The top-level tenant still determines event routing. Use a stable configured value when this context is needed. |
Sports Inventory joins
| Event context | Inventory | Meaning |
|---|---|---|
ootb_discipline_key | categoryKey | Sport or discipline |
ootb_class_key | classKey | Class |
ootb_meeting_key | typeKey | Competition, league, meeting or Type |
ootb_event_key | eventKey | Event or fixture |
ootb_market_key | marketKey | Market |
ootb_selection_key | selectionKey | Selection or outcome |
All six keys should describe one valid path through the Inventory hierarchy. Do not combine a Selection from one Event with the Event, Type or Category keys from another branch.
Multi-selection bets
Send one ootb_sports_bet_placed event for every selection. Each event should:
- use the same
ootb_betslip_keyfor the complete ticket; - identify its own Selection and parent Market/Event hierarchy;
- set
ootb_leg_numto that leg’s position; and - set
ootb_num_selectionsto the total number of selections on the ticket.
Validation checklist
- The wrapper contains
tenant,timestamp,event,customerandcontext. eventis exactlyootb_sports_bet_placed.- All required fields are present for every selection or leg.
- The six hierarchy keys match one valid Sports Inventory path.
- Bet and event timestamps are valid ISO 8601 UTC values.
- Decimal odds and numeric values are JSON numbers, not formatted strings.
- Multi-selection legs share the ticket identifier and total selection count.
- The event represents an accepted bet, not an attempted or rejected bet.
Updated about 2 hours ago
Did this page help you?
