Skip to main content
This tutorial walks through a complete flash sale Journey using Black Friday as the running example (40% off sitewide, midnight to midnight). The pattern applies to any time-limited promotion.
  • Case 1 – Basic: Pure time-based, no tags. Everyone receives the same messages at scheduled times. Good for your first flash sale or teams without tag infrastructure.
  • Case 2 – Advanced: Uses tags (vip_customer, wishlist_count, last_purchase_date) for VIP early access, wishlist personalization, and buyer suppression. Start with Case 1 and layer in Case 2 targeting as your data matures.

At a glance

Setup is the same for both cases. The only difference is how targeting and branching are applied.
  1. Define the entry segment.
  2. Build the push, email, and in-app message templates.
  3. Configure Journey entry, exit, and re-entry rules.
  4. Wire up the Journey steps:

Campaign goals

GoalHow this campaign achieves it
Build pre-sale anticipationEmail + in-app message before the sale
Remind users the day beforePush the day before to keep the sale top of mind
Announce the sale launchEmail + in-app message when the sale goes live
Re-engage mid-salePush a few hours after launch for non-visitors
Final email reminderEmail halfway through to recover non-purchasers
Last-chance urgencyPush 2 hours before the sale ends
Personalize and protect trust (Case 2)VIP early access, wishlist push, and buyer suppression via tags

Prerequisites

  • A OneSignal account with push notifications set up for your app or site
  • Push permission enabled for your users
  • Familiarity with Journeys concepts (entry/exit rules, message and action steps, etc.)
  • Email channel set up if you want to send emails (see Email setup)
  • In-app messaging enabled if you want to show banners during the sale window (see In-app messages setup)
Case 2 also requires tags maintained by your backend. See Case 2: Advanced tag-based Journey.

Segments

Entry segment (both cases):
  • Name: “Total Subscriptions”
  • Built-in, no setup needed. All push-subscribed users enter the Journey.
VIP segment (Case 2 only):
  • Name: “VIP Customers”
  • Filter: User Tag vip_customer · operator is · value true
Wishlist segment (Case 2 only):
  • Name: “Wishlist Users”
  • Filter: User Tag wishlist_count · operator greater than · value 0

Templates

These templates are starting points: clone, edit, and re-use them in your own Journey. They use Liquid syntax for personalization.
WhenNameTitleMessage
Day before saleSale tomorrow🛍️ Tomorrow only. 40% off sitewide.Your Black Friday sale starts at midnight tonight. Don’t miss it.
Mid-saleMid-sale nudge⏰ Still going, 40% off ends tonightThe Black Friday sale is still live. Don’t leave your items behind.
2 hours before closeLast chance🔥 2 hours left, last chanceThe Black Friday sale closes at midnight. This is your last chance.
Sale launch, VIPs (Case 2)VIP early access🎉 You’re in early, {{first_name}}VIP early access is live. 40% off everything, shop before everyone else.
Sale launch + 1 hour (Case 2)Sale launch🛍️ Black Friday is LIVE40% off sitewide, ends tonight at midnight. Shop now.
Sale launch, wishlist users (Case 2)Wishlist on sale💜 Your saved items are 40% offYou have {{user.tags.wishlist_count}} items on your wishlist. They’re all on sale right now.

Templates

Create and manage reusable message templates.

Message personalization

Overview of all personalization options available in OneSignal.

Journey configuration

Both cases share the same Journey settings. Define them once and use them for either case.

Journey settings

SettingValue
EntryAudience Segment: “Total Subscriptions”
ExitUser reaches the end of the flow
Re-entryNo, users receive this Journey only once per sale

Case 1: Basic time-based Journey

This Journey runs entirely on time-based Wait nodes. No tags, no targeting. Everyone receives the same messages at scheduled times. Set it live 2 days before the sale opens.

Journey timing

The campaign progresses through anticipation (2 days before through the day before), launch (sale day), and urgency (afternoon through close):
StepWhenChannelPurpose
12 days before sale (on entry)Email + IAMBuild excitement
2Day before salePushSale starts tomorrow
3Sale launchEmail + IAMSale is live
4A few hours after launchPushMid-sale nudge
5Halfway through saleEmailFinal email reminder
62 hours before closePushLast chance

Basic Journey steps

1

Email + In-App Message: Pre-sale excitement (2 days before)

Goal: Build anticipation a few days before the sale.Add an Email node as the first step, then an In-App Message node immediately after.The email lands when the user enters the Journey. The IAM is queued and displays the next time they open your app.
2

Wait: 1 day

Goal: Advance to the day before the sale.Add a Wait node set to 1 day.
3

Push Notification: Sale starts tomorrow (day before)

