Back to Playbooks

Build a Post‑Purchase NPS Loop That Actually Changes Churn

Free

A detailed walkthrough for e‑commerce and Shopify app teams on wiring a post‑purchase NPS journey in Spreeflo, turning survey responses into automated promoter, passive, and detractor flows that reduce churn, drive advocacy, and keep feedback actionable.

Industry

Niche

Pattern

Loading sequence...

Two weeks after Black Friday, Lina from CartWizard (a Shopify cart recovery app doing ~$90k MRR) opened a spreadsheet her team had proudly titled “NPS dashboard.”

There were 130 responses. Average score: 36. A few glowing comments. A handful of brutal ones.

Then came the familiar shrug: “We should probably do something with this.”

By the next week, that spreadsheet was buried under support queues and feature requests. NPS had turned into a reporting exercise instead of a retention engine.

You do not have time to collect vanity metrics.

You do have time to wire NPS into an automation that surfaces promoters, catches detractors early, and nudges both groups in the right direction without anyone touching a spreadsheet.

The sequence at the top of this page is the whole journey, end to end. It runs on a date-based loop, sends a single NPS ask after purchase, then routes every response to the right follow‑up for both the customer and your team.

This article walks through how that journey is built in Spreeflo, node by node, and how you can adapt it for your own e‑commerce app.

Why a post‑purchase NPS loop matters for apps

For a Shopify or e‑commerce app, your revenue leaks are rarely “we picked the wrong headline.”

They are:

  • Stores that install your app, buy their first month, and silently churn after encountering friction.

  • High‑value users who love you but never get asked for a review or referral.

  • Mid‑tier customers who feel “meh” and are easily poached by the next shiny app.

NPS is one of the cleanest signals you can get on those three groups. The mistake is treating it as a quarterly survey, disconnected from the rest of your system.

When you turn NPS into a journey:

  • Every score is tied to a contact and their behavior.

  • Every detractor kicks off an immediate save attempt.

  • Every promoter is given a path to deepen their relationship with you (reviews, referrals, early access, higher plans).

This is the embodiment of two core ideas we care about:

  1. Capture detail on every customer so you can speak to each uniquely.

  2. Stop leaving lifetime value on the table by ignoring engagement.

Let’s wire this up.

The high‑level flow

Before we zoom into individual nodes, here is the story the journey tells:

  1. Once a day, Spreeflo finds customers who purchased recently and haven’t had an NPS ask in the last 90 days.

  2. It sends a single NPS email with a link to a one‑question survey.

  3. It waits up to 7 days for an NPS response (tracked as a custom event via the Spreeflo SDK or the Spreeflo API).

  4. If there’s no response, the journey can optionally send a gentle reminder, then stop.

  5. If there is a response, it routes the contact into promoter, passive, or detractor paths based on their score.

  6. Each path:
    - Updates the contact’s NPS segment.
    - Tags them for future targeting.
    - Sends the right follow‑up email.
    - Notifies your team internally so someone can actually act.

You build this as a journey (always‑on automation), not a one‑time campaign. If you’re new to automations in Spreeflo, the overview of campaigns and journeys is a good primer.

Now let’s walk through the actual nodes.

1. Cyclic trigger: who we ask, and when

Node: Cyclic trigger
Role: start the journey on a daily schedule for matching contacts.

Configuration:

  • Repeat interval: every 1 day

  • Time of day: 09:00 in your main customer timezone

  • Re‑enrollment: on (true)

Criteria (using Spreeflo’s segment builder):

  • Group connector: AND
    - Custom Events:
    - Event: purchase (or whatever you track as a successful install/charge)
    - Operator: triggered at least 1 time
    - Time window: in the last 14 days
    - Email Subscription Status:
    - is Subscribed
    - Email Activity:
    - Specific email: your NPS email template
    - Condition: was not sent
    - Time window: in the last 90 days

Why this setup:

  • Using Cyclic instead of a single Custom Event trigger lets you keep the logic “14 days after purchase” in one place and adjust it over time without touching your tracking.

  • Checking that the NPS email “was not sent in the last 90 days” ensures a customer doesn’t get hammered with NPS asks if they purchase multiple times in a short window.

  • Re‑enrollment is on because long‑term customers might be eligible for NPS again in the future. The 90‑day email‑activity condition is what prevents duplicates too close together.

If you prefer to only ever survey a customer once, tighten that last rule to “was not sent over all time” and set this trigger’s re‑enrollment to off.

2. NPS invite: the email we actually send

