Never Manually Update Your CRM Again: Qualification Milestones on Autopilot
A practical guide for SaaS teams using Spreeflo to sync MQL, SQL, and won-customer milestones into their CRM via a single Journey with Criteria Match triggers, tags, attributes, and Webhooks, eliminating manual stage updates and spreadsheet hacks.
Industry
Niche
Pattern
Loading sequence...
The warmest leads in your funnel are often the ones your CRM never sees.
An agency signs up for your SEO tool, adds five sites, connects Google Search Console, checks rankings daily… and still sits in HubSpot or Pipedrive as “New trial” because nobody had time to update the stage. Multiply that by dozens of accounts and you’ve got a silent leak in your pipeline.
The sequence at the top of this page is the whole journey, end to end. It turns those invisible product signals into clean CRM stages — automatically — every time someone crosses MQL, SQL, or “won deal” thresholds.
We’ll walk through how a fictional SEO SaaS, RankFlow (a 5‑person team with Stripe + Pipedrive + a simple sales-assist motion), uses Spreeflo to push high-intent accounts into their CRM at exactly the right moments. No more spreadsheets, no more “who owns this lead?” Threads. Just one journey that quietly keeps everything in sync while the team ships product.
This is the kind of leverage founder-led teams win with: build it once, stop thinking about it.
What this journey actually does
At a high level, the journey does three things:
Watches for contacts who become:\n- Marketing Qualified Leads (MQLs)\n- Sales Qualified Leads (SQLs)\n- Won customers
Tags them and stamps a lifecycle attribute on their Spreeflo contact record.
Fires a Webhook to your CRM at each milestone, pushing contact data plus the current stage.
All three stages live in a single Journey that you build in the visual editor. Each stage is its own Criteria Match trigger with a very short path:
Criteria Match trigger → Add Tag → Update Contact Attribute → Webhook → (optional) Send Internal Email → End
Because the paths are short, a contact exits quickly, which means they can re-enter later when they hit the next milestone.
Let’s start with the one thing you must nail before you touch the canvas: the definitions.
Step 1: Decide what MQL, SQL, and “won” mean for your SEO SaaS
This pattern is useless if your criteria are fuzzy. Fortunately, SEO SaaS products expose rich behavioral signals.
For a product like RankFlow (rank tracking + content briefs), their team agreed on:
MQL (Marketing Qualified Lead)\nA trial user that looks like a serious fit, based on basic profile and early engagement.\nExample criteria:\n- Email domain is not a free provider\n- Has “agency”, “marketing”, or “SEO” in the company name or job title\n- Custom event
started_trialhas triggered at least once in the last 14 days\n- Custom eventadded_first_keywordhas triggered at least once\n- Total visits at least 3 in the last 7 daysSQL (Sales Qualified Lead)\nA lead with clear revenue potential and repeated product usage.\nExample criteria:\n- Already qualified as MQL\n-
generated_content_brieftriggered at least 2 times in the last 7 days\n-checked_rankingstriggered at least 4 times in the last 7 days\n- Page visited URL contains/pricingat least 2 times in the last 10 days\n- Team size attribute (from a form or manual enrichment) is at least 3Won deal (Customer)\nA paying account that successfully completed checkout.\nExample criteria:\n- Custom event
subscription_createdorpurchasereceived from your billing backend\n- Contact attributeplan_tieris not blank\n- Email subscription status is Subscribed
You define these as rules in Spreeflo’s segment builder, but for this journey we’ll embed the logic directly into Criteria Match triggers rather than creating separate saved segments.
A quick data note:
Frontend behaviors (
started_trial,added_first_keyword, page visits) are tracked via the Spreeflo SDK in your app.Backend events (
subscription_created,purchase) come from your billing webhook posting into the Spreeflo API.
Once those events and attributes exist, you’re ready to automate the CRM sync.
Step 2: One journey, three Criteria Match triggers
Create a new Journey called “CRM Lifecycle Sync – MQL / SQL / Won”.
This journey has three independent entry points:
Criteria Match: Becomes MQL
Criteria Match: Becomes SQL
Criteria Match: Becomes Won Customer
They don’t connect to each other on the canvas. Each is its own short arm.
That structure matters for two reasons:
You avoid the “only the first trigger ever fires” anti-pattern. Each trigger has its own role.
You can set Re-enrollment to
onfor each trigger, so a contact can pass through MQL today, SQL next week, and Won next month.
Because each arm does its work in a few seconds and then ends, the mid-journey lock is no issue: the contact is always free to re-enter via a different trigger when they qualify.
Let’s walk each arm.
Arm 1: When someone becomes MQL
Trigger: Criteria Match – MQL definition
Drag a Criteria Match trigger onto the canvas and name it “Becomes MQL”.
Configure the criteria with the same rules you wrote down earlier, using the segment builder inline:
Contact Attributes:\n- Job title contains “SEO” OR “marketing”\n- Email does not contain “@gmail.com”, “@yahoo.com”, etc.
Custom Events:\n-
started_trialtriggered at least 1 time in the last 14 days\n-added_first_keywordtriggered at least 1 time over all timeWebsite Activity:\n- Total visits at least 3 in the last 7 days
Set Re-enrollment to on. That way, if an account churns and comes back for a new trial in six months, they can qualify again.
Why Criteria Match here rather than Join Segment? Because lead scoring rules tend to evolve. Keeping the logic inline makes it easier to tweak without juggling extra segments.
Node 2: Add Tag – stamp them as MQL
Next node: Add Tag.
Tags:
mql, maybemql_from_trialif you also feed in inbound demo requests.
You can leave “Force tag trigger” off, since we don’t need downstream Added Tag triggers from this journey. The tag is mostly for filtering and reporting inside Spreeflo.
This gives you a quick way to build a “All MQLs” segment later without re-creating logic.
Node 3: Update Contact Attribute – set lifecycle stage
Then drop an Update Contact Attribute node.
Attribute: a custom text attribute such as
crm_lifecycle_stageUpdate type:
UPDATEValue:
MQL
This does two things:
It keeps Spreeflo’s view of the contact aligned with your CRM.
It gives you a single attribute to drive messaging later (for example, an onboarding journey that branches on lifecycle stage).
Remember: this node always writes the same literal value. You’re setting “MQL” here explicitly; you’re not reading anything from the event payload.
Node 4: Webhook – create/update contact in your CRM
Now the key part: the Webhook action.
Webhook is a Professional-plan feature, so it’s worth checking Spreeflo’s pricing if you’re on Free or Starter.
Configure it roughly like this:
URL: your CRM’s “create or update contact” endpoint (HubSpot, Pipedrive, Close, etc.)
Method:
POSTContact fields:\n- Either “All contact attributes” if your CRM can handle a bit of noise\n- Or “Selected specific fields” with:\n - Email, first name, last name\n - Company\n - Job title\n - Lead score attribute (if you maintain one)\n -
crm_lifecycle_stage\n - Any firmographic attributes you collect (team size, budget, etc.)
Spreeflo serializes that data as JSON in the request body. Your CRM or intermediary (e.g., an API gateway) maps those fields to properties on the contact, and uses crm_lifecycle_stage to set the pipeline stage to “MQL”.
The moment a trial user crosses your MQL threshold, your CRM gets a fresh, fully-enriched record without anyone exporting CSVs.
Optional: Internal notification
Many small teams also drop a Send Internal Email node after the Webhook for this first milestone:
Subject: “New MQL: {{ contact.company }}”
Body: include key attributes and a link to the CRM record.
That way someone on the team always has eyes on new opportunities without living in dashboards.
Arm 2: When an MQL becomes SQL
Trigger: Criteria Match – SQL definition
Add another Criteria Match trigger, “Becomes SQL”.
Example criteria for RankFlow:
Tags:\n- Contact is tagged with
mqlCustom events:\n-
generated_content_brieftriggered at least 2 times in the last 7 days\n-checked_rankingstriggered at least 4 times in the last 7 daysPage Visited:\n- URL contains
/pricingat least 2 times in the last 10 days
Again, set Re-enrollment to on. Some teams prefer SQL to be a one-time thing; if that’s your view, you can keep it off. But allowing re-entry is useful if accounts go cold then re-engage hard later.
Node 2: Add Tag – `sql`
Use Add Tag to apply sql, maybe also sales_focus.
This keeps SQLs easy to filter inside Spreeflo and lets you build “SQL but not yet Customer” segments if you want separate nurture.
Node 3: Update Contact Attribute – stage = SQL
Drop Update Contact Attribute again:
Attribute:
crm_lifecycle_stageUpdate type:
UPDATEValue:
SQL
Simple, literal, and consistent with the earlier step.
Node 4: Webhook – move them in the CRM pipeline
Configure another Webhook action, usually pointing at the same CRM endpoint.
The payload looks the same as the MQL Webhook, but crm_lifecycle_stage now equals SQL. Many CRMs can interpret that as “move this deal to the SQL column” or update a Lifecycle Stage field.
If your CRM API expects a separate “stage” field, you can support that either by:
Having your intermediary API translate
crm_lifecycle_stageinto whatever the CRM expects, orIncluding a dedicated
crm_deal_stagecontact attribute in the payload, updated by another Update Contact Attribute node before the Webhook.
RankFlow keeps it simple: one lifecycle attribute, interpreted consistently.
Optional: Route to a specific owner
This is also a natural place for a Send Internal Email to a shared “sales@” inbox, or a Webhook to a secondary system like Slack or a task manager.
Because Webhook is cheap in terms of recipient perception (no customer-facing messages), you can stack a few in a row here without worrying about pacing.
Arm 3: When a lead becomes a paying customer
The “Won” arm closes the loop between billing and CRM.
Trigger: Criteria Match – Won definition
Add a third Criteria Match trigger: “Becomes Customer (Won)”.
Criteria might be:
Custom Events:\n- Custom event
subscription_createdhas triggered at least 1 time over all time\n (this comes from your billing system posting to the Spreeflo API when Stripe or Paddle confirms payment)Contact Attributes:\n-
plan_tieris not blankEmail Subscription Status:\n- is
Subscribed
You can choose whether to allow re-enrollment here:
If you want to capture re-activations (churned → re-subscribed), set Re-enrollment to
on.If you treat “Won” as strictly first-time only, leave it
off.
Most SaaS teams prefer to know about each re-activation, so on is usually better.
Node 2: Add Tag – `customer`, `won`
Apply tags like customer, won, and maybe agency_customer vs inhouse_customer if you differentiate.
These tags are powerful inside Spreeflo for customer-only communication and cross-sell journeys.
Node 3: Update Contact Attribute – stage = Won
Again, use Update Contact Attribute:
Attribute:
crm_lifecycle_stageUpdate type:
UPDATEValue:
WON
You might also set supporting attributes here, such as:
acv_band(e.g. “<$1k”, “$1k–$5k”)onboarding_status=not_started
Those values are static literals as well, so keep them coarse-grained.
Node 4: Webhook – sync revenue context to the CRM
Final Webhook action.
Here you almost certainly want to send:
Email, name, company
crm_lifecycle_stagePlan tier
Billing period (monthly vs annual)
First payment date (if you store it as a timestamp attribute)
Seat count (if applicable)
Your CRM can either:
Create a new deal in a “Customers” or “Won” stage, or
Update an existing “SQL” deal to “Won” with the revenue attached.
Either way, no human had to notice the Stripe event and “remember to update Pipedrive later”.
Keeping re-enrollment and data hygiene sane
Three practical guardrails when you implement this:
Turn re-enrollment on for all three triggers.\nBecause each arm is short, the mid-journey lock won’t bite you, and you’ll correctly process contacts as they climb the ladder from MQL → SQL → Won, or cycle back.
Avoid overlapping criteria that cause thrashing.\nMake sure your SQL and Won definitions are strictly narrower than MQL, and that Won is clearly “post-purchase”. This prevents a contact from bouncing between stages because of slight activity changes.
Treat Spreeflo as the source of truth for behavior, not for pipeline mechanics.\nThe point of this pattern is to let Spreeflo tell the CRM “here’s what the user is doing in the product”. The CRM still owns tasks, notes, and opportunity management. That separation keeps both systems clean.
If you’re unsure how your current contact data is shaped, it’s worth skimming the overview of audiences, segments, and attributes before turning this journey on.
How to tell if it’s working
Two simple metrics tell you whether this pattern is doing its job:
Sync success rate\n- Pick a time window (e.g. last 30 days).\n- Count how many contacts met each stage’s criteria in Spreeflo (via segments on
crm_lifecycle_stage).\n- Compare to the count of contacts in each corresponding CRM stage.\nThey should be close. Any big gap means either your criteria differ between systems or your Webhook endpoint isn’t handling the payload correctly.CRM record completeness\nSample a handful of MQL, SQL, and Won records in the CRM:\n- Do they have the fields you expect (company, job title, key product signals)?\n- Are sales conversations better because of this context?
As you iterate, you may decide to add or remove fields from the Webhook payload, but the journey itself likely stays exactly the same.
The bigger win: leverage instead of admin work
There’s nothing glamorous about keeping your CRM in sync with your product data. It’s the kind of slow, administrative work founders tend to postpone — until a big agency slips through the cracks and churns because nobody reached out.
This journey is what “founder-led businesses win on leverage, not headcount” looks like in practice:
You design your definitions once.
You wire three short arms with Criteria Match + Webhook.
From then on, every MQL, SQL, and new customer quietly appears in your CRM with the context your team needs.
No RevOps hire. No brittle tangle of separate zaps to maintain. Just one clear system that respects the data Spreeflo is already collecting about each account.
When you’re ready, open your workspace, build a journey that matches the sequence at the top of this page, and let it run for a month. You’ll know it’s working the first time a “perfect fit” account hits SQL without anyone on your team touching a spreadsheet.