> ## 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.

# Journey examples

> Step-by-step Journey configurations for onboarding, re-engagement, abandoned cart, A/B testing, recurring sends, and event-driven workflows.

Each example below includes the recommended Journey settings and step-by-step configuration. Start with the simpler patterns (onboarding, re-engagement) and work up to more advanced workflows (recurring sends, event-driven progression, action button branching).

<Frame caption="Video: Journey examples walkthrough">
  <iframe width="560" height="315" src="https://www.youtube.com/embed/TnsBCXe_Opw?si=feFpzblCm_Hcpbd4" title="Journey examples walkthrough" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen />
</Frame>

***

## Onboarding

Use this pattern to send a welcome or onboarding sequence to new subscribers. It is also commonly referred to as a welcome campaign, welcome series, or new user campaign. The goal is to guide users toward completing a key action (finishing their profile, making their first purchase, or discovering a core feature) rather than messaging them the moment they sign up.

| Journey setting    | Description                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Entry rules**    | **Event-based (recommended):** Use a [Custom Event](./custom-events) trigger (for example, `signup_completed`) so the sequence starts at a meaningful moment: when the user finishes registration.<br /><br />**Segment-based fallback:** "User matches the segment criteria" using the "Subscribed Users" [segment](./segmentation), future additions only. Use this if you don't have a signup event set up. |
| **Exit rules**     | They moved through the entire journey, or when the user completes the key action (for example, they exit a "has not completed onboarding" segment).                                                                                                                                                                                                                                                            |
| **Re-entry rules** | No                                                                                                                                                                                                                                                                                                                                                                                                             |
| **Content**        | A short sequence over the user's first week: a welcome email on day 0, a push nudge on day 2 if they haven't acted, and a follow-up email on day 7 as a last touch.                                                                                                                                                                                                                                            |

**Journey steps**

<Steps>
  <Step title="Immediately: Send a welcome email">
    The user just signed up and is likely still in your app. An email is the right first touch: it's expected, non-intrusive, and can include more detail than a push notification. Save push for when they've left.
  </Step>

  <Step title="Wait 1 day">
    Give the user time to explore on their own before following up.
  </Step>

  <Step title="Day 2: Branch on key action completed?">
    Add a yes/no branch based on whether the user has completed your onboarding goal. Track this with a [tag](./add-user-data-tags) (for example, `onboarding_complete = true`) or segment membership.

    * **Yes branch:** Exit the journey. The user doesn't need a nudge.
    * **No branch:** Send a push notification with a specific, actionable prompt. For example: "Finish setting up your profile" or "Make your first \[action]."
  </Step>

  <Step title="Wait 5 days">
    Allow time for the push to land before sending a final message.
  </Step>

  <Step title="Day 7: Branch on key action completed?">
    * **Yes branch:** Exit the journey.
    * **No branch:** Send a follow-up email as a last touch. Avoid messaging further. Users who haven't engaged after a week are better candidates for a [re-engagement campaign](#re-engagement-campaign).
  </Step>
</Steps>

<Frame caption="Onboarding welcome journey example">
  <img src="https://mintcdn.com/onesignal/uQXaZLJRo_iX3RUv/images/journeys/onboarding-journey.png?fit=max&auto=format&n=uQXaZLJRo_iX3RUv&q=85&s=fdd555052bb0d43d1202d5bff2ca56b4" alt="Onboarding welcome journey flow with push and email steps" width="748" height="1426" data-path="images/journeys/onboarding-journey.png" />
</Frame>

***

## Re-engagement campaign

Use this pattern to win back users who haven't opened your app or visited your site recently. The journey sends a series of increasingly compelling messages and exits the user as soon as they return.

| Journey setting    | Description                                                                                                                                               |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Entry rules**    | **User's last session is greater than 7 days;** subscribed users. Consider excluding segments like paid customers if the goal is to re-engage free users. |
| **Exit rules**     | **They moved through the entire journey or meet certain conditions** — exit when the user becomes active in your app or website.                          |
| **Re-entry rules** | **Yes, after a certain amount of time: 7 days.** Users re-enter whenever they go inactive again.                                                          |
| **Content**        | Remind users to come back to your app when they haven't opened it in a while, and entice them with rewards or discounts.                                  |

