Back to Playbooks

The “Composite Intent” Playbook For Shopify Apps: Stop Guessing When To Hand Off To Sales

Free

Walks through a composite-intent journey for Shopify apps in Spreeflo, using a fictional CartWizard example to show how to combine product, web, and email signals into a single trigger that drives precise sales handoffs and higher conversion.

Industry

Niche

Pattern

Loading sequence...

The install looked perfect on paper.

They found you in the Shopify App Store. Installed. Clicked through your onboarding tour. Even poked around the pricing page.

Your Slack lit up with “New install! 🎉” (your only allowed emoji, obviously). You sent a quick “Hey, if you ever want to chat…” email.

Three weeks later, they quietly uninstall.

Nothing “broke.” They just never activated deeply enough to feel the value, and no one on your team knew when to jump in with a real conversation.

For e‑commerce app developers, this is the most painful missed opportunity: not the leads that never show up, but the ones who do all the right little things… and then slip away because no human ever tapped them on the shoulder at the right moment.

The sequence at the top of this page is the whole journey, end to end. It turns a messy trail of weak signals into one clean, composite intent score and a precise sales or success handoff.

We’ll walk the journey node by node, using a fictional Shopify app to make things concrete, and show you how to tune this pattern for your own product.

The fictional app we’re optimizing

Meet CartWizard, a cart recovery and upsell app for Shopify merchants:

  • $90k MRR, 3,000 active stores

  • Pricing: $29 / $79 / $149 plans

  • Stack: Shopify, Stripe, a simple internal admin, and a marketing setup with Spreeflo for automation plus Google Analytics

Most installs are self‑serve. But a subset of merchants have meaningful budgets and complex setups — the kind where a 20‑minute call reliably turns into $149/mo plus expansion later.

CartWizard’s problem isn’t traffic or installs. It’s catching those high‑intent merchants at the right time, without sending the team 50 “maybe?” alerts a day.

So they adopt a “composite buying signal” model: instead of reacting to any single behavior, they score behavior across web, email, and product usage, then alert sales/success only when a threshold is passed within a short window.

That’s exactly what the journey you see at the top of this page does.

Why this pattern belongs in every founder’s toolkit

Before we dive into the nodes, it’s worth seeing what this journey is trying to fix:

  • A pricing‑page visit alone is noisy. Some visitors are window‑shopping, some are your competitors, some bounced after 10 seconds.

  • A feature usage event is promising, but without context, it doesn’t scream “call me”.

  • An email click could be curiosity, not buying intent.

The magic happens when you combine them into a time‑boxed, multi‑signal pattern:

“Visited /pricing at least twice in 7 days”
+ “Clicked any pricing or upgrade CTA email in the last 7 days”
+ “Triggered high‑value feature events (e.g., automation_created, revenue_generated) at least twice in that same week”

When those line up for the same contact, odds are high you want a human to step in.

This is also where Spreeflo’s philosophy shines: capture detail on every customer so you can speak to each uniquely. You’re no longer broadcasting “Need help?” to your whole install base. You’re tapping the shoulder of people whose behavior actually says “I’m ready to talk.”

Let’s see how the journey turns that into automation.

Step 1: Criteria Match trigger – defining “composite intent”

We start with a single trigger: a Criteria Match journey trigger.

We follow the default design: one trigger, isReEnrollment=false, so each contact flows through once when they first hit your composite threshold.

Inside that trigger, CartWizard defines their intent criteria using the same segment builder you use for segments:

Group 1 (web behavior):

  • Page Visited → URL contains /pricing
    Operator: at least 2 times
    Time window: in the last 7 days

Group 2 (email behavior):

  • Email Activity → clicked
    Frequency: at least 1 time
    Time window: in the last 7 days
    (optionally filter to marketing emails that contain “upgrade” in the subject)

Group 3 (product usage – via Custom Events):

  • Custom event automation_created → at least 1 time in last 7 days

  • OR

  • Custom event revenue_generated → at least 1 time in last 7 days

Then they wrap it all as:

(Visited pricing criteria) AND (Email click criteria) AND (Feature usage criteria)

Why Criteria Match instead of Join Segment:

  • This logic is specific to this journey. It doesn’t need to be a reusable segment yet.

  • Keeping it inline makes it easy to tweak the score without editing multiple segments.

Why isReEnrollment=false?

  • The journey is about the first big composite signal. Once your team knows this merchant is hot, you don’t need to keep re‑alerting them every week.

  • If you do want recurrent alerts, you’d flip it to true and add internal throttling later in the flow.

