Documentation Index
Fetch the complete documentation index at: https://documentation.onesignal.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Daily streaks are one of the most effective retention mechanics in mobile and web apps. By reminding users to return each day, you can build habits, increase engagement, and reduce churn. This tutorial walks through three Journey configurations:- 1-day recurring streak reminder (last session time): A simple daily nudge for users who haven’t opened the app yet today.
- 7-day streak Journey (last session time): A guided 7-day challenge that checks daily activity and rewards users who complete the full streak.
- 1-day recurring streak with tags and custom events: A tag-based approach that tracks streak count and sends personalized reminders based on progress.
Prerequisites
Before starting, make sure you have:- A OneSignal app with push notifications configured
- External IDs assigned to your users (recommended for cross-channel accuracy)
- Familiarity with Journeys, Segments, and Journey actions
1-day recurring streak reminder
Goal: Send multiple daily push notifications throughout the day to users who haven’t opened the app today, reminding them to keep their streak alive. When the user opens the app, they exit the Journey. The next day, the cycle repeats. This approach uses user session activity only to trigger and manage the journey - no tags or custom events required. Users move through the journey using time window nodes, ensuring that your push notifications are sent at specific times of day.Segments used
| Segment | Filters | Notes |
|---|---|---|
| Total Users (optional) | No filters | To include all users in the journey |
| Active in last 8 hours (required) | Last session less than 8 hours ago | In order to check if the user was active before the first time window. |
Active in last X hours segment to a suitable time (e.g. for a 10am time window, the segment should check for users that were active in the last 10 hours)Journey settings
| Setting | Configuration |
|---|---|
| Entry rules | Audience Segment |
| Audience | Include: Total Users segment |
| Exit rules | Exit when user becomes active in your app/website. & Tag users when they exit early: streak_ongoing: true |
| Re-entry rules | Yes, after a certain amount of time: 10 minutes |
| Schedule | Start immediately, never stops |
Journey steps
Add a Time Window node

Check for activity before first Time Window - Add a Yes/No branch

Add a Yes/No branch
streak_ongoing: true tag that is set when a user exits this journey early:
First push notifications

Repeat the above steps.
Add a final time window

Update the "streak_ongoing" tag
streak_ongoing tag to false with a “Tag” node, both for tracking purposes and also so that when they rejoin the journey, they are sent the appropriate push notifications.Similarly, on the “Yes” branch of our first Yes/No node (from step 2), we need to update the streak_ongoing tag to true, as the user completed their streak before our first Time Window check:
7-day streak Journey
Goal: Guide users through a 7-day streak challenge. This can be a one-off, one-shot streak (ideal for time-limited events), or a repeatable streak that users can reattempt (for weekly streaks). This approach uses user activity only to trigger and manage the journey - no tags or custom events required.Segments used
| Segment | Filters | Notes |
|---|---|---|
| Total Users (optional) | No filters | To include all users in the journey. You can use other segments in place of this to target a more limited audience |
| 7 day streak completed (optional) | “7_day_streak” tag is “completed” | Can be used to exclude users that have already completed the streak or for tracking purposes |
| Active in last 8 hours (required) | Last session less than 8 hours ago | To check for user activity between time windows. |
| Active in last 6 hours (required) | Last session less than 6 hours ago | To check for user activity between time windows. |
| Active in last 4 hours (required) | Last session less than 4 hours ago | To check for user activity between time windows. |
| 7 day streak failed (required) | “7_day_streak” tag is “failed” | Used to force the user to exit the journey early if they are inactive for more than a day. |
Journey settings
| Setting | Configuration |
|---|---|
| Entry rules | Audience Segment |
| Audience | Include: Total Users segment. (Optional: Exclude 7 day streak completed to make it so that users can only complete the streak once, and 7 day streak failed to make it so that a user can only attempt the streak once) |
| Exit rules | Exit when user enters a segment: 7 day streak failed (Optional : Tag users when they exit early: 7_day_streak: 0 - removes users from 7 day streak failed segment and allows them to re-enter the journey after failing) |
| Re-entry rules | Yes, after a certain amount of time: 10 minutes (if repeating) OR No, they can receive this only once (for single attempts) |
| Schedule | Start immediately, never stops |
Journey steps
Add a Time Window node

Check for activity before first Time Window - Add a Yes/No branch

Add another Time Window node

Check for activity before Time Window - Add a Yes/No branch

Repeat steps 4, 5 & 6 to send more notifications.

Add another Time Window node for 12:00am

Check for activity before Time Window - Add a Yes/No branch

Add a tag to eject the user from the journey.
7_day_streak with the value failed here. This will put the user into the “7 day streak failed” segment and automatically end the journey for them.
Optionally, you can also add a streak_failed_day tag here with the day number as the value in order to track what days your users failed their streaks.
Add a wait node on the original 'Yes' branch of this day.

Add a tag to signify the streak day achieved.