**Journey steps**

<Steps>
  <Step title="Send a push notification">
    Start with a push — it's the most visible channel for re-engaging lapsed users. Use a clear, action-oriented message like "We miss you! Here's what's new."
  </Step>

  <Step title="Wait 2 days">
    Give the user time to respond to the push before escalating.
  </Step>

  <Step title="Branch on user activity">
    Add a yes/no branch to check if the user has returned (for example, last session within 2 days).

    * **Yes branch:** Exit the journey. The user is re-engaged.
    * **No branch:** Send an email with a stronger incentive (for example, a discount, new content, or feature highlight).
  </Step>

  <Step title="Wait 3 days">
    Allow time for the email to drive the user back.
  </Step>

  <Step title="Final check">
    * **Active:** Exit the journey.
    * **Still inactive:** Optionally send a final SMS or exit. Avoid further messaging — users who haven't responded after multiple touches are unlikely to convert from more messages.
  </Step>
</Steps>

<Frame caption="Re-engagement campaign journey example">
  <img src="https://mintcdn.com/onesignal/QOf62tdZP66tkOD2/images/docs/reengagement-journey.png?fit=max&auto=format&n=QOf62tdZP66tkOD2&q=85&s=63990452d48a0d82b27a87469bf7d00a" alt="Re-engagement journey flow with wait steps and exit conditions" width="1427" height="1495" data-path="images/docs/reengagement-journey.png" />
</Frame>

***

## Abandoned cart

<Card title="Abandoned cart example" href="./abandoned-cart" icon="money-bill">
  Use Custom Events or Tags to track cart activity and send abandoned cart messages.
</Card>

***

## Promotional campaign

Use this pattern for time-limited promotions, sales events, or product launches. The journey builds anticipation, reminds users during the event, and creates urgency as it ends.

| Journey setting    | Description                                                                                                                                      |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Entry rules**    | **User matches the segment criteria.** Subscribed users, or a segment relevant to the promotion.                                                 |
| **Exit rules**     | **They moved through the entire journey or meet certain conditions.** Select a segment that defines the goal (for example, users who purchased). |
| **Re-entry rules** | **No** — for one-off campaigns, send once.                                                                                                       |
| **Content**        | Prepare them for the event, remind them when it starts, and offer a discount or reward as it gets close to ending.                               |

**Journey steps**

<Steps>
  <Step title="Announcement: Send a teaser message">
    Send an email or push announcing the upcoming promotion. Include the date, what to expect, and a reason to pay attention.
  </Step>

  <Step title="Wait until event start">
    Add a wait step timed to the start of your promotion.
  </Step>

  <Step title="Event start: Send the main offer">
    Send a push notification or email with the promotion details, discount code, or call to action.
  </Step>

  <Step title="Wait 2–3 days (mid-event)">
    Give users time to act on the initial message.
  </Step>

  <Step title="Reminder: Last chance message">
    Send a final push or email with urgency — "Sale ends tomorrow" or "Last chance for 20% off." Users who already converted will have exited via the exit rule.
  </Step>
</Steps>

<Frame caption="Promotional campaign journey example">
  <img src="https://mintcdn.com/onesignal/QOf62tdZP66tkOD2/images/docs/promotional-journey.png?fit=max&auto=format&n=QOf62tdZP66tkOD2&q=85&s=fa69c44b733a2b2f97973a64e24395fa" alt="Promotional campaign journey flow with timed messages" width="1487" height="1596" data-path="images/docs/promotional-journey.png" />
</Frame>

***

## Send a message after a user leaves without completing an action

**Initial setup**

1. Use [Tags](./add-user-data-tags) to mark that the action needs to be performed by the user. Remove the tag when the action is completed.
2. Set up the [segment](./segmentation) for this tag.

| Journey setting    | Option                                                        | Description                                                                               |
| ------------------ | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------- |
| **Entry rules**    | The user's last session is greater than the amount of time.   | The threshold for how long the user has been inactive in your app or website.             |
| **Audience**       | Include the segment you want to target with the tag.          | These are the users eligible to receive the message.                                      |
| **Exit rules**     | Exit when the user no longer matches the audience conditions. | When the user leaves the segment, they are no longer eligible for the journey message.    |
| **Re-entry rules** | Yes, after a certain amount of time.                          | The amount of time you want to wait for the user to be eligible to get the message again. |