Goal: Reminder the day before.Add a Push Notification node.
FieldValue
TitleTomorrow only. 40% off sitewide.
BodyYour Black Friday sale starts at midnight tonight. Don't miss it.
Launch URLYour sale landing page
4

Wait: 1 day

Goal: Advance to sale day.Add a Wait node set to 1 day.
5

Email + In-App Message: Sale is live (sale day)

Goal: Announce the sale launch.Add an Email node, then an In-App Message node.The email announces the sale is live. The IAM displays a sale banner when users open the app.
6

Wait: a few hours

Goal: Give users time to see the launch messages before the mid-sale nudge.Add a Wait node set to 3–4 hours (adjust based on your sale duration).
7

Push Notification: Mid-sale nudge

Goal: Re-engage users who haven’t visited yet.Add a Push Notification node.
FieldValue
TitleStill going, 40% off ends tonight
BodyThe Black Friday sale is still live. Don't leave your items behind.
Launch URLYour sale page
8

Wait: until halfway through sale

Goal: Advance to the halfway point.Add a Wait node. For a 24-hour sale that started at midnight, set this to 6–8 hours to land around midday/afternoon.
9

Email: Final reminder

Goal: Last email push to recover non-purchasers.Add an Email node with urgency messaging and countdown.
10

Wait: until 2 hours before end

Goal: Advance to the final urgency window.Add a Wait node to land 2 hours before the sale ends. For a midnight-to-midnight sale, this is around 10 PM.
11

Push Notification: Last chance

Goal: Final urgency push.Add a Push Notification node.
FieldValue
Title2 hours left, last chance
BodyThe Black Friday sale closes at midnight. This is your last chance.
Launch URLYour sale page or cart

Best practices for Case 1

  • Set the Journey live 2 days before the sale. The pre-sale email fires immediately for users who enter.
  • Respect quiet hours. Avoid sending pushes between 10 PM and 7 AM in the user’s timezone. Adjust Wait nodes if needed.
  • Pause the Journey if the sale ends early. From the dashboard, pause stops remaining Wait nodes and prevents any remaining messages from firing.
  • Deep-link every message to the right page. Tapping a push should land users on the sale page, not the app home.

Case 2: Advanced tag-based Journey

Case 2 builds on Case 1 by adding targeting with tags. The timing is the same, but you add:
  • VIP early access: VIPs get a 1-hour head start at sale launch
  • Wishlist personalization: Users with wishlist items get a personalized push
  • Buyer suppression: Filter out buyers from urgency messages

Required tags

TagTypeDescription
vip_customerBooleantrue if the user is a VIP customer
wishlist_countNumberCount of items in the user’s wishlist
last_purchase_dateUnix timestamp (seconds)Time of the user’s most recent purchase, stored as a Unix timestamp in seconds (10 digits)
These tags must be maintained by your backend and synced to OneSignal. See Tags for setup.
The time elapsed greater than operator compares the current time to a Unix timestamp stored on the tag. Store last_purchase_date as a Unix timestamp in seconds (10 digits), not milliseconds or a formatted date. See Tags: Time Operators for details.

Advanced Journey steps

Case 2 follows the same overall timing as Case 1, but adds a VIP branch at launch, a wishlist branch right after, and a buyer-suppression filter on every urgency message.
1

Email + In-App Message: Pre-sale excitement (2 days before)

Goal: Build anticipation a few days before the sale.Add an Email node as the first step, then an In-App Message node immediately after.The email lands when the user enters the Journey. The IAM is queued and displays the next time they open your app.
2

Wait: 1 day

Goal: Advance to the day before the sale.Add a Wait node set to 1 day.
3

Push Notification: Sale starts tomorrow (day before)

Goal: Reminder the day before.Add a Push Notification node.
FieldValue
TitleTomorrow only. 40% off sitewide.
BodyYour Black Friday sale starts at midnight tonight. Don't miss it.
Launch URLYour sale landing page
4

Wait: 1 day

Goal: Advance to sale day.Add a Wait node set to 1 day.
5

Branch: VIP / General split (sale launch)

Goal: Give VIPs a 1-hour head start.Add a Yes/No Branch node:
  • Condition: User Tag vip_customer · operator is · value true
Yes branch (VIP): Add a Push Notification node immediately:
FieldValue
TitleYou're in early, {{first_name}} 🎉
BodyVIP early access is live. 40% off everything, shop before everyone else.
Launch URLYour sale page
No branch (general): Add a Wait node set to 1 hour, then a Push Notification node:
FieldValue
TitleBlack Friday is LIVE 🛍️
Body40% off sitewide, ends tonight at midnight. Shop now.
Launch URLYour sale page
6

Email + In-App Message: Sale is live

