Swivel Tech documentation · Optimove

Optimove campaign playbook

Optimove receives player information from Swivel in two completely separate ways: a nightly batch snapshot, and real-time events. Which one you build on decides what your campaign can see, and when it can fire.

Channel 1
Batch data · nightly
Channel 2
Events · real time
Events live
15
Scenarios
20

Read this first

Events do not update batch data. When a player places a bet and an event fires, their daily batch profile is unchanged — it only moves in the next nightly sync. A scheduled campaign sees yesterday's snapshot, never what happened five minutes ago.

Start here Two separate channels

Optimove receives player information in two totally different ways. They do not mix. Every block in this document is colour-coded to whichever channel it belongs to.

  • Batch · scheduled
  • Events · triggered
  • Campaign output
  • Reference

Batch data

Daily snapshot

Every night, Optimove pulls a fresh copy of every player's profile: balance, level, game history, transaction history. A daily "state of every player."

  • Updates once per day.
  • Covers all players, including those not active today.
  • Used to build target groups and send scheduled campaigns.
  • Source: our database.

Events

Real-time signals

When a player does something right now — places a bet, deposits, levels up — a signal fires instantly to Optimove. These are moments, not profiles.

  • Fires the instant something happens.
  • Fires on a player or system action. Most are in-session; some, such as redemption completed, fire from backend processes.
  • Used to trigger real-time campaigns.
  • Does not update batch or daily data.

Channel 1 Batch data — the daily snapshot

Every night, Optimove pulls a fresh copy of the entire player database. Here is how that works.

  1. Data lives in our database

    Player profiles, balances, levels, game activity, and transaction history.

  2. Nightly sync to Optimove

    Optimove automatically pulls this data once per day into its own system.

  3. Optimove builds profiles

    Each player gets a profile inside Optimove with all their attributes up to date.

  4. Marketers create target groups

    Filter players by any attribute: "level 5+, deposited $50+ in past 30 days."

  5. Scheduled campaign sent

    Campaign fires at a set time — 5am, say — to everyone in the target group.

Cadence

Batch data is a snapshot. It shows where every player stood at the end of yesterday. It is not live.

What Optimove receives — four data sets

Batch data is not a single file. It is four separate views, each with a different purpose. Optimove reads all four nightly and cross-references them by player ID.

Customer profiles

View 1 · one row per player

Updated nightly · the primary segmentation dataset

  • SC balance
  • GC balance
  • Level + rank
  • Tags
  • Is blocked
  • Allow email / SMS
  • Country + state
  • Last login date
  • Registration date
  • Acquisition source
  • Email + phone
  • Name + username

Game activity

View 2 · player × game × day

How Optimove uses these rows is defined on Optimove's side

  • SC bet amount
  • SC win amount
  • GC bet + win amount
  • Bet + win counts
  • Net gaming revenue
What we send

Raw daily rows, one per player/game/day. Optimove aggregates these into lifetime, 3-month, and 2-week totals for bet amounts, win amounts, NGR, game counts, win ratios, and more.

Transactions

View 3 · one row per transaction
  • PURCHASE — coin pack bought, amount + status
  • REDEEM — cashout request, amount + status (pending / approved / rejected)
  • BONUS_SC / BONUS_GC — bonus coins awarded
What we send

Individual transaction records. Optimove aggregates these into lifetime, 3-month, and 2-week totals for purchase amounts, redemption amounts, counts, cashout ratios, and more.

Game catalog

View 4 · one row per game

Used by Optimove to label game activity with names and categories

  • Game ID + name
  • Game category

All attributes available in Optimove today

Everything below is already live. Sourced from the four batch views — raw fields passed through directly, or computed by Optimove from the raw data.

Attribute index

Reference
Identity & profile — passed through from Customer view
  • Player ID
  • First Name
  • Last Name
  • Alias
  • Email
  • Mobile Number
  • Date of Birth
  • Age
  • Gender
  • Country
  • State
  • City
  • Address
  • Language
  • Currency
  • Registration Date
  • Last Login Date
  • Last Active At
  • Tags
  • Is Blocked
  • Is Test
  • Is Optin
  • Is Email Verified
  • Is SMS Verified
  • Is Top Spender?
  • Platform Preference
  • Platform Preference, Last 3 Months
  • Reachable for Web Push
  • Casino Name
Acquisition & UTM — Customer view + last session
  • Referral Type
  • Referred By Id
  • Marketing Id
  • Affiliate Id
  • Promo Code
  • Registered Platform
  • UTM Source (Last Session)
  • UTM Medium (Last Session)
  • UTM Campaign (Last Session)
  • UTM Content (Last Session)
  • UTM Term (Last Session)
Communication preferences — Customer view + OptiMail engagement
  • Allow Email
  • Allow SMS
  • Allow Push
  • Allow Whatsapp
  • Email Valid, Lifetime
  • OptiMail Unsubscribed
  • OptiMail — Days Since Last Opened
  • OptiMail — Days Since Last Clicked
  • Most Effective Channel
Balances — nightly snapshot
  • Balance (SC)
  • Gc Balance
  • Total Pending Redeems
  • Total Balance Loss
Gameplay — computed by Optimove · lifetime · last 3 months · last 2 weeks
  • Total SC Casino Bet Amount, Lifetime
  • Total SC Casino Bet Amount, Last 3 Months
  • Total SC Casino Bet Amount, Last 2 Weeks
  • Total SC Casino Win Amount, Lifetime
  • Total SC Casino Win Amount, Last 3 Months
  • Total SC Casino Win Amount, Last 2 Weeks
  • Total GC Casino Bet Amount, Lifetime
  • Total GC Casino Bet Amount, Last 3 Months
  • Total GC Casino Bet Amount, Last 2 Weeks
  • Total GC Casino Win Amount, Lifetime
  • Total Casino NGR, Lifetime
  • Total Casino NGR, Last 3 Months
  • Total Casino NGR, Last 2 Weeks
  • Average SC Casino Bet Amount, Lifetime
  • SC Win Ratio, Lifetime
  • SC Win Ratio, Last 3 Months
  • GC to SC Ratio, Lifetime
  • GC to SC Ratio, Last 3 Months
  • Number of Bets Made
  • Number of SC Casino Games, Lifetime
  • Number of GC Casino Games, Lifetime
  • Number of Casino Winning Games, Lifetime
  • Number of Casino Game Days, Lifetime
  • Number of Casino Game Days, Last 3 Months
  • Number of Casino Game Days, Last 2 Weeks
  • Number of Casino Mobile Games, Lifetime
  • Number of Casino Web Games, Lifetime
  • Favorite Casino Game
  • Favorite Category
  • Gameplay Activity on Slots
  • Gameplay Activity on Originals
  • Gameplay Activity on Other Games
  • First Casino Game Date
  • Last Casino Game Date
  • Last Bet Made
  • Days Since Last Casino Game
  • Days Since Last SC Casino Game
  • SC Bet Percentile By LCS
  • SC Bet Percentile By LCS, Last 3 Months
  • SC Bet Percentile By LCS, Last 2 Weeks