**Journey steps**

<Steps>
  <Step title="Add the desired message(s)">
    Choose a template for the message step. You can use push, email, SMS, or in-app depending on the action you want the user to take.
  </Step>

  <Step title="Set a wait node for the amount of time you want the user to wait">
    This can be a short or long interval depending on whether the message should repeat as a reminder. In this example, the wait is set to 104 weeks (2 years) so the message effectively sends only once — the long wait prevents the user from looping back through the journey while re-entry rules handle the next trigger.
  </Step>
</Steps>

***

## A/B test within a Journey

Using a **split branch** node, you can set a 50/50 split within your journey. Create two different message templates and as your users flow through, half will get "Template A" and the other "Template B".

Export the message data from each template to compare [analytics](./analytics-overview) between variants.

<Frame caption="An A/B test">
  <img src="https://mintcdn.com/onesignal/w9XjWmVBB-0WycSD/images/docs/ab-test-journey.png?fit=max&auto=format&n=w9XjWmVBB-0WycSD&q=85&s=ef12a5ca93a5b5cf6cc48a6f2184a5d6" alt="A/B test journey with a 50/50 split branch and two message templates" width="1608" height="772" data-path="images/docs/ab-test-journey.png" />
</Frame>

***

## Display in-app messages in order and once per day

This example displays 3 or more in-app messages in sequence, showing one per day. If a user does not open the app, the next message appears the next time they open it.

**Initial setup**

<Steps>
  <Step title="Create a new segment">
    Create a segment called `iam_journey` with filter: User Tag `iam_journey` is `1`

    1. You can change `iam_journey` to whatever name you choose.
    2. This tag will be set on each user that finishes the journey and gets all messages.

    <Frame caption="Segment creation screen">
      <img src="https://mintcdn.com/onesignal/QOf62tdZP66tkOD2/images/docs/iam-journey-segment.png?fit=max&auto=format&n=QOf62tdZP66tkOD2&q=85&s=c5c3444e720b727a73a4f8b73bb488df" alt="Segment creation screen with iam_journey tag filter" width="803" height="433" data-path="images/docs/iam-journey-segment.png" />
    </Frame>
  </Step>

  <Step title="Create the in-app messages">
    See [design in-app messages with drag and drop](./design-your-in-app-message) for more.
  </Step>

  <Step title="Set up the following journey">
    | Journey setting    | Option                                | Description                                                                              |
    | ------------------ | ------------------------------------- | ---------------------------------------------------------------------------------------- |
    | **Entry rules**    | User matches the segment criteria     | These are the users eligible to receive the message.                                     |
    | **Audience**       | Include segment & exclude segment     | Include the "Subscribed Users" segment. Exclude the "`iam_journey`" segment from step 1. |
    | **Exit rules**     | They moved through the entire journey | No additional conditions necessary.                                                      |
    | **Re-entry rules** | Yes, after a certain amount of time   | 2 minutes                                                                                |

    **Journey steps**

    Repeat this order for the number of messages you want to display. This example uses 3 in-app messages (IAM 1, IAM 2, IAM 3).

    1. **Add an in-app message step.**
       1. Name the message, for example: `IAM 1`.
       2. At the bottom of the message, set **delivery schedule** to **1 day**.

    2. **Add a yes/no branch action before the in-app message step.**
       1. Set your branching condition: previous message behavior: "`IAM 1` viewed".
       2. **Follow the No branch**
          1. Drag the `IAM 1` to the No branch.
          2. Add a wait step for 1 day.
       3. **Follow the Yes branch**
          1. Within the Yes branch, repeat steps 1 and 2 for all messages, replacing `IAM 1` with the next in-app message (`IAM 2`, `IAM 3`).
          2. At the final Yes branch, add **tag user** action.
             1. Tag the same key used in Initial setup → Step 1 segment.
                1. Example `iam_journey : 1`.

    <Frame caption="The complete journey">
      <img src="https://mintcdn.com/onesignal/QOf62tdZP66tkOD2/images/docs/iam-journey-complete.png?fit=max&auto=format&n=QOf62tdZP66tkOD2&q=85&s=ed5c5c36d00e786c9ad91dffd9699564" alt="Complete in-app message journey with branching and daily delivery" width="1376" height="1522" data-path="images/docs/iam-journey-complete.png" />
    </Frame>
  </Step>