This trigger fires the moment a contact newly matches the criteria, then moves them into the main path.

Step 2: Initial Time Delay – debounce the chaos

Right after the trigger, the journey uses a Time Delay node:

  • Time Delay: 1 hour, unit: hour

Reasoning:

  • Composite criteria can sometimes be hit in a “burst” (click email, immediately hit pricing, then trigger feature usage). If your sales rep gets an alert 10 seconds after install, they have no context.

  • A short delay gives the user time to stabilize their session and lets more data arrive (e.g., revenue events that lag a few minutes behind the UI).

Choosing differently:

  • No delay: you risk alerts that feel premature or noisy. Reps start ignoring them.

  • Long delay (24+ hours): you miss the “I’m in the product and curious right now” window that makes outreach feel natural.

One hour is a practical middle ground. Adjust based on your typical interaction patterns.

Step 3: Add Tag – mark the contact for future segments

Next, CartWizard uses an Add Tag node:

  • Add Tag: intent-high, watched-by-sales

  • Force tag trigger: off

Why tag here:

  • Tags give you a simple way to build future segments like “all high‑intent users last 90 days” without re‑creating the multi‑condition logic.

  • You can also build downstream journeys triggered by this tag (e.g., an account‑based nurture series) if you want later.

Why not force the tag trigger:

  • At this stage, you assume this is the first time they’ve been tagged as high‑intent. If someone manually added the tag already, you don’t want to re‑fire any Added Tag triggers unnecessarily.

Step 4: Wait Condition – did they self‑convert?

Now comes one of the most important pieces: a Wait Condition node.

Configuration:

  • Condition: custom event subscription_upgraded triggered at least 1 time in the last 24 hours

  • Timeout: 1 day

This tells Spreeflo:

“Pause here. If this contact upgrades their plan within 24 hours of hitting the intent threshold, let them move forward as ‘converted’. Otherwise, treat them as ‘high‑intent but unconverted’.”

Why not just alert sales immediately?

Because many high‑intent users will self‑serve within a day. You don’t want a rep chasing someone who upgraded 30 minutes ago. That burns trust and wastes time.

The Wait Condition:

  • Automatically moves converted users along once the event fires (no fixed delay needed).

  • Falls back to the timeout (1 day) for those who don’t upgrade, so they don’t get stuck.

This is a classic example of founder‑led leverage: your team doesn’t have to watch dashboards all day. The system waits and routes for you.

Step 5: If/Else branch – split converted vs. not converted

Once the Wait Condition completes (via event or timeout), the journey uses an If/Else process node.

Condition:

  • Contact is member of segment “Paying customers”

  • OR

  • Custom event subscription_upgraded triggered at least 1 time over all time

Branching:

  • Yes branch: “Converted during window”

  • Else branch: “High‑intent, not yet converted”

Why this split:

  • Converted users need a different kind of human touch: onboarding support, integration advice, and expansion opportunities.

  • Non‑converted high‑intent users are prime for a light, helpful sales follow‑up focused on clarifying value or handling objections.

Without this branch, your team gets a generic alert that doesn’t match the context.

Step 6A: Converted branch – internal context + gentle check‑in

On the “Yes / converted” branch, CartWizard chains:

  1. Send Internal Email

  2. Add Tag

  3. Optional Webhook

Send Internal Email configuration:

  • Template: “High‑intent merchant converted – onboarding needed”

  • To: sales@company or a shared Slack‑to‑email channel

  • Send only once: on

Email content pulls contact details and behavior:

  • Plan chosen

  • Total revenue generated in trial

  • Pages visited (pricing, docs)

  • Last 3 custom events (automation_created, revenue_generated, etc.)

This is where Spreeflo’s email builder is handy: you can include dynamic fields so the rep doesn’t need to query your database manually.

Why internal email versus task in a CRM?

  • Most small teams don’t have a heavy CRM stack. Email is the common denominator.

  • If you do have a CRM, you can add a Webhook node next to push the payload into your own system.

Add Tag:

  • Add Tag: intent-converted, needs-onboarding

  • Force tag trigger: off

Webhook (optional, Pro plan):

  • Webhook → your internal endpoint

  • Data: key contact attributes plus a simple “intent_score = 100” so your side knows this was a max‑intent event.

The result: your team gets a clear signal with context, and your internal tools stay in sync, without anyone refreshing an analytics dashboard.

