Back to Playbooks

Never Manually Update Your CRM Again: Qualification Milestones on Autopilot

Free

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:

  1. Watches for contacts who become:\n- Marketing Qualified Leads (MQLs)\n- Sales Qualified Leads (SQLs)\n- Won customers

  2. Tags them and stamps a lifecycle attribute on their Spreeflo contact record.

  3. 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_trial has triggered at least once in the last 14 days\n- Custom event added_first_keyword has triggered at least once\n- Total visits at least 3 in the last 7 days

  • SQL (Sales Qualified Lead)\nA lead with clear revenue potential and repeated product usage.\nExample criteria:\n- Already qualified as MQL\n- generated_content_brief triggered at least 2 times in the last 7 days\n- checked_rankings triggered at least 4 times in the last 7 days\n- Page visited URL contains /pricing at least 2 times in the last 10 days\n- Team size attribute (from a form or manual enrichment) is at least 3

  • Won deal (Customer)\nA paying account that successfully completed checkout.\nExample criteria:\n- Custom event subscription_created or purchase received from your billing backend\n- Contact attribute plan_tier is 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:

  1. You avoid the “only the first trigger ever fires” anti-pattern. Each trigger has its own role.

  2. You can set Re-enrollment to on for 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_trial triggered at least 1 time in the last 14 days\n- added_first_keyword triggered at least 1 time over all time

  • Website 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, maybe mql_from_trial if 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_stage

  • Update type: UPDATE

  • Value: MQL

This does two things:

  1. It keeps Spreeflo’s view of the contact aligned with your CRM.

  2. 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: POST

  • Contact 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 mql

  • Custom events:\n- generated_content_brief triggered at least 2 times in the last 7 days\n- checked_rankings triggered at least 4 times in the last 7 days

  • Page Visited:\n- URL contains /pricing at 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_stage

  • Update type: UPDATE

  • Value: 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_stage into whatever the CRM expects, or

  • Including a dedicated crm_deal_stage contact 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_created has 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_tier is not blank

  • Email 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_stage

  • Update type: UPDATE

  • Value: 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_stage

  • Plan 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:

  1. 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.

  2. 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.

  3. 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:

  1. 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.

  2. 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.