Purchases — computed by Optimove from Transactions
  • Total Purchase Amount, Lifetime
  • Total Purchase Amount, Last 3 Months
  • Total Purchase Amount, Last 2 Weeks
  • Number of Purchases, Lifetime
  • Number of Purchases, Last 3 Months
  • Number of Purchases, Last 2 Weeks
  • Number of Purchase Days, Lifetime
  • Number of Purchase Days, Last 3 Months
  • Number of Purchase Days, Last 2 Weeks
  • Number of Purchase Days, Last Calendar Month
  • Average Purchase Amount, Lifetime
  • Average Purchase Amount, Last Month
  • Average Purchase Amount, Last 3 Months
  • Average Monthly Purchase Amount, Lifetime
  • First Purchase Date
  • First Purchase Amount, Lifetime
  • Last Purchase Amount, Lifetime
  • Days Since First Purchase
  • Days Since Last Purchase
  • Purchase Amount Monthly Change, Lifetime
  • Purchase Amount Since Reactivated
  • Purchases Since Reactivated
  • Purchase Percentile By LCS
  • Purchase Percentile By LCS, Last 3 Months
  • Frequency, Last 3 Months
  • Frequency, One Year
Redemptions — computed by Optimove from Transactions
  • Total Redeem Amount, Lifetime
  • Total Redeem Amount, Last 3 Months
  • Total Redeem Amount, Last 2 Weeks
  • Number of Redeems, Lifetime
  • Number of Redeem Days, Lifetime
  • Last Redeem Date
  • Last Completed Redemption Date
  • Days Since Last Redeem
  • Cashout Ratio, Lifetime
  • Cashout Ratio, Last Month
  • Cashout Ratio, Last 3 Months
  • Net Cash, Lifetime
  • Net Cash, Last 2 Weeks
Custom attributes — defined by Swivel
  • Net Purchase (lifetime)
  • Net Purchase Last 3 Months
  • Net Purchase including pending and balance
  • Net Score
  • NGR Total Purchase − Total Redemption
  • Redemption Ratio
Lifecycle & activity — computed by Optimove
  • Lifecycle Stage
  • Previous Lifecycle Stage
  • Lifecycle Stage Before Churn
  • Days Since Lifecycle Stage Change
  • Activity Days, Lifetime
  • Number of Activity Days, Lifetime
  • Number of Activity Days, Last 3 Months
  • Number of Activity Days, Last 2 Weeks
  • Days Since First Activity
  • Days Since Last Activity
  • Days Since Last Login
  • Days Since Last Visit
  • Days Since Registration
  • Months Since Registration
  • Last Activity Date
  • Dormant Activity Layer
  • Dormant Type
  • Number of Times Churned, Lifetime
  • Days In Churn, Lifetime
  • Days In Reactivated, Lifetime
  • Days Since Last Reactivation
  • Number of Visits, Last 14 Days
  • Number of Visits, Last 30 Days
  • Avg. Session Time in Minutes
  • Total Visit Time, Last 14 Days
  • Total Visit Time, Last 30 Days
Predictive scores — Optimove AI / ML
  • Churn Probability Score
  • Churn Factor
  • Churn Factor, One Year
  • Reactivation Probability Score
  • Conversion Probability Score
  • Becoming Top Spender Score
  • Rank in Churn Probability
  • Rank in Reactivation Probability
  • Rank in Conversion Probability
  • Rank in Becoming Top Spender
  • Rank by LCS Churn Probability
  • Rank by LCS Becoming Top Spender
Campaign intelligence — Optimove
  • Response Rate, Last 7 Days
  • Response Rate, Last 30 Days
  • Number of Campaigns, Last 7 Days
  • Number of Campaigns, Last 30 Days
  • Most Effective Channel
  • Content — Game Category
  • Content — Promotion Type
  • Content — Tone of Voice
  • Random Customer Percentage
  • Random Customer Slice

Channel 2 Events — real-time signals

When a player does something, a signal fires instantly. These drive campaigns for players who are active right now.

  1. Player action

    Player places a bet, deposits, levels up.

  2. Event fires

    Signal sent instantly with rich data attached.

  3. Queue

    Brief buffer, milliseconds, to guarantee delivery.

  4. Optimove receives

    Event arrives in Optimove within seconds.

  5. Campaign triggers

    If conditions match, the campaign fires immediately.

Events we send — with what is attached

Each event carries a snapshot of that player's current state, so real-time campaigns have fresh data without needing to query the database. Full payloads are in the event catalogue.

bet_finished

After every bet

Fires whether the player won or lost. Carries current balances, level, risk score, game result, and DWH aggregate metrics — all fresh at the moment of the bet.

Sample contextJSON
sc_balance: 12232.79   risk_total_risk_score: 0
  level_name: "Unicorn 3"   login_count_7d: 3
  bet_amount_today: 13750.20   bet_amount_7d: 73290.62
  bet_amount_lifetime: 85998.23   win_amount_today: 10909.28
  purchase_count_lifetime: 3   bonus_claimed_30d: 11.02

completed_redemption_* fields are excluded to stay within Optimove's attribute count limit.

deposit

On every purchase

Carries updated balances, level, risk score, purchase amount, sw_package_type, is_first_time_deposit, affiliate and marketing IDs, and DWH aggregate metrics.

Sample contextJSON
sc_balance: 12232.79   deposit_in_usd: 2.99
  sw_package_type: "standard"   is_first_time_deposit: false
  affiliate_id: "N/A"   purchase_amount_today: 0
  purchase_amount_lifetime: 2.97   purchase_count_lifetime: 3

completed_redemption_* fields are excluded to stay within Optimove's attribute count limit.

level_change

Fires on level up

Carries new level, rank, and current balances. A good trigger for congratulations.

redemption_requested

Cashout submitted

Carries redemption amount and current pending redemption total.

redemption_completed

Cashout approved

Carries updated redemption history windows. Triggers for completed redeemers.

bonus_claim

Bonus claimed

Carries cumulative bonus totals. Enables campaigns for frequent bonus claimers.

sign_up

Once, on registration

Triggers onboarding campaigns. Carries initial profile state.