</Steps>

***

## Limited entry journey

Ensure users can only enter a journey a limited number of times while controlling the experience at each stage.

| Journey setting    | Description                                                                                                                                         |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Entry rules**    | User matches the segment criteria (for example, subscribed users or any relevant target segment).                                                   |
| **Audience**       | Include your target segment. Exclude users with the tag `journey_count = 2` to cap entries at two times.                                            |
| **Exit rules**     | They moved through the entire journey.                                                                                                              |
| **Re-entry rules** | Yes, after a certain amount of time: 15 days.                                                                                                       |
| **Content**        | Provide a first-time experience on initial entry, and a tailored second-time experience on re-entry. Prevent any further entries beyond the second. |

<Frame caption="Limited entry settings">
  <img src="https://mintcdn.com/onesignal/Kryww3qVcdmjY27T/images/journeys/limited-entry-settings.png?fit=max&auto=format&n=Kryww3qVcdmjY27T&q=85&s=71647a50f354d2174200298b11678e6b" alt="Limited entry journey settings with audience exclusion and re-entry rules" width="646" height="1490" data-path="images/journeys/limited-entry-settings.png" />
</Frame>

**Initial setup**

<Steps>
  <Step title="Prepare your tag strategy">
    Use a user tag named `journey_count` to track entries. Tags are created automatically when you set them in the Journey. See [tag action](./journeys-actions#tag-user) for details.
  </Step>

  <Step title="Configure audience include/exclude">
    In journey audience:

    * Include your target segment (for example, “Subscribed Users”).
    * Exclude users where user tag `journey_count` is `2`.
  </Step>

  <Step title="Set re-entry rules">
    Set re-entry rules to “Yes, after a certain amount of time: 15 days.”\
    This allows exactly one re-entry between the first and second runs.
  </Step>
</Steps>

**Journey steps**

<Frame caption="Limited entry flow">
  <img src="https://mintcdn.com/onesignal/Kryww3qVcdmjY27T/images/journeys/limited-entry.png?fit=max&auto=format&n=Kryww3qVcdmjY27T&q=85&s=3d8652adedf2610bb444ee217eb52856" alt="Limited entry journey flow with yes/no branch based on journey_count tag" width="932" height="1468" data-path="images/journeys/limited-entry.png" />
</Frame>

<Steps>
  <Step title="Add a yes/no branch at the start">
    Condition: user tag `journey_count` equals `1`.

    * **Yes branch** = returning users (second entry).
    * **No branch** = first-time users (no tag present yet).
  </Step>

  <Step title="No branch (first time entry)">
    * Add tag user action: set `journey_count` to `1`.
    * Send your first-time messages and actions.
    * Continue to end or additional logic as needed.
  </Step>

  <Step title="Yes branch (second time entry)">
    * Add tag user action: set `journey_count` to `2`.
    * Send your returning-user messages and actions.
    * Continue to end or additional logic as needed.
  </Step>

  <Step title="Enforce the limit">
    Because the audience excludes users with `journey_count = 2`, any attempted third entry is blocked automatically.
  </Step>
</Steps>

***

## Recurring journeys for specific days

Send recurring messages that align with a specific day of the week, like weekly promotions or event reminders.

| Journey setting    | Description                                                          |
| ------------------ | -------------------------------------------------------------------- |
| **Entry rules**    | User matches the segment criteria (for example, subscribed users).   |
| **Audience**       | Include your target segment.                                         |
| **Exit rules**     | They moved through the entire journey.                               |
| **Re-entry rules** | Yes, after a certain amount of time: 7 days.                         |
| **Content**        | A weekly message sent on a specific day (for example, every Friday). |

<Frame caption="Recurring journey settings">
  <img src="https://mintcdn.com/onesignal/lYMMkFJp3v40a2sJ/images/journeys/recurring-journey-settings.png?fit=max&auto=format&n=lYMMkFJp3v40a2sJ&q=85&s=774b448a2c3789fcf5173ad71630d2aa" alt="Recurring journey settings with 7-day re-entry" width="648" height="1446" data-path="images/journeys/recurring-journey-settings.png" />
</Frame>

**Initial setup**

<Steps>
  <Step title="Configure audience">
    Include your target segment so eligible users can enter the journey at any time during the week.
  </Step>

  <Step title="Set re-entry rules">
    Set re-entry rules to “Yes, after a certain amount of time: 7 days” to enable weekly recurrence.

    * The re-entry timer starts when the user **exits** the Journey, not when they entered.
    * A 7-day re-entry ensures users re-enter in time for the next week’s time window.
    * The re-entry duration must be **longer than the time window duration** to avoid double-sends.

    See [Using time windows for recurring sends](./journeys-actions#using-time-windows-for-recurring-sends) for details.
  </Step>
</Steps>

**Journey steps**

<Frame caption="Recurring journey flow">
  <img src="https://mintcdn.com/onesignal/lYMMkFJp3v40a2sJ/images/journeys/recurring-journey-steps.png?fit=max&auto=format&n=lYMMkFJp3v40a2sJ&q=85&s=12657ad8e9b0cfc2de32a9d87f9eed2c" alt="Recurring journey flow with time window node and message step" width="598" height="1460" data-path="images/journeys/recurring-journey-steps.png" />
</Frame>

<Steps>
  <Step title="Add a time window node (first step)">
    Configure the time window to filter for your target day of week (for example, Friday).\
    Users entering the journey will wait until the next matching day.
  </Step>

  <Step title="Add your message after the time window">
    Place the message node immediately after the time window so it sends when the day is reached.
  </Step>

  <Step title="End the journey">
    Let users exit after the message sends. With re-entry at 7 days, they will rejoin and repeat weekly.
  </Step>
</Steps>

<Tip>
  Update the message content regularly to avoid sending the same copy each week.
</Tip>

***

## Progressive journeys (event-driven)

Escalate engagement based on user progression using [custom events](./custom-events) and [wait-until](./journeys-actions#wait-until) conditions.

| Journey setting    | Description                                                                                                                                                                                                                                                                                                                     |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Entry rules**    | **Custom Event** = `Progression_Level`, with filter `progression_level = 0`.                                                                                                                                                                                                                                                    |
| **Audience**       | Optional segment filter. You can run this for all users or restrict to a subset; no tags required.                                                                                                                                                                                                                              |
| **Exit rules**     | - They moved through the entire journey.<br />- Or when maximum progression level is reached (`progression_level = 3`).<br />- Optionally: exit when a **Wait Until** node expires.<br />- Optionally: branch from a **Wait Until** node to tag users who do not complete the event, leading them into a re-engagement journey. |
| **Re-entry rules** | No                                                                                                                                                                                                                                                                                                                              |
| **Content**        | Stage-based messages that escalate as users complete milestones (emails in this example).                                                                                                                                                                                                                                       |

<Frame caption="Progression journey flow">
  <img src="https://mintcdn.com/onesignal/86gjHZhU_WHClFAO/images/journeys/progression-journeys.png?fit=max&auto=format&n=86gjHZhU_WHClFAO&q=85&s=d1115ca7a2a7c06aa0cc0fa4b81a0533" alt="Progressive journey flow with wait-until nodes for each level milestone" width="690" height="1482" data-path="images/journeys/progression-journeys.png" />
</Frame>

**Journey steps**

<Steps>
  <Step title="User enters the journey">
    All eligible users enter based on entry rules.\
    Trigger: **Custom Event** `Progression_Level` with `progression_level = 0`.\
    Start: **Immediately**.
  </Step>

  <Step title="Level 1">
    * Wait until custom event `Progression_Level` occurs with `progression_level = 1`.
    * Send: **Level 1 Complete!** message.
    * (Optional) Apply expiration on the wait node → exit user if milestone not reached.
    * (Optional) Branch: if expiration hits, tag the user and send them into a re-engagement journey.
  </Step>

  <Step title="Level 2">
    * Wait until custom event `Progression_Level` occurs with `progression_level = 2`.
    * Send: **Level 2 Complete, you are doing great!** message.
    * (Optional) Apply expiration or branch/tag to re-engagement.
  </Step>

  <Step title="Level 3">
    * Wait until custom event `Progression_Level` occurs with `progression_level = 3`.
    * Send: **You’ve reached level 3!** message.
    * (Optional) Apply expiration or branch/tag to re-engagement.
  </Step>

  <Step title="Exit">
    End the journey once users complete Level 3, or when a Wait Until node expires.\
    Optionally, use branch/tag paths to route stalled users into a re-engagement track.\
    Schedule: **Start immediately**, **Never stops**.
  </Step>
</Steps>

<Tip>
  This method ensures progression happens only when real engagement signals occur. Adding expiration and branch/tag logic lets you handle stalled users gracefully — either exiting them or re-routing into a re-engagement Journey.
</Tip>

***

## Branch a Journey by action button clicked

Route users down different Journey paths based on which push notification action button they tapped. This pattern uses [action buttons](./action-buttons), a [custom event](./custom-events), and a [Wait Until](./journeys-actions#wait-until) step to branch users by their specific button click — not just whether they clicked or not.

<Info>
  This example requires website or app code to capture the button click and send a custom event. It cannot be done entirely through the OneSignal dashboard.
</Info>

| Journey setting    | Description                                                                                                     |
| ------------------ | --------------------------------------------------------------------------------------------------------------- |
| **Entry rules**    | User matches the segment criteria (for example, subscribed users or a campaign-specific segment).               |
| **Exit rules**     | They moved through the entire journey.                                                                          |
| **Re-entry rules** | No                                                                                                              |
| **Content**        | Send a push with multiple action buttons, then branch follow-up messages based on which button the user tapped. |

The built-in [Yes/No branch](./journeys-actions#yesno-branch) message behavior conditions detect whether a user **clicked** or **was delivered** a message — but not *which* button they clicked. To branch by specific button, you capture the Action ID from the click event and send it as a Custom Event property that the Journey can branch on.

<Steps>
  <Step title="Add action buttons to your push">
    When creating the push message in the Journey (or in a [template](./templates)), open **Advanced Options > Action Buttons** and assign a unique **Action ID** to each button.

    **Example**: A promotional push with two CTAs:

    * Button 1: "Shop Now" → Action ID: `shop_now`
    * Button 2: "Learn More" → Action ID: `learn_more`

    See [Action buttons](./action-buttons) for full setup details.
  </Step>

  <Step title="Add a click listener and send a Custom Event">
    On your website or in your app, listen for the notification click event and send a Custom Event that includes the Action ID as a property.

    <Note>
      The Web SDK example requires version `160500` or later. Users should be [logged in](./web-sdk-reference#login) for custom events to be tracked.
    </Note>

    <CodeGroup>
      ```javascript Web SDK theme={null}
      OneSignalDeferred.push(function(OneSignal) {
        OneSignal.Notifications.addEventListener("click", function(event) {
          var actionId = event.result.actionId;
          if (actionId) {
            OneSignal.User.trackEvent("cta_clicked", { button: actionId });
          }
        });
      });
      ```

      ```kotlin Android SDK theme={null}
      OneSignal.Notifications.addClickListener { event ->
          val actionId = event.result.actionId
          if (actionId != null) {
              OneSignal.User.trackEvent("cta_clicked", mapOf("button" to actionId))
          }
      }
      ```

      ```swift iOS SDK theme={null}
      let listener = { (event: OSNotificationClickEvent) in
          if let actionId = event.result.actionId {
              OneSignal.User.trackEvent("cta_clicked", properties: ["button": actionId])
          }
      }
      OneSignal.Notifications.addClickListener(listener)
      ```
    </CodeGroup>

    See [Custom events](./custom-events) for event requirements and limits.
  </Step>

  <Step title="Add a Wait Until step in the Journey">
    After the push message step in your Journey:

    1. Add a **Wait Until** step.
    2. Add a condition for each button: Custom Event `cta_clicked` where property `button` equals the Action ID (for example, `shop_now`).
    3. Add additional conditions for each Action ID you want to branch on (for example, `learn_more`).
    4. Set an **expiration** (for example, 3 days) so users who don't click any button continue down a fallback path.

    Users follow the branch for the **first condition they meet**. If no condition is met before the expiration, they follow the expiration branch.
  </Step>

  <Step title="Add follow-up messages to each branch">
    On each branch after the Wait Until step, add the appropriate follow-up message or action:

    * **"Shop Now" branch**: Send a product recommendation or discount code.
    * **"Learn More" branch**: Send educational content or a feature overview.
    * **Expiration branch**: Send a re-engagement message or exit the Journey.
  </Step>
</Steps>

<Tip>
  You can chain multiple Wait Until steps to branch on subsequent interactions too — there is no limit on the number of Wait Until steps in a Journey.
</Tip>

***

## FAQ

### Can I schedule a message to send every day?

Yes. Add a [time window](./journeys-actions#time-window) node as the first step and configure it for every day of the week with the hours you want the message to send (for example, 10 AM to 6 PM in the user's time zone). Then set **re-entry rules** to re-enter after a time shorter than one day but **longer than the time window duration** — for example, 12 hours for an 8-hour window. This ensures users re-enter early enough to catch the next day's time window without risking a double-send within the same window.

### Can I A/B test different messages in a Journey?

Yes. Add a [split branch](./journeys-actions#random-split) node to divide users evenly (for example, 50/50). Place a different message template on each branch, then compare analytics between the two templates after the Journey runs.

### How do I limit how many times a user can enter a Journey?

Use a tag (for example, `journey_count`) to track entries. Increment the tag each time the user enters, and add an audience exclusion rule that blocks users once the tag reaches your desired limit. See the [Limited entry journey](#limited-entry-journey) example above.

### Why did my recurring Journey send on the wrong day?

The [time window](./journeys-actions#time-window) node filters by the user's local time zone if time zone data is available. If a user does not have time zone data, the message sends based on your app's default time zone. Verify that your time window settings and user time zone data are correct.

### How do I stop a running Journey?

Set the Journey status to **Paused** or **Stopped** in the Journey settings. Paused Journeys retain users at their current step; stopped Journeys exit all users immediately. See [Journey settings](./journeys-settings) for details.

***

## Related pages

<Columns cols={2}>
  <Card title="Journeys overview" icon="route" href="./journeys-overview">
    Introduction to Journeys and how they work.
  </Card>

  <Card title="Journey actions" icon="code-branch" href="./journeys-actions">
    Add wait steps, branching logic, time windows, and split paths.
  </Card>

  <Card title="Journey settings" icon="gear" href="./journeys-settings">
    Configure entry rules, exit rules, re-entry, and scheduling.
  </Card>

  <Card title="Journey messages" icon="envelope" href="./journeys-messages">
    Configure push, email, SMS, and in-app message steps in a Journey.
  </Card>

  <Card title="Abandoned cart" icon="cart-shopping" href="./abandoned-cart">
    Full walkthrough for building an abandoned cart Journey.
  </Card>

  <Card title="Custom events" icon="bolt" href="./custom-events">
    Trigger Journeys and pass event properties for personalization.
  </Card>

  <Card title="Journey analytics" icon="chart-bar" href="./journeys-analytics">
    Track Journey performance with delivery metrics, user activity, and conversion insights.
  </Card>
</Columns>

<AccordionGroup>
  <Accordion title="Additional resources on the OneSignal blog">
    * [Maximizing User Engagement: The Synergy of Push Notifications and Email](https://onesignal.com/blog/use-push-notifications-and-email-together/)
    * [Consistently Drive Value with Journeys](https://onesignal.com/blog/consistently-drive-value-with-journeys/)
    * [Increase Engagement with Email for Cross-Channel Journeys](https://onesignal.com/blog/increase-engagement-with-email-for-cross-channel-journeys/)
    * [Improve Retention with In-App and SMS for Journeys](https://onesignal.com/blog/improve-retention-with-in-app-and-sms-for-journeys/)
  </Accordion>
</AccordionGroup>