Goal: Announce the sale to everyone.Connect both branches into the same next node. Add an Email node, then an In-App Message node. The email announces the sale is live and the IAM displays a sale banner when users open the app.
7

Branch: Wishlist personalization

Goal: Send a personalized push to wishlist users.Add a Yes/No Branch node:
  • Condition: User Tag wishlist_count · operator greater than · value 0
Yes branch (wishlist users): Add a Push Notification node:
FieldValue
TitleYour saved items are 40% off
BodyYou have {{user.tags.wishlist_count}} items on your wishlist. They're all on sale right now.
Launch URLYour wishlist page
No branch (no wishlist): Continue with no message.Connect both branches into the next step.
8

Wait: a few hours

Goal: Give users time before the mid-sale nudge.Add a Wait node set to 3–4 hours.
9

Branch + Push: Mid-sale nudge (buyer suppression)

Goal: Nudge non-buyers only.Add a Yes/No Branch node. Match any of these filters:
  • User Tag last_purchase_date · operator time elapsed greater than · value 4 hours
  • User Tag last_purchase_date · operator does not exist
Adjust the 4 hours value based on how long after sale launch this step fires in your Journey.Yes branch (non-buyers): Add a Push Notification node:
FieldValue
TitleStill going, 40% off ends tonight
BodyThe Black Friday sale is still live. Don't leave your items behind.
Launch URLYour sale page
No branch (buyers): Skip the push, route directly to the next step.
10

Wait: until halfway through sale

Add a Wait node to reach the halfway point.
11

Branch + Email: Final reminder (buyer suppression)

Goal: Email non-buyers only.Add a Yes/No Branch node. Match any of these filters:
  • User Tag last_purchase_date · operator time elapsed greater than · value 12 hours (halfway through a 24-hour sale)
  • User Tag last_purchase_date · operator does not exist
Yes branch (non-buyers): Add an Email node with urgency messaging.No branch (buyers): Skip the email.
12

Wait: until 2 hours before end

Add a Wait node to reach the final urgency window.
13

Branch + Push: Last chance (buyer suppression)

Goal: Final push to non-buyers only.Add a Yes/No Branch node. Match any of these filters:
  • User Tag last_purchase_date · operator time elapsed greater than · value 22 hours (two hours before a midnight close)
  • User Tag last_purchase_date · operator does not exist
Yes branch (non-buyers): Add a Push Notification node:
FieldValue
Title2 hours left, last chance
BodyThe Black Friday sale closes at midnight. This is your last chance.
Launch URLYour sale page or cart
No branch (buyers): End of Journey.
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 messages later that day. Verify the sync cadence before launch.

Best practices for Case 2

  • Apply buyer suppression to every urgency message. Without it, users who bought early still receive “last chance” pushes, which is the most common cause of unsubscribes after a flash sale.
  • Verify tag freshness before launch by simulating a purchase and confirming the last_purchase_date tag updates within minutes.
  • All Case 1 best practices still apply. Quiet hours, deep linking, and pausing the Journey if the sale ends early.
  • Be aware of message volume. A VIP wishlist user who never buys can receive up to 4 pushes and 3 emails across the full sequence. Make sure that volume feels appropriate for your audience before launch.

Compare Case 1 and Case 2

Both cases share the same entry segment, Journey settings, and templates. Case 2 adds targeting.
Case 1: BasicCase 2: Advanced
Data requiredNoneTags: vip_customer, wishlist_count, last_purchase_date
Setup effortLow, no tag infrastructure neededMedium, requires backend tag sync
VIP early accessNo, everyone gets sale launch at same timeYes, VIPs get 1-hour head start
Wishlist personalizationNoYes, “your saved items are on sale” push
Buyer suppressionNo, everyone gets urgency messagesYes, filter out buyers via last_purchase_date
Best forFirst flash sale, no tag infrastructureTeams with existing tags, better UX

Where to go from here

Start with Case 1 if you’re running your first flash sale or don’t have tag infrastructure in place. As you add tags to your data layer, upgrade to Case 2 by adding the VIP branch, wishlist branch, and buyer-suppression filters. The VIP early access alone is worth the effort: it rewards your best customers and creates social proof when they share their finds. After this Journey is live, consider adding SMS for the final urgency push (see SMS messaging) or extending the pattern to other time-limited promotions like summer sales, anniversary events, or new product launches.

Journeys overview

Learn how to build, branch, and manage automated message flows.

Message personalization

Use Liquid tags to personalize message copy with user data.

Segments

Build reusable audiences based on tags, behavior, and more.

In-app messages

Create banners and modals to reach users inside your app.

Email setup

Configure email messaging for your campaigns.

Tags

Add custom data to user profiles for targeting and personalization.