user_active

Every ~120s while in session

Full snapshot of all DWH aggregate metrics, plus completed_redemption_* unlike bet_finished and deposit. Keeps the RT Attributes V2 profile fresh even in sessions with no bets or deposits.

Why this event matters →

Independence

An event firing does not update a player's batch profile. The batch profile updates once per night via the daily sync, period. A campaign scheduled for tomorrow will use tomorrow night's batch data, not the events that fired today.

Phase 2 enrichment — DWH aggregates on all events

All backend events now carry the fields below.

  • bet_amount_today/7d/30d/lifetime
  • win_amount_today/7d/30d/lifetime
  • purchase_amount_today/7d/30d/lifetime
  • purchase_count_today/7d/30d/lifetime
  • completed_redemption_amount_7d/30d/lifetime
  • completed_redemption_count_30d/lifetime
  • bonus_claimed_30d/lifetime
  • login_count_7d
  • redemption_rate_lifetime
  • net_purchase_lifetime
30-second lag

All DWH aggregate values lag roughly 30 seconds behind real values. A bet_finished event can fire with bet_amount_today = 0 even though the bet amount is non-zero — the DWH has not yet reflected it.

completed_redemption_* exclusions

Removed from bet_finished and deposit to stay within Optimove's per-event attribute count limit. These fields are present on redemption_requested, redemption_completed, level_change, bonus_claim, user_active, and initial_daily_balance.

Defaults and signs

bonus_claimed can be negative — it is calculated as SUM(bonus_amount − bonus_give_up). Free spin wins are counted in win amounts instead. All numeric DWH fields default to 0, never null. All string fields (affiliate_id, sw_package_id) default to "N/A" when empty.

Event configuration Three event types in Optimove

Before creating a campaign, events must be configured in Optimove's back office as one of three types. Each event is one type only, not all three.

Simple event

Configured

One action → fires immediately, every time

Fires once each time the defined action happens. The campaign evaluates trigger conditions against each event independently and fires if all pass. This is the most common type.

Swivel examples
  • deposit → show $20 offer if player bought a $10 standard pack
  • bet_finished → top-up offer if sc_balance < 1
  • bonus_claim → engagement follow-up campaign
  • redemption_requested → purchase incentive if sc_balance < 2

All Swivel events are Simple events by default.

Repeated event

Configured

Event fires always · trigger activates on the Nth occurrence

The event fires every time the action happens — always. The trigger activates when the count reaches N. Optimove tracks occurrences internally; no counter value is sent from Swivel. Two counting modes:

  • Occurred X times — fires on the Xth event. The counter starts when the customer enters the trigger logic, not from account creation.
  • Consecutive X times — the same event must fire back to back. Any different event resets the streak. Whether a condition mismatch on the same event type also resets is unverified.
Time windows

To require N occurrences within a timeframe (3 deposits within 3h), add the same event multiple times in the trigger sequence and set the timeframe at the bottom of the trigger config. Do not use a single "Occurred N times" condition for this — it has no time window.

Swivel examples
  • 3rd deposit after trigger entry → loyalty reward (Occurred 3 times)
  • 3 deposits within 3h → loyalty reward (Deposit ×3 in trigger, 3h window at bottom)
  • 3 consecutive bets → "you're on a roll" bonus (any non-bet event resets)

deposit and bet_finished are set up as Repeated events. Occurrence count is tracked by Optimove from trigger entry.

Uncompleted sequence

Needs setup

A happens, B expected but does not → fires

Optimove watches for a first action (A), then waits for a follow-up action (B). If B does not happen within the time window, the campaign fires. This is the cart-abandonment equivalent — the player started a journey but did not finish it.

Swivel examples
  • sign_up → no deposit within 30 min → first purchase welcome offer
  • deposit → no bet_finished within 15 min → "you have coins, try a game"
  • bet_finished → no new bet within 20 min → keep-playing nudge
Not yet configured

Each sequence (A → expected B) must be added as a new event in Optimove BO before it can be used in any campaign.

Campaigns Two types of campaign

The type of campaign depends on which channel it listens to — batch data or events.

Scheduled campaign

Batch data

For inactive players

  1. Batch data refreshed last night

    Every profile is up to date as of yesterday's snapshot.

  2. Target group filters applied

    "Not active in 7+ days AND country = US AND is_blocked = No AND total purchases over $100."

  3. Campaign fires at scheduled time

    5am ET, say — when servers are quiet and the message reads as a morning nudge.

  4. Email or push sent

    "We miss you — here's 500 GC to come back."

Best for

Win-back, reactivation, loyalty milestones, risk-based segmentation.

Triggered campaign

Events

Primarily active players — though some events fire regardless of session

  1. Player does something right now

    Places a bet, deposits, levels up, completes a redemption.

  2. Event fires instantly

    Signal arrives at Optimove within seconds, carrying fresh player data.

  3. Conditions checked in real time

    "Deposit event AND first purchase ever AND balance now over 1000 SC."

  4. Campaign triggers immediately

    Pop-up, push notification, or bonus fires while the player is still in session.

Best for

Purchase upsell, level-up celebration, first-deposit welcome, redemption follow-up.

Target groups — used in both campaign types

A target group is a saved filter of player attributes. Both scheduled and triggered campaigns require a target group — it defines the eligible pool. Use common sense about what belongs there. Balance changes every session, so a batch snapshot will always be stale. Average purchase amount means nothing for a player with two purchases.

In scheduled campaigns

The TG defines who gets the email or push at the scheduled time.

In triggered campaigns

The TG defines who is eligible before the trigger condition is checked.

The one fact that decides everything

Target group membership is evaluated by Optimove at a time you do not control, against the nightly batch snapshot. That single fact decides what may and may not go into a target group.

Critical distinction Target groups vs trigger conditions

Two completely different places where Optimove checks whether a player should receive a campaign. They must carry different types of data.

Target group

Batch · unknown time · slow fields

Use stable, slowly-changing attributes. Balance changes every session, so a batch snapshot is always behind. Averages and ratios are only meaningful if the player has enough data points to make them statistically valid.

Put here
  • Country = US
  • Is banned = No
  • Opted in = Yes
  • Player type: new vs existing
  • Total purchases > $50 — lifetime total, stable
  • Redemption count > 5 — stable count
Never here
  • sc_balance < 1 — changes every bet, always stale
  • Average purchase amount under 5 purchases — meaningless

Balance belongs in the trigger condition, not here. It changes on every bet, and the batch snapshot will never reflect the right moment. Lifetime totals and counts are fine — they accumulate slowly.

Trigger condition

