Stop Waiting for Enterprise Inbound: Automate the Moment Your Shopify App Should Escalate to Sales
A step-by-step Spreeflo journey for Shopify and e-commerce apps that automatically identifies expansion-ready self-serve accounts, alerts sales, and orchestrates targeted upgrade outreach the moment customers cross key usage or revenue thresholds so quiet enterprise opportunities stop slipping away.
Industry
Niche
Pattern
Loading sequence...
The first time Lina realized she’d missed a five‑figure expansion, it was because of a churn email.
She runs FulfillFlow, a Shopify ops app doing about $180k MRR, six‑person team, very self‑serve. One day a store owner wrote in to cancel: “We’ve grown to 18 staff now and need more control over permissions and reporting. Moving to an enterprise tool.”
Lina pulled the account’s history. Installed 11 months ago. Quietly added seat after seat. Upgraded once. Never opened a single marketing email about “advanced features.” No one on her team had ever looked at their usage chart.
If someone had reached out when they added the fifth or eighth teammate, that “enterprise tool” probably would have been FulfillFlow.
The sequence at the top of this page is the whole journey, end to end, that fixes this: the moment a self‑serve account crosses a usage or revenue line, Spreeflo flags it, alerts sales, and kicks off targeted outreach without anyone refreshing dashboards.
This article walks through that journey node by node, explains why it’s wired this way, and shows how to adapt it for your own Shopify or e‑commerce app.
Why “quietly big” self‑serve accounts are your leakiest revenue
If you sell an e‑commerce app through a marketplace like the Shopify App Store, your best customers rarely start as enterprise deals.
They:
Install on a single store
Add a couple of team members
Start pushing serious GMV through your app
Bump against your tier limits on seats, orders, or features
By the time they complain about pricing or ask about SSO, they’ve already been “enterprise‑shaped” for months. Every month they stay on self‑serve is lost expansion MRR.
Two numbers suffer:
Expansion‑to‑enterprise revenue: how many accounts ever make the jump.
Time‑to‑expansion: how long it takes from “big enough that sales should know” to “actually on the right plan.”
The solve is not “check Stripe export more often.” It’s wiring usage and billing data into automation so that the handoff is behavior‑driven, not calendar‑driven.
That’s exactly what this journey does using a Criteria Match trigger, a mix of Send Email and Send Internal Email, and a handful of routing nodes.
Before you build: what data this journey needs
You can’t trigger on “this account is ready for sales” if you don’t track what “ready” means.
For FulfillFlow, Lina decided that an account is expansion‑ready when:
account_seat_count≥ 5, oraccount_mrr≥ $149, andThey are still on a self‑serve plan (no sales touch yet)
In Spreeflo, those show up as contact attributes on the billing owner of the account, updated from your app using the Spreeflo API or JavaScript SDK:
account_seat_count(NUMBER)account_mrr(NUMBER)account_plan_type(TEXT, values like "self_serve", "enterprise")Optional: feature flags or usage counters (e.g.
advanced_reports_used)
If you’re already sending custom events like seat_added, subscription_upgraded, or plan_changed via web tracking and analytics, you just mirror the “current state” into these attributes whenever something changes.
Once that’s in place, the rest of the journey happens entirely inside Spreeflo.
Step 1: Criteria Match trigger that spots expansion moments
At the very top of the sequence you’ll see a Criteria Match trigger. This is the journey’s entry point.
Configuration in plain English:
Criteria:
account_plan_type is "self_serve"AND
account_seat_count greater than 4
(that’s your “5th seat” moment)OR
account_mrr greater than 149AND
Email subscription status is Subscribed
This uses Spreeflo’s full segment builder inline inside the Criteria Match trigger, so you can nest your AND/OR logic properly: for example, a top‑level AND group with a sub‑group for the “seat or revenue threshold.”
Re‑enrollment is set to false for this trigger. That choice matters:
You want the journey to run once per account when they first cross the line.
If you later bump your threshold or move them back to self‑serve for some reason, you probably want a fresh journey with its own logic, not a replay of the same one.
Because re‑enrollment is journey‑scoped, that setting guarantees the same contact won’t re‑enter this journey through this or any other trigger once they’ve completed it.
Why Criteria Match instead of Join Segment? For this pattern, the criteria are specific to this handoff. Keeping them inside the trigger keeps the canvas self‑contained. If you later reuse “High‑usage self‑serve” elsewhere, you can absolutely promote that logic to a saved segment and switch to a Join Segment trigger instead.
Step 2: Tag and timestamp the opportunity
Right after the trigger, the sequence adds two bits of metadata:
An Add Tag node
- Tags:expansion-pql, maybeself-serve-expansion
-isForceTriggercan stay off unless you have other journeys listening for Added Tag events and want them to fire even when the tag already exists.An Update Contact Attribute node
- Attribute:expansion_pql_first_seen_at(TIMESTAMP)
- Update type: Set to now
- This writes the current timestamp when the node executes.
Why bother?
Sales gets a clean definition of “product‑qualified lead” that can be filtered on in their tools.
You can build future segments and reports off “everyone who was ever an expansion PQL,” and how long it took from
expansion_pql_first_seen_atto upgrade.If they churn instead, you still know they were once high‑value, which changes the tone of win‑back messaging.
This is where one of Spreeflo’s core beliefs shows up in practice: capturing detail on every customer so you can speak to each uniquely. You’re not just noticing heavy usage; you’re recording the context in the contact record where every future journey can see it.
Step 3: Notify sales with useful context, not just a ping
Next in the sequence is a Send Internal Email node. This is the moment your human sales brain gets involved.
Configuration:
Recipient: your sales or “founder inbox” identity (e.g.
sales@fulfillflow.io)Template: a concise internal alert built with Spreeflo’s email builder
“Send only once” left on, because you don’t need multiple alerts for the same opportunity
The email body can pull in the attributes you’ve been tracking:
Account name and billing owner
Current
account_seat_countandaccount_mrrPlan type
Top feature events in the last 30 days
expansion_pql_first_seen_at
That is a much more actionable cue than “Someone signed up.” A rep can decide whether to reach out personally, invite them to a call, or just watch how they respond to the automated email that follows.
If you’re on the Professional plan and want this logged in a CRM, add a Webhook node after the internal email. Configure it to POST to your CRM’s endpoint with all contact attributes. You’re still within Spreeflo’s automation graph; you haven’t added any fragile one‑off scripts.
This is founder‑leverage in practice: once you write that internal alert template, it fires for you forever.
Step 4: Give the customer a thoughtful upgrade path via email
You could leave everything to sales at this point, but that wastes one of your highest‑intent outbound moments.
The journey instead:
Adds a Time Delay node
- Delay: 1 hourSends a customer‑facing email via a Send Email node
- From: the founder or account manager identity
- Template: “You’ve outgrown our self‑serve plan”
This keeps the sales alert and customer email from landing at the exact same minute. It also gives your team a window to cancel or tweak outreach if needed.
The copy can be personalized using attributes and AI, especially if you’re using AI variables for hyper-personalized subject lines:
Subject: “You’re at 5 seats on FulfillFlow—want higher‑volume pricing?”
Body:
Acknowledge their growth explicitly
Call out features that are locked behind higher tiers but relevant to their usage
Offer a short call link or invite them to reply
Crucially, this email is only sent once per contact (leave “Send only once” on). Even if they somehow re‑hit the criteria through data glitches, they won’t get duplicate upgrade nudges.
By the time the account owner reads that email, your sales team already has the internal alert and context. Whether the conversation starts from a reply or an outbound call, both sides are in sync.
Step 5: Branch on engagement with Check Email Activity
After the outbound email, the sequence pauses with another Time Delay node:
Delay: 3 days
Then it hits a Check Email Activity node tied to that specific upgrade email template.
Three key branches are configured:
Branch A:
clicked
Contacts who clicked any link in the email.Branch B:
opened
Contacts who opened but did not click.Else branch: everyone else (unopened, undelivered, etc.)
Each path reflects a different level of intent.
Path A: Clickers (high intent, hot opportunities)
For contacts in the clicked branch:
Add Tag node
- Tag:expansion-high-intentSend Internal Email node
- Quick “They clicked the upgrade email” note to sales with a reminder of seats/MRR.
You can stop there and let sales take over, or, after another 2‑day Time Delay, send a second, more concrete email:
“Here’s exactly what you’d get on the Growth plan vs your current plan”
Case study link tailored to their store size or vertical
Remember the pacing rule: there is always at least a 1‑day Time Delay between every pair of Send Email nodes this contact can traverse.
Path B: Opened but didn’t click (warm, needs clarity)
These contacts showed some curiosity but didn’t engage deeply.
For them, the journey might:
Add Tag:
expansion-warmTime Delay: 4 days
Send Email: a softer follow‑up focused on education rather than upgrade pressure
For example:
A short “how other 5+ seat stores use us” email
A link to your pricing breakdown or feature comparison
Sales still has the original internal alert and can decide whether to add a manual touch, but your automation continues nurturing them intelligently.
Else: No visible engagement (cool, don’t spam)
For everyone who didn’t open, the most respectful move is often restraint.
On this branch, the journey can:
Add Tag:
expansion-unresponsiveOptionally, create a Wait Condition node to see if they upgrade or downgrade on their own in the next 14 days.
No more emails for now. Your weekly or monthly product updates will still reach them; this journey’s job was to flag the moment and give them a clear path, not to nag.
Step 6: Don’t keep nudging after they expand on their own
People don’t always respond to email. Sometimes they see the pricing page, talk internally, and then just upgrade in‑app.
You don’t want those accounts sitting in “warm expansion nurture” once they’re already on an enterprise‑ish plan.
There are two simple patterns in the sequence to handle this:
A Wait Condition node
- Condition:account_plan_type is "enterprise"ORaccount_mrr greater than 299
- Timeout: 14 daysImmediately after, an If/Else node using the same condition:
- If yes: go to a “success” branch (Add Tagexpansion-won, send Internal Email “They upgraded themselves,” end journey).
- Else: proceed to any final light‑touch nudges you want.
Why both nodes? Wait Condition pauses the contact until either condition or timeout happens. The If/Else then decides what actually happened at that point.
This pattern lets you:
Avoid sending “upgrade” emails to people who have already upgraded.
Still close the loop on those who never move, updating their tags and attributes so future journeys know they were once an expansion PQL that didn’t convert.
Why this earns its retainer line item
For FulfillFlow, the first version of this journey took an afternoon to build. Two months later, Lina had numbers:
41 accounts hit the expansion criteria.
29 responded in some way (replies, clicks, or upgrades).
17 upgraded to higher tiers within 30 days.
She didn’t hire an SDR. She didn’t spend her Thursdays exporting “big accounts” from Stripe. She built a journey once in campaigns and journeys and let it run.
Three things made that work:
She captured meaningful, account‑level detail as contact attributes, then used Spreeflo’s criteria logic to define exactly who qualifies as “expansion‑ready.” That’s Brand Message #1 in action: speak uniquely to each customer based on who they actually are and how they behave.
She used automation to handle the 90% case: tagging, internal alerts, first outreach, basic routing. Humans stepped in only where their judgment added value. That’s Brand Message #2: founder‑led businesses win on leverage, not headcount.
She respected pacing and intent. High‑usage accounts got personal, contextual emails. Quiet accounts weren’t badgered; they were marked for future context.
For a Shopify or e‑commerce app operating in the $50k–$300k MRR band, that combination is often the difference between “we have some big stores” and “we have a predictable expansion motion.”
Bringing this pattern into your own app
If you have:
A clear definition of “this account is too big to be left fully self‑serve,” and
A way to push those signals into contact attributes or events
then you have everything you need to reproduce the sequence at the top of this page.
Start by wiring your product into the Spreeflo API, set up the account‑level attributes that matter for you, and sanity‑check a few real contacts in the UI. Once the data is right, the journey is mostly a matter of dragging the right nodes onto the canvas and being thoughtful about who should hear what, and when.
You’ll still close enterprise deals on calls. You’ll still answer edge‑case pricing questions in support. The difference is that the quiet, high‑usage accounts that already love your app won’t have to raise their hands before you start acting like they matter.