Node: Send Email
Role: send the NPS survey invitation.

Configuration:

  • From: your main sending identity

  • Template: built in Spreeflo’s email builder

  • “Send only once”: off (we’re already guarding with the email‑activity condition)

Content notes (marketing, not mechanics):

  • Subject: simple and direct. Example: “Quick question about [AppName]: 0–10?”

  • Body:
    - Remind them what your app helps them do.
    - Make it clear this takes seconds.
    - Big NPS scale or button that leads to your survey page (where you track the response via Spreeflo.track("nps_response", { score, comment })).

Why here:

  • This is the first touch in the journey, and since it’s date‑based, you want it to feel like a natural follow‑up to their recent purchase or install (not an abstract “rate us sometime” message).

  • We keep “Send only once” off so the same template can be reused in future waves, controlled by the segment criteria.

Pacing rule: this is the first marketing email in the path, so no spacing issue yet.

3. Wait for a response without stalling forever

Node: Wait Condition
Role: give customers up to 7 days to respond, but move on as soon as they do.

Configuration:

  • Condition (Segment Builder):
    - Custom Events:
    - Event: nps_response
    - Operator: triggered at least 1 time
    - Time window: in the last 7 days

  • Timeout duration: 7 days

Why Wait Condition instead of a fixed delay:

  • If someone responds 30 minutes after the email, you don’t want to wait a full week before treating them as a promoter or detractor.

  • Wait Condition releases the contact as soon as the condition is true, or when the timeout hits, whichever comes first.

How the tracking works in practice:

  • Your NPS survey page calls Spreeflo.identify to link the browser to the right contact (if it isn’t already).

  • When they submit, you fire Spreeflo.track("nps_response", { score, comment }).

  • That custom event is what this Wait Condition is watching for.

If you’re sending the NPS data server‑side, you can use the HTTP endpoints in the Spreeflo API docs instead. The journey logic is identical either way.

4. Did they answer at all?

Node: If/Else
Role: split between “responded” and “no response.”

Configuration:

  • Condition (same as the Wait Condition):
    - Custom Events: nps_response triggered at least 1 time in the last 7 days

  • Then branch: responded

  • Else branch: no response

Why this extra split:

  • Wait Condition by itself doesn’t tell you why it released: response vs timeout.

  • By checking the same condition immediately after, you can separate people who answered from those who ignored the email.

What happens on each branch:

  • Else (no response):
    - Option 1: do nothing and end the journey for this contact.
    - Option 2: add a Time Delay of 3–5 days, then a one‑time Send Email reminder. If you do that, remember there is already spacing (Wait Condition) between the two emails, so you’re safe on pacing.

  • Then (responded): that path continues into the NPS score routing.

For the rest of this playbook, we’ll focus on the “responded” branch.

5. Multi‑way Split: promoter, passive, detractor

Node: Multi‑way Split
Role: branch contacts based on their NPS score.

Configuration:

  • Branch: Promoter
    - Condition: Custom event nps_response triggered at least 1 time in the last 7 days
    with property score greater than or equal to 9.

  • Branch: Detractor
    - Condition: Custom event nps_response triggered at least 1 time in the last 7 days
    with property score less than or equal to 6.

  • Else branch: Passive
    - No explicit condition; anyone not matched above (scores 7–8, or edge cases) falls here.

Why this structure:

  • You’re using Custom Events in the Segment Builder, with property filters on score.
    That keeps all the routing logic inside Spreeflo; no extra mapping layer.

  • The 0–6 / 7–8 / 9–10 buckets are the standard NPS bands your team already understands.

You could get fancier (for example, having a separate branch for “10 with a long comment”), but this three‑way split covers 90% of use cases.

6. Tag and classify each NPS segment

Before you send follow‑up emails, you want to stamp each contact with reusable data.

Promoter branch

Nodes:

  1. Update Contact Attribute
    - Attribute: a custom text attribute, e.g. nps_segment
    - Update type: Update
    - New value: "promoter"

  2. Add Tag
    - Tags: nps-promoter
    - Force tag trigger: off

Why both:

  • The nps_segment attribute is easy to use in reports or dashboards.

  • The nps-promoter tag is great for quickly building audiences, e.g. a saved segment “promoters who haven’t left a review.”

You can follow the same pattern for passives and detractors, with static values "passive" and "detractor" and tags nps-passive and nps-detractor.

Remember: Update Contact Attribute writes a static literal that you configure on the node. Each branch sets its own literal value, which is exactly what you want here.