Checked instantly · live data

The trigger condition is evaluated the instant an event arrives, against the data attached to that event. The event payload carries live values from the exact moment of the action.

Put here
  • sc_balance < 1
  • risk_score < 70
  • purchase_amount = $10
  • avg_purchase between $4.99 and $9.99
  • pending_redemption < 2 SC

Why this works: the event payload is built at the exact moment the player acts. Balance, risk score, purchase amount — all reflect reality right now. Trigger conditions read that snapshot instantly.

Worked example — bet finished, balance under 1 SC

  1. Target group, static

    Existing / new (visitor) user · not banned · opted in · country = US

  2. Event fires

    bet_finished { sc_balance: 0.8, risk_score: 45 }

  3. Trigger condition

    risk_score < 70 passes · sc_balance < 1 passes

  4. Campaign fires

    Top-up offer shown to the player.

Step by step How to build a campaign in 4 steps

Every campaign — triggered or scheduled — follows the same setup flow.

  1. Define your target group — who is eligible?

    The target group is the pool of players who could receive this campaign. For triggered campaigns, use slow-changing attributes only. Never put balance, purchase amounts, or redemption data here — those values are stale by the time Optimove reads them.

    Recommended base TG

    Add to nearly every triggered campaign
    • Country = US
    • Is Blocked = No
    • Allow Push / Email = Yes
    • Player Type = Existing

    Do not add sc_balance or purchase amounts to a target group for triggered campaigns. Optimove evaluates TG membership at an unknown time using batch data — those values will be outdated by the time the event fires.

  2. Choose your trigger — what starts the campaign?

    Pick an event from Swivel. The event type (Simple, Repeated, Uncompleted Sequence) is already determined by how the event was configured in Optimove BO — you do not choose it here. You can also configure a trigger as a combination of events within a time window: sign_up followed by deposit within 30 min, or 3 bet_finished events within 1 hour.

    • bet_finished
    • deposit
    • redemption_requested
    • redemption_completed
    • bonus_claim
    • level_change
    • sign_up
    • user_active
    • initial_daily_balance
    • cashier_exit
    • promo_award_selected
  3. Set trigger conditions — what must be true in the payload?

    Conditions are checked the instant the event fires, against the live data attached to that event. All conditions must be true for the campaign to fire.

    Core fields — live snapshot, Phase 1, all events
    • sc_balance
    • gc_balance
    • risk_total_risk_score
    • xp_total
    • xp_to_next_level
    • pending_redemption_amount_in_usd
    • level_name
    • level_rank
    deposit-only fields, Phase 1
    • deposit_in_usd
    • is_first_time_deposit
    • sw_package_type
    • affiliate_id
    • marketing_id
    • payment_method
    bet_finished-only fields, Phase 1
    • is_winning_bet
    • amount_won_in_usd
    • original_amount
    • multiplier
    • game_id
    • game_type
    DWH aggregate fields — all events, Phase 2, ~30s lag
    • bet_amount_today/7d/30d/lifetime
    • win_amount_today/7d/30d/lifetime
    • purchase_amount_today/7d/30d/lifetime
    • purchase_count_today/7d/30d/lifetime
    • bonus_claimed_30d/lifetime
    • login_count_7d
    • redemption_rate_lifetime
    • net_purchase_lifetime
    Redemption aggregates — not on bet_finished or deposit
    • completed_redemption_amount_7d/30d/lifetime
    • completed_redemption_count_30d/lifetime
    DWH aggregate fields lag ~30 seconds

    A player places their first ever bet of 30 SC. bet_finished fires instantly, but bet_amount_today in that payload may still be 0. Use threshold conditions (> X), not exact equality (= N), when building on DWH aggregate fields.

    You can combine multiple conditions with AND. The campaign fires only when all are true, which lets you be precise about who gets what offer at exactly the right moment.

  4. Design and launch the campaign

    Choose your channel and craft the message. For triggered campaigns the timing is automatic — the campaign fires the moment conditions are met. No scheduling needed.

    In-app popup

    Best while the player is in session.

    In-app toast

    A brief, dismissible banner — lighter-touch than a popup, no click required.

    Push notification

    Reaches them whether or not they are on site.

    Email

    Works, but the moment has passed by the time they open it.

    SMS

    High reach, high cost. Reserve for high-value moments.

Target group guide Building target groups that work

Not all attributes are equal. Some give reliable segments from day one; others need sufficient player history before they mean anything. Getting this wrong means campaigns firing to the wrong people.

Start every triggered campaign with this base TG

These four filters keep you compliant, exclude the wrong audience, and ensure campaigns reach reachable players only. Add extra filters on top.

  • Country = US (or target markets)
  • Is Blocked = No
  • Allow Email or Allow Push = Yes
  • Player Type = Existing / Visitor

Statistical gotchas — when attributes mislead you

Some attributes only make sense after a player has enough history. Using them too early produces garbage segments and campaigns that fire to the wrong people.

Average purchase amount

One large outlier purchase completely skews the average for players with few transactions. A player who bought once at $50 has an "average" of $50 — a sample of one, not a behavioural signal.

Add Number of Purchases, Lifetime ≥ 5 first.

Cashout ratio

A player with one redemption has either a 0% or 100% ratio — mathematically correct but statistically useless. You cannot segment meaningfully on ratios with 1–2 data points.

Add Number of Redeems, Lifetime ≥ 3 first.

Churn probability score

Optimove's churn model needs months of behavioural history to be accurate. Players who registered recently produce unreliable scores that may cause you to target — or exclude — the wrong people.

Add Months Since Registration ≥ 3 first.

SC win ratio

Win ratios fluctuate wildly with small sample sizes. A player who won 5 of their first 7 bets looks like a 71% winner — that is pure variance, not a reliable signal.

Only meaningful with Number of Bets Made ≥ 20.

Frequency, last 3 months

This measures activity over the last 90 days. For a player registered 20 days ago, "last 3 months" is mostly empty — the frequency will be misleadingly low and segment them incorrectly.

Add Days Since Registration ≥ 90 first.

Percentile vs raw amounts

Raw purchase amounts like "lifetime total > $50" mean different things depending on how long a player has been registered. A 2-week player at $50 and a 2-year player at $50 are very different segments.

Prefer Purchase Percentile By LCS over raw Total Purchase Amount.

Risk score and redemption rate belong in trigger conditions

Both values change over time. Putting them in a target group means Optimove evaluates them at an unknown time against stale batch data — by the time an event fires, TG membership may not reflect the player's current state. Put risk_score < 70 or redemption_rate < 75% in the trigger condition, which reads the live value from the event payload at the exact moment it fires.

