Build a Post‑Purchase NPS Loop That Actually Changes Churn
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:
Capture detail on every customer so you can speak to each uniquely.
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:
Once a day, Spreeflo finds customers who purchased recently and haven’t had an NPS ask in the last 90 days.
It sends a single NPS email with a link to a one‑question survey.
It waits up to 7 days for an NPS response (tracked as a custom event via the Spreeflo SDK or the Spreeflo API).
If there’s no response, the journey can optionally send a gentle reminder, then stop.
If there is a response, it routes the contact into promoter, passive, or detractor paths based on their score.
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:
- isSubscribed
- 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 viaSpreeflo.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 daysTimeout 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.identifyto 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_responsetriggered at least 1 time in the last 7 daysThen 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 eventnps_responsetriggered at least 1 time in the last 7 days
with propertyscoregreater than or equal to 9.Branch: Detractor
- Condition: Custom eventnps_responsetriggered at least 1 time in the last 7 days
with propertyscoreless 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:
Update Contact Attribute
- Attribute: a custom text attribute, e.g.nps_segment
- Update type: Update
- New value:"promoter"Add Tag
- Tags:nps-promoter
- Force tag trigger: off
Why both:
The
nps_segmentattribute is easy to use in reports or dashboards.The
nps-promotertag 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:
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 thecommentproperty from the NPS event if you capture it.(Optional) Time Delay
- 1 day, to give the team space to respond manually first if they prefer.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
planattribute, and only send to paying or higher‑tier customers.Multi‑event eligibility: instead of
purchase, you can base eligibility on afeature_usedevent (“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:
You stop treating scores as a dashboard number and start treating them as communication triggers.
Your team hears about problems while they can still do something, not when a cancellation hits.
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.