Turn “Unsubscribe” Into Insight: A Feedback Survey Journey for Shopify Apps
Design a Spreeflo journey that turns Shopify app unsubscribe intent into structured feedback, clear save vs unsubscribe paths, and measurable metrics, so small SaaS teams stop guessing why merchants opt out and start acting on real data.
Industry
Niche
Pattern
Loading sequence...
The first time Lina looked at her churn report for CartWizard, she saw a clean number: 4.2% of merchants unsubscribed from her product tips each month.
Then she opened a few individual records.
“Unsubscribed.”
No reason. No context. No idea whether those stores hated the product or just wanted fewer emails.
CartWizard is a four-person team making a cart recovery app for Shopify stores, sitting at about $90k MRR. Their install rate is healthy. Their biggest leak is invisible: people quietly opting out of marketing, then uninstalling a few weeks later with no feedback trail.
That’s what this pattern fixes.
The sequence at the top of this page is the whole journey, end to end. It listens for “I’m thinking of unsubscribing” behavior, sends a short survey email, and then either saves the contact on a lighter-touch cadence or unsubscribes them cleanly with their reason recorded.
For a small SaaS team, this is where you stop guessing why people leave and start collecting structured, per-contact data — at scale — without manual work.
What this journey is (and what it isn’t)
Important framing first: this flow reacts to unsubscribe intent, not the mandatory “unsubscribe from all” link in your email footer.
You should still:
Keep a one-click “unsubscribe from all marketing” link that takes effect immediately.
Treat that hard unsubscribe as sacred and never gate it behind extra steps.
This journey surrounds everything _before_ that hard line:
A “Pause emails” toggle in your Shopify app settings.
A link in your footer that says “Too many emails? Adjust frequency or tell us why.”
An in-app CTA like “Stop weekly tips” that signals frustration but not full opt-out yet.
Those clicks fire a Custom Event into Spreeflo. The journey captures that intent, asks for a 10‑second reason, offers a softer alternative (fewer emails), then either:
Keeps them on a low-frequency track (a “save”), or
Unsubscribes them and records why.
You get two key metrics almost for free:
Survey completion rate
Save rate from unsubscribe intent
Both are much more useful than a raw unsubscribe count.
Step 0: Capture unsubscribe intent as an event
Before the journey can run, your app has to say: “This contact is thinking about unsubscribing.”
You have two practical ways to do that:
From your backend using the Spreeflo API
From your front-end using the SDK described in web tracking and analytics
When a merchant clicks your “Pause emails” or “Too many emails?” link, send a Custom Event such as:
unsubscribe_intent
You’ll also typically attach context on that call:
source(e.g.,footer_link,in_app_settings)channel(e.g.,product_tips,changelog)
At the same time, have your front-end call Spreeflo.identify and set a text attribute like unsubscribe_intent_source and, optionally, unsubscribe_reason_freeform if you collect a quick inline reason.
That single instrumentation point is the bridge between UX and automation. Everything else in this article assumes that event exists.
Step 1: Custom Event trigger — listening for intent
At the very top of the journey you’ll see a Custom Event trigger configured for the unsubscribe_intent event.
Key configuration choices:
Event name:
unsubscribe_intentProperty conditions: usually off to start. If you only want this flow for a subset (say, only product-tip emails), you can add a condition later on
channel is product_tips.Re-enrollment: set to true.
Re-enrollment matters. A merchant might flirt with unsubscribing a few times a year. You want this journey to fire each time they hit that threshold, not just the first time in their life.
Because journeys in Spreeflo have a mid-journey lock, re-enrollment doesn’t create duplicates. If they hit “Pause emails” twice in an hour, they still move through one instance of the flow.
This trigger is where you turn a vague sense of “some people are opting out” into something concrete the system can respond to.
Step 2: Tag and timestamp the intent
The first node after the trigger in the sequence is an Add Tag action.
Configuration:
Tags:
unsubscribe-intent(and optionallyunsubscribe-product-tipsetc.)Force tag trigger: off (you generally don’t want to repeatedly fire Added Tag triggers from the same label here).
This tag is your audit trail. It lets you:
Build segments later like “contacts who signalled unsubscribe intent in the last 30 days”.
Track conversion to “saved” or “fully unsubscribed” downstream.
Right after tagging, add an Update Contact Attribute node that sets a timestamp attribute, for example unsubscribe_intent_at, using “Set to now”.
That combination — tag plus timestamp — is how you measure how fresh the intent is and whether your journey is resolving it quickly enough.
If you’re new to tags in Spreeflo, this is a good time to skim getting started with tags. This pattern relies on tags as the glue between raw behavior and analytics.
Step 3: Send the “before you go” survey email
Next in the journey is a Send Email node. This is the only customer-facing message in the flow.
You’ll build it in our email builder, and it should do three jobs clearly:
Acknowledge their control.
Offer a one-click “Unsubscribe from all” option.
Ask a single, respectful question.
A simple structure:
Subject: “We’ll pause emails — one quick question?”
First line: “You’re in control of how often we email you. You can unsubscribe immediately below.”
Primary buttons:
- “Unsubscribe from all emails” (takes them to a page or endpoint that updates their email subscription status to Unsubscribed via API)
- “Keep emails, just send fewer” (fires aunsubscribe_save_clickedCustom Event and updates an attribute likeemail_frequency = low)One-link survey: “Tell us why (10 seconds)” that opens a very short form.
Inside the Send Email node:
Choose the sender identity that matches your main marketing emails.
Keep “Send only once” turned on. If they trigger unsubscribe intent again months later, you’ll create a new journey instance with a new Send Email step.
This email is partly transactional (“we heard your request”) and partly research. The tone should reflect that. You’re not trying to talk them out of their decision with a wall of copy. You’re trying to understand it and offer a lower-friction alternative.
Step 4: Wait briefly for a response
You don’t want to hammer their inbox, and you also don’t want their intent to linger unresolved forever. That’s where the Wait Condition node comes in next.
Configuration:
Condition: a group that looks roughly like:
- Custom eventunsubscribe_save_clickedtriggered at least 1 time in the last 1 day
- OR Custom eventunsubscribe_feedback_submittedtriggered at least 1 time in the last 1 dayTimeout: 1 day
Under the hood, that condition is built in Spreeflo’s segment builder using the Custom Events filter with frequency and time-window modifiers.
The effect:
If they click “Keep me subscribed” or complete the survey, the condition becomes true and the journey moves on immediately.
If they ignore the email, the timeout expires after a day and the contact continues anyway.
Either way, nobody is stuck mid-journey for more than 24 hours, and you always have a deterministic point where you decide what happens to their subscription.
Step 5: Split “saved” vs “not saved”
After the wait, the journey hits an If/Else node.
Here you decide whether this contact has effectively “rescued” themselves from unsubscribing.
Condition ideas:
Custom event
unsubscribe_save_clickedtriggered at least 1 time in the last 1 day
orContact attribute
email_frequencyislow(if your backend updates it when they click the “fewer emails” option)
If the condition is true, they go down the “Saved” path. If not, they go down the “Unsubscribe” path.
Why not key off the survey event here? Because survey completion isn’t the same as opting back in. Someone can give you feedback and still want to leave. The “save” event or attribute should indicate explicit permission to keep emailing, ideally with a lower cadence.
Step 6: The “Saved” path — reduce cadence and log the win
On the “Saved” branch you’re essentially saying: “Thanks for the honesty. Let’s make this less noisy.”
Typical nodes on this path:
Add Tag
- Tag:unsubscribe-saved
- This is your numerator for save-rate reporting: how many unsubscribe intents ended in a save.Update Contact Attribute
- Attribute:email_frequency(a custom text attribute you define)
- Update type: Update
- New value:low
- Every future campaign and journey can check this attribute to send fewer broadcasts to these contacts.Optional: Send Internal Email
- For high-value segments (e.g., large Shopify Plus stores), you might alert a human.
- Subject line could be “High-LTV merchant nearly unsubscribed but chose lower frequency”.
- Body pulls in the contact’s attributes, current plan, and anyunsubscribe_reason_*attributes your backend writes when they submit the survey.Remove Tag
- Tag:unsubscribe-intent
- You’ve resolved this specific intent, so keeping the flag around just muddies your data.
At this point, the contact stays subscribed, gets less frequent email, and you have a clear log that this journey did its job.
Step 7: The “Unsubscribe” path — respect the choice and capture insight
On the Else branch, you assume the merchant wants out. Your job is to:
Make sure they are fully unsubscribed.
Record why, if you have that data.
Optionally notify your team for patterns and follow-up.
A clean sequence here looks like:
Update Email Subscription Status
- Status: Email unsubscribed
- This ensures that, even if your backend didn’t already flip their status, Spreeflo will stop sending them marketing emails.If/Else on “gave feedback or not”
- Condition: Custom eventunsubscribe_feedback_submittedtriggered at least 1 time in the last 7 days
- Yes branch: they answered your survey.
- Else branch: they skipped it.On the “gave feedback” branch:
- Add Tag:unsubscribed-with-feedback
- Optional Update Contact Attribute:
- Attribute:last_unsubscribe_feedback_at(timestamp)
- Update type: Set to now
- Optional Send Internal Email to your product or success inbox with context like:
- Store name, plan, MRR
- Theunsubscribe_reasonattribute your backend wrote when they submitted the surveyOn the “no feedback” branch:
- Add Tag:unsubscribed-no-feedback
You now have three neat slices for reporting:
unsubscribe-intentvs overall audienceAmong those,
unsubscribe-savedvs unsubscribedAmong unsubscribed,
unsubscribed-with-feedbackvsunsubscribed-no-feedback
For a small team, that’s enough structure to drive serious product and messaging decisions.
Reading the numbers that matter
Once this journey has been live for a few weeks, you can start treating unsubscribe events like any other funnel.
Two simple derived metrics:
Survey completion rate
- Numerator: contacts taggedunsubscribed-with-feedback
- Denominator: contacts taggedunsubscribe-intentSave rate from unsubscribe intent
- Numerator: contacts taggedunsubscribe-saved
- Denominator: contacts taggedunsubscribe-intent
Because everything is driven by tags and attributes, you can build these views as saved segments or dashboards without extra engineering.
This is where Spreeflo’s “capture detail on every customer so you can speak to each uniquely” belief shows its teeth. You’re no longer acting on a vague story like “people say we email too much.” You’re looking at actual per-merchant data:
How often “email too frequent” appears as a reason
Whether certain app features correlate with higher save rates
Whether specific cohorts (by plan, geography, store size) are more likely to unsubscribe without feedback
For a Shopify app in the $50–$200/mo range, plugging even a few percent of churn at this edge can be worth thousands of dollars a month.
Variants and gotchas
A few variations you might consider once the core pattern is in place:
Tag-based trigger instead of Custom Event.
If your systems already apply a tag likeunsubscribe-intentvia API, you can build a parallel journey using the Added Tag trigger instead of a Custom Event trigger. The rest of the flow stays identical.Different flows per channel.
You can attach an event property likechannelor a contact attribute to indicate which email stream they’re opting out of (product tips vs billing alerts), and branch early with a Multi-way Split to adjust the messaging.
And some pitfalls to avoid:
Don’t delay the hard “unsubscribe from all” experience. That link should still work in one click. This journey is about the softer signals and surrounding context.
Don’t send multiple “before you go” nudges. One carefully written email is enough. Respect the fact that unsubscribe intent is a sign of fatigue.
Be careful with your re-enrollment settings. The trigger should allow re-entry over a contact’s lifetime, but the journey itself should be short so people don’t get stuck.
Why this earns its place in your stack
For founder-led teams building Shopify apps and e‑commerce tools, it’s tempting to think “we’ll do churn research later.” There’s always another feature to ship or integration to debug.
An unsubscribe-intent survey journey is the opposite of that mindset. You build it once, in an afternoon, in the same visual canvas you use to build a journey for onboarding or upsells. After that, it quietly:
Captures structured reasons every time someone moves to the edge of your ecosystem.
Gives a small but meaningful share of them a softer option instead of a hard exit.
Keeps your email list clean and compliant without extra manual work.
Most businesses are already leaking lifetime value at this stage; they just don’t see it because “unsubscribed” looks like a dead end. When you wire unsubscribe intent into a Spreeflo journey, it stops being a black box and becomes another optimization surface.
You don’t need a big marketing team to do this. You need a clear flow, a few well-placed events, and a tool that treats every contact as someone whose story is worth knowing.
That’s what this pattern gives you.