Event reference Complete event catalogue

Every event Swivel sends to Optimove, with real production payloads. Fifteen events across two transports: ten sent backend to backend, five fired by the Optimove browser SDK.

Transport A

Backend events

10 events · ad-blocker safe

Sent server to server. Unaffected by ad blockers. Every one of these carries the common context block documented at the end of this section.

sign_up

Once · after registration
Event-specific fields
  • type_of_registration
  • country_code
  • state_code
  • promo_code
  • referred_by_id
  • affiliate_id
  • marketing_id

No DWH aggregates — the user is brand new. Balances are 0, and there is no purchase or bet history yet.

Real payloadJSON
"type_of_registration": "email"
  "country_code": "IE"
  "promo_code": "N/A"
  "referred_by_id": "N/A"
  "affiliate_id": "N/A"
  "gc_balance": 0
  "sc_balance": 0
  "xp_total": 0

deposit

Every completed purchase
Event-specific fields
  • deposit_id
  • deposit_in_usd
  • is_first_time_deposit
  • original_deposit
  • original_currency
  • payment_method
  • requested_deposit
  • sw_package_id
  • sw_package_type
DWH lag risk

purchase_count_* may not yet reflect this deposit — the DWH lags ~30s. See the user_active recommendation.

Real payloadJSON
"deposit_in_usd": 2.99
  "is_first_time_deposit": false
  "payment_method": "creditCard"
  "sw_package_type": "standard"
  "purchase_count_lifetime": 3     // may still read 2
  "purchase_count_30d": 2
  "purchase_amount_lifetime": 2.97
  "sc_balance": 12232.78

bet_finished

Every bet round
Event-specific fields
  • game_id
  • game_type
  • provider_id
  • amount_in_usd
  • amount_won_in_usd
  • original_amount
  • original_currency
  • multiplier
  • is_winning_bet
DWH lag risk

bet_amount_* and win_amount_* may lag ~30s. High-frequency event — fires on every single bet.

Real payloadJSON
"game_id": "dice"
  "game_type": "originals"
  "amount_in_usd": 1250
  "amount_won_in_usd": 1212.12
  "is_winning_bet": true
  "multiplier": 0.9697
  "bet_amount_30d": 73654.47
  "sc_balance": 12232.78

level_change

On level up
Event-specific fields
  • level_experience_threshold

Best event for level-gated campaigns. No DWH lag concerns for level itself.

Real payloadJSON
"level_name": "Yellow Gold 2"
  "level_rank": "Yellow Gold"
  "level_experience_threshold": 7500
  "xp_total": 7574.24
  "xp_to_next_level": 2425.76
  "sc_balance": 12232.78

bonus_claim

When a bonus is claimed
Event-specific fields
  • bonus_id
  • bonus_name
  • bonus_type
  • claimed_amount
  • claimed_currency
  • free_spin_count
  • user_bonus_id

bonus_type is "cash" or "freeSpins". For free spins claimed_amount is null and free_spin_count carries the value.

Real payload · cashJSON
"bonus_name": "CashCash20"
  "bonus_type": "cash"
  "claimed_amount": 20
  "claimed_currency": "gc"
  "free_spin_count": null
  "bonus_claimed_30d": 11.02
Real payload · freeSpinsJSON
"bonus_name": "FreeSpin"
  "bonus_type": "freeSpins"
  "claimed_amount": null
  "claimed_currency": null
  "free_spin_count": 100

redemption_requested

Cashout submitted
Event-specific fields
  • payout_id
  • requested_amount
  • requested_currency

Use for retention plays: the player has intent to withdraw — consider a purchase incentive if sc_balance is low after the redemption.

Real payloadJSON
"requested_amount": 10
  "requested_currency": "sc"
  "sc_balance": 12232.78
  "pending_redemption_amount_in_usd": 0
  "completed_redemption_count_lifetime": 6

redemption_completed

Payout clears · backend
Event-specific fields
  • payout_id
  • requested_amount
  • requested_currency
  • paid_out_amount
  • paid_out_currency

Fires from a backend process, not a player action. Good for a "your withdrawal cleared" follow-up — but the player is probably not in session, so use email or push, never a popup.

Real payloadJSON
"requested_amount": 10
  "requested_currency": "sc"
  "paid_out_amount": 0.00473139
  "paid_out_currency": "eth"
  "completed_redemption_count_30d": 5
  "completed_redemption_amount_lifetime": 55

user_active

Every ~2 min in session
Recommended No event-specific fields
Recommended for DWH-aggregate campaigns

By the time this fires, about 2 minutes after the last activity, all aggregate fields have settled in the DWH. Read the full recommendation →

Real payloadJSON
// Only common context — same fields as every other event
  "purchase_count_lifetime": 3     // settled
  "bet_amount_30d": 73654.47       // settled
  "sc_balance": 12232.78
  "level_name": "Yellow Gold 2"
  "xp_total": 7574.24

initial_daily_balance

Once per day · first session
No event-specific fields

Useful for daily check-in campaigns and day-start balance nudges. Fires once per player per calendar day on their first login.

Real payloadJSON
// Same context as user_active — full aggregate snapshot
  "sc_balance": 12232.78
  "purchase_count_today": 0
  "bet_amount_today": 13750.20
  "login_count_7d": 3

promo_award_selected

Player picks a promo offer
Event-specific fields
  • award_id
  • promo_id

Frontend-triggered, backend-relayed: POST crm/events/select-offer → queue → worker → Optimove. Because it is relayed server to server, ad blockers cannot suppress it.

Schema, not a captured sample

No production sample captured yet — fields below are per the backend DTO. Carries database enrichment only: no DWH aggregates and no risk score, the same shape as sign_up.

SchemaJSON
"award_id": "a1a4a2ba-2f1e-4b6c-9ad2-6c0a8d51e4f7"
  "promo_id": "7f3c9e28-4d51-4a0e-b6c9-8e2d1f0a5b34"
  "gc_balance": 41158
  "sc_balance": 12232.78845139062
  "level_name": "Yellow Gold 2"
  "level_rank": "Yellow Gold"
  "pending_redemption_amount_in_usd": 0
  "xp_total": 7574.2387711363635
  "xp_to_next_level": 2425.7612288636365
Transport B

Frontend SDK events

5 events · ad blockers apply
Delivery is not guaranteed

These are fired by the Optimove browser SDK from the player's own device — the only events that do not go server to server. A share of them is suppressed by ad blockers and privacy extensions. Do not build a campaign whose correctness depends on one of these firing for every player.

set_user_id_event

Identity