Repeat for days 2-7.
7_day_streak tag that was updated in step 12 to remind users how big their streak is so far.Add a final data tag
7_day_streak to completed.If you have been setting the streak_failed_day tag as well, update this to a blank value to delete the tag.
1-day recurring streak with tags and custom events
Goal: Send escalating push reminders throughout the day, using a custom event (streak_continued) to detect when the user completes their daily action. As soon as the event fires, the user skips all remaining reminders for that day. If the user doesn’t act, they receive up to four reminders spaced 4 hours apart. The cycle resets the next day.
This approach uses a custom event (streak_continued) to signal that a user has completed their daily streak action, and Wait Until nodes to listen for that event between reminders. Unlike the previous examples, this journey doesn’t rely on segment-based activity checks: instead, it reacts directly to an event fired by your app.
streak_count tag on the user profile to personalize messages with liquid syntax, so users who are continuing a streak see different copy than users who are starting fresh.Send the custom event and update streak tags from your app
Each time a user completes their daily streak action (opening the app, finishing a lesson, logging a workout, etc.), send astreak_continued custom event to OneSignal and update the streak_count tag on the user profile:
- Frontend SDK
- REST API
streak_count tag to 0 (or remove it). This ensures the journey’s push templates always reflect the correct streak state.
Create personalized message templates
Use liquid syntax in your push notification templates to show different copy depending on whether the user has an active streak or is starting fresh. This keeps the journey structure simple: a single push node handles both cases. Example push template:| Field | Value |
|---|---|
| Title | {% if streak_count and streak_count != "0" %}Keep your streak alive!{% else %}Start a streak today!{% endif %} |
| Message | {% if streak_count and streak_count != "0" %}You're on a {{streak_count}}-day streak. Don't let it end!{% else %}Open the app to start building your streak.{% endif %} |
| Launch URL | https://yourapp.com/streak |
Segments used
| Segment | Filters | Notes |
|---|---|---|
| Total Users (or your preferred audience) | No filters | To include all users in the journey. Replace with a more targeted segment if needed. |
Journey settings
| Setting | Configuration |
|---|---|
| Entry rules | Audience Segment |
| Audience | Include: Total Users (or your preferred audience segment) |
| Exit rules | They moved through the entire journey |
| Re-entry rules | Yes, after a certain amount of time: 10 minutes |
| Schedule | Start immediately, never stops |


Journey steps
The journey uses Wait Until nodes to listen for thestreak_continued custom event between each reminder. If the event fires at any point, the user follows the A branch and skips all remaining reminders for the day. If the event doesn’t fire before the expiration, the user receives a push notification and moves to the next Wait Until node.
Add a Time Window node

Add a Wait Until node (1-hour expiration)
streak_continued occurs. Set the expiration to 1 hour.- A branch (event fires): The user already completed their daily action early in the morning, so they skip all reminders and proceed directly to the exit.
- Expire branch (1 hour, no event): The user hasn’t acted yet. Continue to the first push reminder.

Send the 8am Streak Reminder push

Add a second Wait Until node (4-hour expiration)
streak_continued. This time, set the expiration to 4 hours.- A branch: User completed their action after the first reminder. Skip remaining reminders and proceed to the exit.
- Expire branch: No action after 4 hours. Continue to the 12pm reminder.
Send the 12pm Streak Reminder push

Continue the pattern for afternoon and evening reminders
- Wait Until (4 hours) → 4pm Streak Reminder push
- Wait Until (4 hours) → 8pm Streak Reminder push
streak_continued event can fire to skip all remaining reminders and jump straight to the exit.Converge all branches to the Exit node
streak_continued event fired) and the final push notification branch should converge at the end of the journey, leading to the Exit node.
How the flow works
Here’s a walkthrough of a typical day for a user in this journey:| Time | User action | Journey behavior |
|---|---|---|
| 7:00 AM | - | User passes through Time Window, enters first Wait Until (1-hour expiration) |
| 7:00–8:00 AM | No streak_continued event | Wait Until expires → sends 8am Streak Reminder push |
| 8:00 AM–12:00 PM | No event | Wait Until expires (4 hours) → sends 12pm Streak Reminder push |
| 2:30 PM | User opens app, streak_continued fires | Wait Until condition met → user follows A branch, skips 4pm and 8pm reminders |
| - | - | User exits journey → re-enters after 10 min → waits at Time Window for next 7:00 AM |
streak_continued event fires, all remaining reminders are skipped for the day. The cycle resets the next morning at your configured Time Window.Comparison of approaches
| Last session (1-day) | Last session (7-day) | Tags + custom events | |
|---|---|---|---|
| Complexity | Low | Medium | High |
| Setup required | Segment only | Segment + branching | SDK/API integration + segments |
| Personalization | Generic messages | Day-specific messages | Streak count in messages |
| Tracks streak count | No | Implicitly (by day in Journey) | Yes (via tags) |
| Best for | Simple daily reminders | Time-limited challenges | Apps with streak UI/rewards |
| Code required | None | None | Yes (events + tag updates) |
Tips and best practices
- Don’t over-message. Ensure that you send an appropriate amount of reminders, and use Time Window nodes to control when messages are sent and avoid interrupting users during off-hours.
- Use different channels where appropriate. If your users are subscribed to multiple channels, try experimenting with SMS and Email messages as part of your flow to see if streak retention increases. Note that in-app messages are not appropriate for streak reminders, as the user has to be in the app to see them, and in-app messages in journeys can only be shown to a user once, even if they re-enter the journey.
- Combine with outcomes. Track streak completions as Custom Outcomes to measure the impact of your streak Journeys on retention and engagement.
- Test your timing. Experiment with different delivery windows and message frequencies. Use Split Branch nodes to A/B test.
- Reset streaks gracefully. When a streak breaks, consider sending an encouraging “start a new streak” message rather than a punitive one.
FAQ
Can I track the actual streak count without tags or custom events?
Not directly. OneSignal’s Last Session filter tells you when a user was last active but does not count consecutive days. For streak counting, use tags or custom events as shown in the third example.What happens if a user has multiple subscriptions?
Segment checks evaluate all of a user’s subscriptions. If a user has both a mobile and web subscription, activity on either device updates their last session time. Assign External IDs to unify subscriptions under a single user profile.Can I reward users for completing a streak?
Yes. At the end of a streak Journey, use a Tag User action to mark the user (for example,streak_7day_complete: true). Your app can read this tag to unlock rewards, badges, or other incentives. You can also use a Journey webhook to notify your backend when a user completes the streak.