Step 6B: Not‑converted branch – precise, human outreach

On the “Else / not converted” branch, the journey is similar but tuned for conversion:

  1. Send Internal Email

  2. Add Tag

  3. Time Delay

  4. Send Email (optional nurture)

Internal email template:

  • “High‑intent trial needs follow‑up – didn’t upgrade yet”

  • Include:

  • Install date and days since install

  • Plan they’re currently on (trial/free)

  • Key behaviors: visits to pricing, features used, any payment_failed events

  • A quick “Suggested outreach angle” paragraph (you can draft this with AI personalization tools referencing their use case, if you store it as an attribute)

This gives your founder or rep exactly what they need for a short, relevant Loom or email.

Add Tag:

  • Add Tag: intent-high-open, sales-followed-up

  • Force tag trigger: off

Time Delay:

  • 2 days, unit: days

Why a delay before marketing follow‑up:

  • Give your human outreach time to land first.

  • If a rep books a call, you probably don’t want a generic “Still thinking?” campaign going out in parallel.

After 2 days, if there’s still no upgrade event, CartWizard sends a single automated email:

Send Email:

  • Template: “Is CartWizard the right fit for your store?”

  • Send only once: on

Content is consultative: “Based on what you’ve set up so far (X, Y, Z), here’s who usually sees results. If that’s not you, reply and we’ll be honest if we’re not a fit.”

Because this email is scoped only to people who passed your composite intent filter, it avoids the generic “are you still interested?” spam your audience is used to ignoring.

Optional: tighten or relax your composite criteria

What if the alerts are still noisy? Or too rare?

This pattern is easy to tune by editing the Criteria Match trigger:

To tighten (fewer, higher‑precision alerts):

  • Increase counts:
    - Pricing visits: from 2 → 3+
    - Feature events: from 1 → 3+ in 7 days

  • Add time‑on‑site conditions:
    - Time on site > 300 seconds in last 7 days

  • Restrict email activity:
    - Email clicked at least 2 times, or only specific “upgrade” campaigns

To relax (more alerts, better coverage):

  • Reduce counts:
    - Pricing visits: 1+ in last 7 days

  • Remove email requirement for certain segments:
    - E.g., if they’re on a higher‑traffic plan segment

Because all this is in the same criteria group, you don’t need to re‑wire the journey. You simply adjust rules in one place.

If you find a stable definition that works everywhere, you can future‑proof it by turning it into a saved segment and using a Join Segment trigger instead, while the rest of the flow stays identical.

Why this earns its own “retainer line item” in your stack

Most e‑commerce apps already send welcome flows and broadcast newsletters. Those are table stakes.

What moves the revenue needle for a small team is the stuff that feels “too advanced” for your current stage — like intent scoring and human‑in‑the‑loop outreach. The irony is that with the right journey builder, it’s not advanced at all. It’s a two‑page criteria config and a handful of nodes.

This pattern pays for itself because:

  • It compresses your sales attention onto the subset of users that actually look ready to buy.

  • It gives each rep a richer picture of the contact’s behavior than they’d ever assemble manually.

  • It’s adaptable: edit criteria, thresholds, tags, and handoff rules without writing code.

More importantly, it perfectly fits the core truth for founder‑led SaaS: you win on leverage, not headcount. You design this once; Spreeflo watches every install, every page view, every email click, every feature use, and pings you only when the puzzle pieces fit.

Metrics and next steps: what to watch once it’s live

When you ship this journey, track two headline metrics:

  1. Composite‑score conversion rate
    Of all contacts who enter this journey, what percentage become paying customers within 30 days?

  2. Alert precision (qualitative)
    Ask your team weekly: “Are these alerts usually worth our time?” Your goal is “yes, most of them.”

If conversion is low and reps say alerts feel weak, tighten your criteria.

If conversion is high but volume is tiny, relax them slightly so more promising users get into the flow.

Over time, you can get fancy (intent tiers, different branches per plan size, adding web push to warm people earlier). But don’t overcomplicate your v1.

Start with one clean composite definition, one clear internal email, and one or two follow‑up branches. Let it run. Then refine based on the behavior you actually see in your audiences and segments.

The big shift is this: instead of hoping someone on your team “notices” when a merchant is leaning in, you’ve made that a system job. The system is tireless, consistent, and wired directly into the same data your app is already emitting via the Spreeflo API.

You’re still doing founder‑led sales. You’re just not doing founder‑led tab‑watching anymore.