Binds the anonymous visitor ID the SDK has been using to the authenticated player ID. Fires in the sign-up and login sequence. Everything the visitor did before this point is stitched onto the player profile.

Real payloadJSON
"userId": "57affc85-0776-4f30-ae92-4a1c38ca58f9"
  "originalVisitorId": null
  "updatedVisitorId": null

set_email_event

Identity

Sets the player's email on the Optimove profile from the browser. Fires in the sign-up sequence alongside set_user_id_event.

Real payloadJSON
"email": "regms61e418242ca1@test.swivelgaming.com"

set_page_visit_event

Navigation

Fires on each page view. This is the event Optimove needs to display an in-app popup: a popup can only be rendered on a live frontend page event, so any popup campaign must include a page visit in its trigger sequence.

No captured sample. Carries the SDK's standard page context.

cashier_exit

Abandonment · Phase 4, v3.73

Fires when the player closes the cashier without completing a purchase. The abandonment signal behind scenario 15.

Frontend event — ad blockers suppress a percentage of fires. Treat any cashier-abandonment campaign as best-effort coverage.

pwa_install

Engagement

Fires when the player installs the site as a progressive web app on their device. A strong engagement signal — installers are materially more likely to return.

No captured sample.

Shared

Common context

Every backend event except sign_up

All DWH-sourced aggregate fields below are available in every event as campaign conditions. They are sourced from ClickHouse and carry a ~30-second lag behind the action that fires the event.

Field index

Purchases — DWH, ~30s lag
  • purchase_count_lifetime
  • purchase_count_30d
  • purchase_count_7d
  • purchase_count_today
  • purchase_amount_lifetime
  • purchase_amount_30d
  • purchase_amount_7d
  • purchase_amount_today
Bets & wins — DWH, ~30s lag
  • bet_amount_30d
  • bet_amount_7d
  • bet_amount_lifetime
  • bet_amount_today
  • win_amount_30d
  • win_amount_7d
  • win_amount_lifetime
  • win_amount_today
Redemptions — DWH, ~30s lag
  • completed_redemption_count_30d
  • completed_redemption_count_lifetime
  • completed_redemption_amount_30d
  • completed_redemption_amount_7d
  • completed_redemption_amount_lifetime
  • redemption_rate_lifetime
Bonuses — DWH, ~30s lag
  • bonus_claimed_30d
  • bonus_claimed_lifetime
Live balances & profile — no lag
  • sc_balance
  • gc_balance
  • pending_redemption_amount_in_usd
  • net_purchase_lifetime
  • level_name
  • level_rank
  • level_id
  • xp_total
  • xp_to_next_level
  • login_count_7d
  • risk_total_risk_score
  • are_email_notifications_enabled
  • are_phone_notifications_enabled
  • user_id
  • user_email
  • event_id
DWH lag affects campaign reliability

If your campaign condition checks any DWH field above, read the user_active recommendation before choosing your trigger event.

Critical guideline Use user_active for DWH-aggregate campaigns

Campaigns triggered by action events and filtered on DWH aggregates are fundamentally unreliable. Here is why, and the right approach.

Do not do this

Do not trigger on action events when your condition checks aggregate counts. The data warehouse that populates purchase_count_lifetime, bet_amount_30d and the rest has a ~30-second propagation delay. When a deposit event fires, the DWH aggregate for that same deposit has almost certainly not updated yet. Sometimes it has, sometimes it has not — which makes the campaign non-deterministic.

Concrete example — fire when a player makes their 3rd deposit

Wrong — trigger on deposit

  1. T+0:00

    Player completes their 3rd deposit.

  2. T+0:00

    deposit fires instantly to Optimove.

  3. T+0:00

    Optimove reads purchase_count_lifetime = 2. The DWH has not caught up.

  4. T+0:00

    Condition ≥ 3 fails. The campaign does not fire.

  5. T+0:30

    DWH catches up: the count is now 3, but the event moment has passed.

The campaign silently fails. On other occasions the DWH updates in time, so it fires some of the time but not always.

Right — trigger on user_active

  1. T+0:00

    Player completes their 3rd deposit.

  2. T+0:30

    DWH catches up: purchase_count_lifetime = 3.

  3. T+~2:00

    user_active fires on its heartbeat.

  4. T+~2:00

    Optimove reads purchase_count_lifetime = 3 — settled.

  5. T+~2:00

    Condition ≥ 3 passes. Campaign fires.

Fires within about 2 minutes of the 3rd deposit, every time. The delay is invisible to the player and eliminates the race condition.

How user_active solves the problem

  1. Set the trigger event to user_active

    user_active fires roughly every 2 minutes while the player is active in a session. It is controlled by a server heartbeat with Redis dedup, so it fires at most once per interval per user. By the time it fires, the DWH has had ample time to process any preceding action.

  2. Add your aggregate threshold as a trigger condition

    Use any DWH aggregate as the condition — purchase_count_lifetime >= 3, bet_amount_30d >= 1000, or completed_redemption_count_lifetime >= 5. These values are guaranteed to be settled by the time user_active fires.

  3. Gate correctly — the right cap depends on your condition shape

    Because user_active fires repeatedly, the campaign will re-fire on every heartbeat as long as the condition is true. How you cap it depends on whether the condition can ever become false again.

    Open-ended threshold

    >= X on a lifetime counter

    purchase_count_lifetime >= 3 is true forever once crossed. The only valid gate is once per user lifetime. A 30-day cooldown is wrong: after 30 days the player still has ≥ 3 lifetime deposits and the campaign fires again.

    Bounded range

    >= X AND <= Y

    The player eventually exits the range, so the condition becomes false on its own. A time-based cooldown can work here — but confirm the business intent. If it is "first time ever," use a lifetime gate regardless.

When to use each trigger approach

Follow this decision table every time you design a new event-triggered campaign.

Use the action event

Your condition uses only the event's own fields, not DWH aggregates. These are set at the moment the event fires — no lag.

  • deposit_in_usd > 50
  • is_first_time_deposit = true
  • game_id = "crash"
  • bonus_type = "freeSpins"
  • sc_balance < 10

Use user_active

Your condition relies on any DWH aggregate count or amount. These read from ClickHouse and lag ~30s behind the triggering action. Always pair with a per-user frequency cap.

  • purchase_count_*
  • bet_amount_*
  • win_amount_*
  • completed_redemption_count_*
  • bonus_claimed_*

Use a Repeated event

You want to trigger on the Nth occurrence of the event itself. Optimove counts occurrences internally from when the player enters the trigger — no DWH involved. Reliable, and it does not need user_active.

