A practical guide to creating campaigns โ event triggers, target groups, step-by-step examples, and 17 ready-to-build scenarios.
Optimove receives player information in two totally different ways. They do not mix.
Every night, Optimove pulls a fresh copy of every player's profile โ balance, level, game history, transaction history. Think of it as a daily "state of every player."
When a player does something right now โ places a bet, deposits, levels up โ a signal fires instantly to Optimove. These are moments, not profiles.
When a player places a bet and an event fires, their daily batch profile is not updated. The batch profile only changes in the next daily sync. Events and batch data live in completely separate systems. A scheduled campaign sees yesterday's snapshot, not what just happened 5 minutes ago.
Every night, Optimove pulls a fresh copy of the entire player database. Here's how that works.
Player profiles, balances, levels, game activity, and transaction history โ all stored in our database.
Optimove automatically pulls this data once per day into its own system.
Each player gets a profile inside Optimove with all their attributes up-to-date.
Filter players by any attribute: "level 5+, deposited $50+ in past 30 days."
Campaign fires at a set time (e.g. 5 AM) to everyone in the target group.
Batch data is a snapshot. It shows where every player stood at the end of yesterday. It is not live.
Batch data is not a single file. It's four separate views, each with a different purpose. Optimove reads all four nightly and cross-references them by Player ID.
Everything below is already live. Sourced from the four batch views โ raw fields passed through directly, or computed by Optimove from the raw data.
When a player does something, a signal fires instantly. These drive campaigns for players who are active right now.
Player places bet, deposits, levels up...
Signal sent instantly with rich data attached
Brief buffer (milliseconds) to ensure delivery
Event arrives in Optimove within seconds
If conditions match, campaign fires immediately
Each event carries a snapshot of that player's current state โ so real-time campaigns have fresh data without needing to query the database.
Fires whether player won or lost. Carries current balances, level, risk score, and average purchase โ all from the database at the moment of the bet.
Carries updated balances, level, risk score, and the amount just purchased โ the key data for deposit upsell triggers.
Carries new level, rank, and current balances. Great trigger for congratulation campaigns.
Carries redemption amount and current pending redemption total.
Carries updated redemption history windows. Triggers for completed redeemers.
Carries cumulative bonus totals. Enables campaigns for frequent bonus claimers.
Triggers onboarding campaigns. Carries initial profile state.
An event firing does not update a player's batch profile. The batch profile updates once per night via the daily sync โ period. A scheduled campaign scheduled for tomorrow will use tomorrow night's batch data, not the events that fired today.
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. Swivel currently has Simple and Repeated events configured. Uncompleted Sequence events need to be set up separately in Optimove BO before they can be used in campaigns.
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.
The event fires every time the action happens โ always. The trigger is configured with a threshold (count N, time window). When the event fires and the count reaches N within that window, the trigger activates and the campaign fires. Before the Nth occurrence, the event still fires โ the campaign just doesn't.
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 your cart-abandonment equivalent โ the player started a journey but didn't finish it.
The type of campaign depends on which channel it listens to โ batch data or events.
Every player's profile is up-to-date as of yesterday's snapshot
e.g. "Not active in 7+ days AND country = US AND is_blocked = No AND total purchases over $100"
e.g. 5 AM ET โ when servers are quiet and the message feels like a morning nudge
"We miss you โ here's 500 GC to come back!"
โ Best for: win-back, reactivation, loyalty milestones, risk-based segmentation
Places a bet, deposits, levels up, completes a redemption...
Signal arrives at Optimove within seconds, carrying fresh player data
e.g. "Deposit event AND first purchase ever AND balance now over 1000 SC"
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
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 here: balance changes every session so a batch snapshot will always be stale. Average purchase amount means nothing for a player with two purchases. Stick to attributes that are stable and statistically meaningful โ country, account status, player type, lifecycle stage.
e.g. "Last login was more than 7 days ago"
e.g. "Lifetime purchases over $50"
e.g. "Lifecycle stage = Active, level 5 or higher"
These are two completely different places where Optimove checks if a player should receive a campaign. They must carry different types of data.
Use stable, slowly-changing attributes. Common sense applies: balance changes every session โ a batch snapshot is always going to be behind. Averages and ratios are only meaningful if the player has enough data points to make them statistically valid.
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.
Existing/New (visitor) user ยท not banned ยท opted in ยท country = US
BET_FINISHED
{ sc_balance: 0.8,
risk_score: 45 }
risk_score < 70 โ
sc_balance < 1 โ
Top-up offer shown to player
Every campaign โ triggered or scheduled โ follows the same setup flow. Here's what each step means and how to get it right.
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.
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 don't choose it here. You can also configure a trigger as a combination of events within a time window (e.g. sign_up followed by deposit within 30 min, or 3 bet_finished events within 1 hour).
Conditions are checked the instant the event fires, against the live data attached to that event. This is where real-time data lives. All conditions must be true for the campaign to fire.
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.
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.
These four filters keep you compliant, exclude the wrong audience, and ensure campaigns reach reachable players only. Add any extra filters on top.
Some attributes only make sense after a player has enough history. Using them too early produces garbage data and campaigns that fire to the wrong people.
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 โ but that's a sample of one, not a behavioral signal.
Number of Purchases, Lifetime โฅ 5 before using any average purchase
filter
A player with one redemption has either a 0% or 100% ratio โ mathematically correct but statistically useless. You can't segment meaningfully on ratios with 1โ2 data points.
Number of Redeems, Lifetime โฅ 3 before using any redemption rate
filter
Optimove's churn model needs months of behavioral history to be accurate. Players who registered recently produce unreliable scores that may cause you to target (or exclude) the wrong people.
Months Since Registration โฅ 3 before relying on Churn Probability
Score
Win ratios fluctuate wildly with small sample sizes. A player who won 5 of their first 7 bets looks like a 71% winner โ but that's pure variance, not a reliable signal.
Number of Bets Made โฅ 20 for reliable segmentation
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.
Days Since Registration โฅ 90 when using any "Last 3 Months"
frequency filters
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.
Purchase Percentile By LCS over raw
Total Purchase Amount for spend-based segmentation
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, the TG membership may not reflect the player's current state. Instead, include risk_score < 70 or redemption_rate < 75% in the trigger condition โ that reads the live value from the event payload at the exact moment it fires.
Organized by type: triggered (active players, real-time) and scheduled (inactive players). Every triggered scenario fires from a live event โ conditions are checked on the payload, not in the target group.
deposit fires the moment a purchase completes
Existing/New (visitor) user ยท not banned ยท opted in ยท Country = US
purchase_amount = $10
In-app popup or push: special $20 offer with extra SC bonus
bet_finished fires after every bet resolves
Existing user ยท not banned ยท opted in ยท avg_purchase between $4.99โ$9.99 (โฅ5 purchases)
sc_balance < 1
Top-up offer personalised to their typical spend tier
redemption_requested fires when cashout is submitted
Existing/New (visitor) user ยท not banned ยท opted in
sc_balance below 2 SC after the request
Purchase incentive โ "top up while your cashout processes"
bonus_claim fires the moment the bonus is claimed
Existing/New (visitor) user ยท not banned ยท opted in
risk_score < 70 โ exclude bonus abusers from receiving further incentives
Engagement campaign โ "make the most of your bonus coins"
bet_finished fires after every bet
Existing/New (visitor) user ยท not banned ยท opted in
sc_balance < 1 AND risk_score < 70
Top-up offer โ not shown to players with high risk or abuse signals
deposit fires on every purchase
Existing/New (Visitor) users ยท not banned ยท opted in
is_first_time_deposit = true
First purchase welcome campaign with bonus coins or special pack
level_change fires on every level-up
Existing/New (visitor) user ยท not banned ยท opted in
No extra condition needed โ every level-up is worth celebrating
Congratulations popup + preview of next level perks and XP threshold
bet_finished fires after every bet
Existing/New (visitor) user ยท not banned ยท opted in
xp_to_next_level < 100 (threshold to confirm with product)
"You're only X XP away from [next level name]!" โ motivation push or popup
bet_finished fires after every bet
Existing/New (visitor) user ยท not banned ยท opted in
is_winning_bet = true AND amount_won_in_usd > 50
"Congrats on your big win! Ready to ride the streak?" โ offer to keep playing
redemption_completed fires when cashout is approved and paid
Existing/New (visitor) user ยท not banned ยท opted in
sc_balance < 5 โ focus on players who have little left after cashing out
"Your cashout is on its way! Here's a bonus pack to keep the fun going"
deposit โ configured as Repeated, count = 4, window = 24 hours
Existing/New (visitor) user ยท not banned ยท opted in
No extra condition โ the 4th occurrence within 24h is the trigger itself
VIP loyalty reward โ bonus coins or exclusive pack for frequent buyers
bet_finished โ configured as Repeated, count = 3, window = session (or 60 min)
Existing/New (visitor) user ยท not banned ยท opted in
risk_score < 70 โ don't reward high-risk patterns
"You're on a roll! Here's a bonus bet to keep it going"
Event A: sign_up ยท Event B expected: deposit ยท Window: 30 minutes
Visitors (new users today) ยท not banned ยท opted in
If deposit does NOT fire within 30 min after sign_up โ campaign fires
"Welcome! Your first purchase comes with X bonus coins โ offer expires in 1 hour"
Event A: deposit ยท Event B expected: bet_finished ยท Window: 15 minutes
All users ยท not banned ยท opted in
If bet_finished does NOT fire within 15 min after deposit โ campaign fires
"You've got coins! Try [featured game] โ your first bet is waiting"
cashier_exit fires when user closes the cashier without completing a purchase
All users ยท not banned ยท opted in
Option A โ Simple (immediate)
None โ event already signals abandonment. Campaign fires immediately on cashier_exit.
Popup or push โ player is still in session
Option B โ Uncompleted Sequence (give them a chance first)
Event A: cashier_exit ยท Event B expected:
deposit ยท Window: 10โ15 min
If no deposit follows โ campaign fires
Push or email โ player may have already left the session
Scheduled campaigns run on batch data (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 haven't been active recently, and stale-data risk is near zero for that group.
No trigger event โ scheduled campaign sent at a fixed time
Existing user ยท not banned ยท opted in ยท Days Since Last Login โฅ 7 AND โค 30 ยท Total Purchase Amount, Lifetime > $10
No trigger condition โ TG filters define the audience
Email at 5 AM: "We miss you! Here's 500 free GC to come back"
No trigger event โ scheduled campaign sent daily
Existing user ยท not banned ยท opted in ยท Churn Probability Score > 70 ยท Days Since Last Activity โฅ 3 ยท registered more than a few days ago
No trigger condition โ TG filters define the audience
Email at 11 AM: personalised retention offer based on their favorite game or spend tier
These scenarios depend on time-windowed aggregates (e.g. total wagered in last 24h) that are not in Postgres today. Phase 2 will expose them as trigger conditions via DWH enrichment.
bet_finished fires after each bet resolves
Existing user ยท not banned ยท opted in
total_wagered_last_24h โฅ X SC (threshold to be defined)
Loyalty reward or bonus offer โ "you've been on a roll today"
Phase 1 delivers the new events (redemption_requested, redemption_completed, bonus_claim) + Postgres enrichment on all events (sc_balance, risk_score, xp_to_next_level, is_first_time_deposit, etc.). That covers 16 of the 17 scenarios. Scenario 15 (cashier abandonment) uses the cashier_exit frontend event โ Phase 4. Phases 2 and 3 will add richer data (DWH aggregates) but are not blockers for anything here.
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 (e.g. 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. 5 AM) | Instant (seconds after 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. | |
| Channel type | Batch | Events |