Run a time-limited sale campaign with OneSignal Journeys. Choose a basic time-based flow using existing tags, or an advanced event-driven flow with Custom Events for buyer suppression and personalization.
Use this file to discover all available pages before exploring further.
This tutorial walks through a complete push campaign for a flash sale — a short, high-pressure promotion (often 24 hours or less) where conversions happen inside a narrow window. Black Friday (40% off sitewide, midnight to midnight) is the running example, but the pattern applies to any time-limited promotion.The campaign progresses through three phases: Anticipation (teasing and wishlist building), Launch (VIP-first rollout with personalization), and Urgency (re-engaging non-openers and non-purchasers).You can build this campaign two ways:
Case 1: Basic time-based flow — uses tags you likely already have (vip_customer, wishlist_count, last_purchase_date). No new instrumentation. Good for your first flash sale or low-effort campaigns.
Case 2: Advanced event-driven flow — uses Custom Events (sale_page_viewed, purchase_completed) to gate messages on real user actions. Cleanly exits buyers from the Journey and unlocks event-property personalization. Recommended once you have basic event tracking in your app.
Both paths share the same Journey backbone, segments, and timing — see Campaign overview for the unified plan. Pick the path that matches your tech stack and skip ahead.
Two teaser pushes (D-2, D-1) drive wishlist adds before the sale opens
Reward loyalty with VIP early access
VIPs get a 1-hour head start before the general announcement
Personalize by user intent
Wishlist users see a “your saved items are on sale” push with their saved-item count
Recover non-engagers mid-sale
Mid-day nudge sent only to users who have not visited the sale page
Convert clickers in the final hours
Two urgency pushes targeted at users who clicked but have not purchased
Protect trust by suppressing buyers
A last_purchase_date filter (Case 1) or purchase_completed event exit (Case 2) keeps “last chance” pings off purchasers
The campaign sends 6 pushes total, capped at ~3 per user per day. The most important guardrail: always suppress purchasers from urgency messages — “last chance” pings to buyers are the #1 unsubscribe driver. Respect quiet hours (22:00–07:00) and pause the Journey if the sale ends early.
This Journey runs entirely on time-based Wait nodes and existing tags. No in-sale instrumentation required. Set it live 2 days before the sale opens; it walks every subscriber through the full pre-sale → launch → urgency arc.
Each of these three pushes uses a Yes/No Branch node to exclude buyers before sending. Build each as a Wait → Branch → Push sequence:Node 5: Mid-day reminder
Add a Wait node set to 10 hours after Node 4.
Add a Yes/No Branch node with the condition: Tag last_purchase_date is earlier than the sale start date (or tag does not exist).
Yes branch (non-buyers) → Add a Push Notification node:
Field
Value
Title
Still going — 40% off ends tonight
Body
The Black Friday sale is still live. Don't leave your items behind.
Launch URL
Your sale page
No branch (buyers) → Route directly to Node 6 (skip the push).
Node 6: 4-hours-left urgency
Connect both branches from Node 5 into a Wait node set to 10 hours.
Add a Yes/No Branch node with the same condition: Tag last_purchase_date is earlier than the sale start date.
Yes branch → Push:
Field
Value
Title
4 hours left ⏰
Body
The sale ends at midnight. Grab your items before they're gone.
Launch URL
Your cart page
No branch → Route to Node 7.
Node 7: 30-minutes-left urgency
Connect both branches from Node 6 into a Wait node set to 3.5 hours.
Add a Yes/No Branch node with the same buyer-exclusion condition.
Yes branch → Push:
Field
Value
Title
30 minutes left — last chance
Body
The Black Friday sale closes at midnight. This is your last chance.
Launch URL
Your sale page or cart
No branch → End of Journey.
Case 1 cannot distinguish engaged users from non-engaged users without event tracking — both groups receive all three pushes (minus those who bought).
The last_purchase_date filter only suppresses buyers if your backend updates the tag in near-real-time. If your stack updates the tag nightly, buyers in the early hours of the sale will still receive urgency pushes later that day. Verify the sync cadence before launch — if you cannot guarantee it, jump to Case 2, which uses an event-based exit instead.
Apply the last_purchase_date filter to every urgency-arc message (Nodes 5, 6, and 7). Without it, users who bought at hour 2 still get “last chance” pings — the #1 unsubscribe driver.
Verify tag freshness before launch by simulating a purchase and confirming the tag updates within minutes.
Accept the engagement trade-off. Case 1 cannot distinguish “clicked-but-not-purchased” from “ignored everything” — both groups receive the urgency arc. If post-sale unsubscribe trends climb, upgrade to Case 2.
Review frequency caps before launch. A VIP wishlist user who never buys can receive up to 6 pushes across the sequence.
Pause the Journey if the sale ends early. From the dashboard, pause stops remaining Wait nodes and prevents urgency pushes from firing.
This Journey replaces Case 1’s tag filters with Wait Until nodes that listen for Custom Events. Buyers exit cleanly the moment they purchase, non-engagers are filtered without tag staleness, and event properties drive personalization in the urgency arc. Recommended once you have basic event tracking wired in your app.The pre-sale and launch nodes (1–4) are identical to Case 1. Case 2 only changes how the mid-day reminder and urgency arc are gated.
Both urgency nodes use Wait Until with purchase_completed. Because the journey-level exit handles buyers, the event branch silently exits while the timeout branch sends the urgency push.Node 6: 4-hours-left urgencyAdd a Wait Until node:
Setting
Value
Wait for event
purchase_completed
Timeout
10 hours
On timeout, send a push that personalizes with the user’s most recent sale_page_viewed.cart_value:
Field
Value
Title
4 hours left ⏰
Body
Your ${{event.cart_value}} cart is waiting. The sale ends at midnight — grab your items.
Launch URL
Your cart page
{{event.cart_value}} references the cart_value property from the user’s most recent sale_page_viewed event. Always set a fallback in the message editor so the push still renders for users without a matching event. See OneSignal’s Liquid event property reference for exact syntax.
Node 7: 30-minutes-left urgencyAdd another Wait Until node:
Setting
Value
Wait for event
purchase_completed
Timeout
3.5 hours
On timeout, send the final push:
Field
Value
Title
30 minutes left — last chance
Body
The Black Friday sale closes at midnight. This is your last chance.
Launch URL
Your sale page or cart
Buyers who fire purchase_completed at any point exit the Journey via the journey-level exit rule — they never receive the urgency pushes.
Verify events fire reliably before going live. Test sale_page_viewed and purchase_completed in a staging app and confirm they arrive within seconds, not minutes.
Use the journey-level exit on purchase_completed rather than per-node filters — one rule covers every node and prevents accidental sends.
Set a fallback for event-property personalization so pushes still render correctly for users without a matching event.
Pause the Journey if the sale ends early.
When ready to launch, click Set Live on D-2 — the D-2 teaser fires immediately for every user who enters the Journey.
Email: After any Push node, add an Email node. Insert a Wait node (1–2 hours) between push and email to avoid overwhelming users.In-app: After Node 3 (sale launch), add an In-App Message node. Users see the banner the next time they open your app.SMS: At Node 7 (30-minutes-left), add an SMS node after the push. SMS is high-interrupt — use it only for the final urgency message.
What if my last_purchase_date tag isn’t synced in real-time?
If your backend updates tags nightly instead of in real-time, buyers from the early hours of the sale will still receive urgency pushes later that day. Either speed up your tag sync or use Case 2, which exits buyers instantly via the purchase_completed event.
A maximum of 6 pushes across the full sequence. VIP wishlist users who never purchase receive all 6; non-VIP users without a wishlist receive 5. Buyers exit early and receive fewer.
OneSignal’s Intelligent Delivery can optimize send times per user, but for a time-bound sale with a hard deadline, send at clock time instead. If your audience spans multiple time zones, consider running separate Journeys per region with adjusted timing.
Yes. Add Email or SMS nodes alongside or instead of Push nodes. The same timing, branching, and suppression logic applies. For multi-channel campaigns, stagger channels to avoid overwhelming users — for example, push first, then email 2 hours later to non-openers.