For a time window ("3 bets within 1 hour"), add the event multiple times in the trigger sequence and set the timeframe at the bottom; a single "Occurred N times" condition has no time window.

Practical campaign examples using user_active

Reward after 3rd deposit ever

Trigger
user_active
Condition
purchase_count_lifetime >= 3
Guard
Once per user lifetime
Why
DWH aggregate — needs a settled value

High-value bettor, $1,000 in 30d

Trigger
user_active
Condition
bet_amount_30d >= 1000
Guard
Once per user per 30 days
Why
Fires on every heartbeat once the threshold is passed

Fifth redemption loyalty bonus

Trigger
user_active
Condition
completed_redemption_count_lifetime >= 5
Guard
Once per user lifetime
Why
Count not reliable on redemption_completed

Bonus spender milestone, $50+

Trigger
user_active
Condition
bonus_claimed_lifetime >= 50
Guard
Once per user lifetime
Why
Bonus totals lag behind claim events

First deposit ever

Action event — no DWH needed

Trigger
deposit
Condition
is_first_time_deposit = true
Guard
None — boolean, fires once
Why
Event's own field — fires reliably

Low balance after a bet

Action event — live field

Trigger
bet_finished
Condition
sc_balance < 10
Guard
Per-user cooldown, e.g. 1/day
Why
sc_balance is live, not DWH

Campaign scenarios 20 scenarios, ready to build

Grouped by trigger mechanism. Every triggered scenario fires from a live event — conditions are checked on the payload, not in the target group.

  • Simple event
  • Repeated event
  • Uncompleted sequence
  • Scheduled
Group A

Triggered · simple events

Fires on each occurrence · 01–10
01

Deposit upsell

SimplePhase 1

Goal — player buys a standard $10 pack, show a $20 special offer while they are still in the cashier flow

Event
deposit, the moment a purchase completes
TG
Existing / new (visitor) · not banned · opted in · country = US
Condition
purchase_amount = 10.00 AND is_first_time_deposit = false
Fires
In-app popup or push: special $20 offer with extra SC bonus
02

Balance drop

SimplePhase 1

Goal — mid-tier buyer drains their SC mid-session, nudge with a top-up matching their usual spend

Event
bet_finished, after every bet resolves
TG
Existing · not banned · opted in · avg_purchase $4.99–$9.99 with ≥5 purchases
Condition
sc_balance < 1
Fires
Top-up offer personalised to their spend tier

avg_purchase is a batch attribute — it belongs in the TG filter, not the trigger condition. Only include players with ≥5 purchases so the average is statistically meaningful.

03

Redemption requested

SimplePhase 1

Goal — player submits a cashout with almost no SC left, encourage a purchase before they disengage

Event
redemption_requested
TG
Existing / new (visitor) · not banned · opted in
Condition
sc_balance < 2 after the request
Fires
"Top up while your cashout processes"
04

Bonus claimed

SimplePhase 1

Goal — player claims a bonus, ride the engagement momentum with a follow-up offer

Event
bonus_claim
TG
Existing / new (visitor) · not banned · opted in
Condition
risk_score < 70 — exclude bonus abusers
Fires
"Make the most of your bonus coins"

risk_score is null for a new user (visitor) — not defined.

05

Bet finished, empty pockets

SimplePhase 1

Goal — SC hits zero after a bet, offer a top-up but exclude likely bonus abusers

Event
bet_finished
TG
Existing / new (visitor) · not banned · opted in
Condition
sc_balance < 1 AND risk_score < 70
Fires
Top-up offer, hidden from high-risk players

risk_score is null for a new user (visitor) — not defined.

06

First purchase ever

SimplePhase 1

Goal — any player makes their very first purchase, fire a first-time buyer welcome

Event
deposit, on every purchase
TG
Existing / new (visitor) · not banned · opted in
Condition
is_first_time_deposit = true
Fires
Welcome campaign with bonus coins or a special pack

For brand-new users registered today, you can also use a Visitor TG plus the sign_up → deposit uncompleted sequence — see scenario 13.

07

Level up celebration

SimplePhase 1

Goal — player levels up, celebrate and tease what is coming at the next level

Event
level_change, on every level-up
TG
Existing / new (visitor) · not banned · opted in
Condition
None — every level-up is worth celebrating
Fires
Congratulations popup plus next-level perks and XP threshold
08

Almost at next level

SimplePhase 1

Goal — player is close to levelling up, motivate with an XP-progress nudge

Event
bet_finished, after every bet
TG
Existing / new (visitor) · not banned · opted in
Condition
xp_to_next_level < 100 — threshold to confirm with product
Fires
"You're only X XP away from [next level]"
09

Big win moment

SimplePhase 1

Goal — player wins big, capitalise on high positive emotion

Event
bet_finished, after every bet
TG
Existing / new (visitor) · not banned · opted in
Condition
is_winning_bet = true AND amount_won_in_usd > 50
Fires
"Congrats on your big win — ready to ride the streak?"
10

Redemption completed

SimplePhase 1

Goal — player just got paid out, re-engage while goodwill is at its peak

Event
redemption_completed, when the cashout is approved and paid
TG
Existing / new (visitor) · not banned · opted in
Condition
sc_balance < 5
Fires
"Your cashout is on its way — here's a bonus pack"
Email or push, never a popup

This fires when the admin approves and the external payment system completes the payout. That is asynchronous — the player is likely not in session.

Group B

Triggered · repeated events

Fires on the Nth occurrence · 11–12
11

4th purchase today

RepeatedPhase 1

Goal — player has already bought 3 times today, reward their 4th with a loyalty perk

Event
deposit, configured as Repeated
TG
Existing / new (visitor) · not banned · opted in
Condition
deposit × 4 in the trigger sequence, 24h timeframe at the bottom
Fires
VIP loyalty reward — bonus coins or exclusive pack

Add the deposit event 4 times in the trigger sequence, then set the 24h timeframe at the bottom. Do not use "Occurred 4 times" — it has no time window.

12

3 bets in a row

RepeatedPhase 1

Goal — player places 3 bets in a session, reward their momentum with a bonus

Event
bet_finished, configured as Repeated
TG
Existing / new (visitor) · not banned · opted in
Condition
bet_finished × 3 within 60 min, plus risk_score < 70
Fires
"You're on a roll — here's a bonus bet"

Add bet_finished 3 times with a 60-minute timeframe at the bottom. For strict consecutive detection with no other events in between, use Optimove Streams. risk_score is null for a new user (visitor).

Group C

Triggered · uncompleted sequence

A fires, B does not follow · 13–15
13

Registered, no purchase

SequencePhase 1