If you’re new to tags inside Spreeflo, the guide on getting started with tags is worth a skim.

7. Close the loop with the customer

Now, each branch sends a different follow‑up email. They all come after the Wait Condition and Multi‑way Split, so every path already has the required spacing from the initial NPS invite.

Promoters: thank‑you + advocacy

Branch: promoter
Node: Send Email

Content ideas:

  • Open by acknowledging their high score.

  • Thank them sincerely for supporting a small team.

  • Offer one specific action:
    - Leave a review on your app marketplace listing.
    - Share a short testimonial you can quote.
    - Refer a friend (with a clear, simple way to do it).

Why this matters:

  • Turning promoters into public advocates is where NPS starts to pay back acquisition costs.

  • Because you’ve tagged them, you can also pull them into future “early access” or beta journeys.

Passives: learn what’s missing

Branch: passive (else branch)
Node: Send Email

Content ideas:

  • Acknowledge their honest feedback.

  • Ask one focused question: “What would have made this a 9 or 10 for you?”

  • Offer a low‑friction way to answer: short reply, 1–2 checkboxes, or a quick Loom link if you do product interviews.

Here you’re trying to turn vague “it’s fine” sentiment into concrete product insights. For higher‑value accounts, you can add a Send Internal Email node after this to notify the product owner whenever a passive with MRR above a threshold responds.

Detractors: fast human response

Branch: detractor
Nodes:

  1. Send Internal Email
    - To: founder, product lead, or customer success
    - Subject: “NPS detractor: [Contact] – score [X]”
    - Body: include the contact’s email, store URL, plan, and the comment property from the NPS event if you capture it.

  2. (Optional) Time Delay
    - 1 day, to give the team space to respond manually first if they prefer.

  3. Send Email
    - Tone: humble and direct.
    - Acknowledge their low score.
    - Offer a concrete next step: a quick call, a Loom walkthrough of the feature they struggled with, or a simple “hit reply and tell us what went wrong.”

Why this order:

  • The Send Internal Email fires immediately so your team knows there’s a problem.

  • The external email can go out right away or after a short delay depending on how high‑touch you want to be.

Detractors are where you catch churn before it hits Stripe. A single save here often covers months of your Spreeflo's pricing, which is exactly the kind of leverage founder‑led teams need.

8. Close the loop with your team as a whole

Individual internal alerts are helpful, but you may also want a lightweight view of your NPS distribution without leaving Spreeflo.

Two simple options:

  • Create three saved segments based on the tags: nps-promoter, nps-passive, nps-detractor. Those counts immediately show you your promoter/detractor split at any point.

  • Build a separate weekly Cyclic journey that sends a Send Internal Email summary to your team: “This week: 24 promoters, 3 detractors, 12 passives.” The contact list for that campaign can be pre‑computed via segments; the email can highlight a few recent comments your team should read.

This is not a full analytics suite. It’s an operational heartbeat that keeps feedback close to the people who can act on it.

9. Adapting the pattern to your app

Every app’s lifecycle is a little different. A few easy tweaks that still fit the same structure:

  • Shorter or longer delay: for high‑touch B2B apps, you might want 30 days instead of 14 so users experience more of the product before scoring.

  • Target by plan: add an If/Else before the NPS email that checks a plan attribute, and only send to paying or higher‑tier customers.

  • Multi‑event eligibility: instead of purchase, you can base eligibility on a feature_used event (“sent first 10 recovery emails”) so you only survey users who hit activation.

The key is that every tweak goes through the same building blocks: Cyclic trigger + Segment Builder criteria + branching nodes.

You can always revisit this journey later, duplicate it from the template library, and adjust thresholds as your product and customer base evolve.

What this buys you over a spreadsheet

When you wire NPS into a journey like this, three things change:

  1. You stop treating scores as a dashboard number and start treating them as communication triggers.

  2. Your team hears about problems while they can still do something, not when a cancellation hits.

  3. Your best customers get an intentional path to deepen their relationship with the product and brand.

Under the hood, this is just a handful of nodes: one Cyclic trigger, a Send Email, a Wait Condition, an If/Else, a Multi‑way Split, a few Update Contact Attribute and Add Tag actions, and some Send Internal Email steps.

You configure it once, it runs every day, and it compounds.

For a small e‑commerce app team, that is the point. You capture more detail on every customer, speak to promoters and detractors differently, and you keep lifetime value from quietly leaking away between purchases.

The spreadsheet can still exist if you want. It just becomes an artifact of a system that is already acting on NPS, not a graveyard of forgotten feedback.