Goal — new player signed up but has not bought anything, catch them while warm

Event
A: sign_up · B expected: deposit · window 30 min
TG
Visitors, new users today · not banned · opted in
Condition
If deposit does not fire within 30 min after sign_up
Fires
"Your first purchase comes with X bonus coins — expires in 1 hour"

Requires the uncompleted sequence event configured in Optimove BO first.

14

Deposited, no bet

SequencePhase 1

Goal — player bought coins but has not placed a bet, bridge purchase and play

Event
A: deposit · B expected: bet_finished · window 15 min
TG
All users · not banned · opted in
Condition
If bet_finished does not fire within 15 min after deposit
Fires
"You've got coins — try [featured game]"

Requires the uncompleted sequence event configured in Optimove BO first.

15

Cashier exit, no purchase

SimpleSequencePhase 4

Goal — player opened the coin store but left without buying. Two approaches, depending on urgency.

Event
cashier_exit, when the user closes the cashier without buying
TG
All users · not banned · opted in

Option A — immediate

No condition. The event already signals abandonment, so the campaign fires immediately. Popup or push, since the player is still in session.

Option B — give them a chance

A: cashier_exit · B expected: deposit · window 10–15 min. If no deposit follows, the campaign fires. Push or email, since the player may have left.

cashier_exit is a frontend event — ad blockers suppress a percentage of fires. Option B also requires the uncompleted sequence configured in Optimove BO first.

Group D

Scheduled · inactive players

Batch data · all players · 16–17

Scheduled campaigns run on the nightly snapshot and can reach inactive players. Unlike triggered campaigns, target groups can include richer filters here — the batch data is fresh enough for players who have not been active recently.

16

Win-back, 7 days inactive

ScheduledPhase 1

Goal — players who were active but have not logged in for 7+ days, bring them back before they churn

Event
None — scheduled campaign at a fixed time
TG
Existing · not banned · opted in · Days Since Last Login ≥ 7 AND ≤ 30 · Total Purchase Amount, Lifetime > $10
Condition
None — TG filters define the audience
Fires
Email at 5am: "We miss you — here's 500 free GC"

The Total Purchase Amount filter focuses on players who have previously spent — non-spending players rarely reactivate from win-back emails.

17

High churn risk

ScheduledPhase 1

Goal — players Optimove's AI predicts are about to churn, pre-emptive retention offer

Event
None — scheduled campaign sent daily
TG
Existing · not banned · opted in · Churn Probability Score > 70 · Days Since Last Activity ≥ 3 · registered more than a few days ago
Condition
None — TG filters define the audience
Fires
Email at 11am: personalised retention offer
Guard

When using Churn Probability Score, filter on time since registration. Players registered only a few days ago do not have enough history for the score to be meaningful.

Group E

Phase 2 · DWH aggregates

Live, v3.74.0 · 18–20

These scenarios use DWH aggregate fields now embedded in every event payload. All windowed metrics are grouped by UTC calendar day, not rolling windows. "Today" means the current UTC day; "7d" means the last 7 calendar days from UTC midnight.

DWH aggregate values lag ~30 seconds

A player makes their 3rd deposit. The deposit event fires instantly, but purchase_count_lifetime inside that same payload may still read 2, so purchase_count_lifetime >= 3 fails and the campaign silently misses. On other occasions the DWH has already updated, which makes the trigger non-deterministic.

Solution: trigger on user_active instead. It fires every ~2 minutes while the player is active, by which point the DWH has settled. Scenarios 18 and 20 do exactly this.

Gating rule: for open-ended thresholds (>= X on a lifetime counter) gate once per user lifetime — the condition never becomes false again. For bounded ranges (>= X AND <= Y) a time-based cooldown is acceptable, since the player will eventually exceed Y.

18

High wager volume today

SimplePhase 2

Goal — player has wagered a large amount today, reward engagement before they stop

Event
user_active, every ~2 min while active
TG
Existing · not banned · opted in
Condition
bet_amount_today >= 50000 SC — threshold to define with product
Fires
Loyalty reward or VIP offer — "you've been on a roll today"

Use user_active, not bet_finished. bet_amount_today is a DWH aggregate and lags ~30s. Gate: once per UTC day per playerbet_amount_today resets at UTC midnight.

19

Standard pack → premium upsell

SimplePhase 1

Goal — player just bought a standard pack, upsell to premium while they are in a buying mindset

Event
user_active, every ~2 min while active
TG
Existing / new (visitor) · not banned · opted in
Condition
sw_package_type = "standard"
Fires
Popup — "upgrade to premium and get 2× the SC for $X more"

Combine with is_first_time_deposit = false to exclude first-time buyers — they have a separate welcome campaign, scenario 06.

20

Purchase milestone

SimplePhase 2

Goal — player crosses a lifetime purchase count milestone, reward loyalty with a surprise bonus

Event
user_active, every ~2 min while in session
TG
Existing · not banned · opted in
Condition
purchase_count_lifetime >= 10
Fires
"Thank you for your 10th purchase — here's a loyalty bonus"

Use user_active, not deposit. purchase_count_lifetime is a DWH aggregate. Gate: once per user lifetime. The threshold >= 10 is true forever once crossed — a time-based cap would re-fire the campaign indefinitely.

Release status

All 20 scenarios live
Phase 1
v3.73–3.76 — new events (redemption_requested, redemption_completed, bonus_claim) and Postgres enrichment on all events. Covers scenarios 1–14, 16–17, 19.
Phase 4
v3.73 — cashier_exit frontend event. Covers scenario 15.
Phase 2
v3.74 — DWH aggregate enrichment on all events plus the user_active heartbeat. Unlocks scenarios 18 and 20. All DWH aggregate values lag ~30s.

Summary Everything together

The two channels serve different players at different moments.

Topic Batch / scheduled Events / triggered
Who it targets All players, including inactive Primarily active players — but backend-triggered events, such as redemption_completed, can reach any player
Data freshness Yesterday's snapshot The moment it happened
Update frequency Once per night Every action, every time
Campaign timing Scheduled, e.g. 5am Instant, seconds after the action
Best use case Reactivation, win-back, loyalty Upsell, celebration, follow-up
Do they affect each other? No. Completely independent channels. Events never update batch data.

Where each piece sits

  1. Data sources

    Player database, transaction history, and game activity — plus the player action that fires an event.

  2. Inside Optimove

    Profiles updated nightly for all players; target groups evaluated at an unknown time on static filters; and the real-time event stream.

  3. Output

    Scheduled campaigns fire at a set time to inactive players. Triggered campaigns fire instantly to active ones.