> ## Documentation Index
> Fetch the complete documentation index at: https://docs.os.default.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MQL to SQL: handing marketing-qualified leads to sales with Default

> How to hand a marketing-qualified lead (MQL) to sales with Default: a CRM Record Updated trigger fires when a Salesforce Lead's status or a HubSpot Contact's lifecycle stage changes to MQL, Enrich Data fills gaps, Round-Robin or Rules of Engagement picks the rep, Update Record writes the owner, and Send Slack Message tells the rep, who accepts or rejects the lead as a sales-qualified lead (SQL) in the CRM.

The MQL to SQL handoff is the step where marketing passes a qualified lead to sales and a rep
decides whether to work it. Default runs the handoff as a workflow. When a lead reaches MQL in
Salesforce or HubSpot, the workflow fills in missing data, picks a rep, writes the owner to the CRM,
and tells the rep in Slack. The rep then accepts or rejects the lead on the CRM record.

## MQL vs SQL

A marketing-qualified lead (MQL) is a lead that marketing judges ready for sales, based on fit and
engagement criteria your teams agree on, such as a demo request or a lead score above a threshold. A
sales-qualified lead (SQL) is a lead that a rep has reviewed and accepted as worth pursuing.
Marketing sets the MQL status, usually automatically, and the rep sets the SQL status in the CRM.

## The MQL handoff at a glance

| Step | Node | What it does |
| - | - | - |
| 1. Detect the MQL | **CRM Record Updated** trigger | Starts a run when a Salesforce Lead's `Lead Status`, or a HubSpot Contact's `Lifecycle Stage`, changes to your MQL value. |
| 2. Fill gaps | **Enrich Data** | Adds person and company details the record is missing, such as job title and company size. |
| 3. Pick the rep | **Round-Robin** or **Rules of Engagement** | Picks a rep from a queue, or by territory and segment rules. |
| 4. Write the owner | **Update Record** | Sets the rep as the record's owner, and optionally a handoff status. |
| 5. Tell the rep | **Send Slack Message** | Sends the rep a direct message with the lead's details. |
| 6. Start outreach (optional) | A sequencing node | Adds the lead to a sequence that sends as the rep. |
| 7. Accept or reject | The CRM record | The rep sets the SQL status, or rejects the lead. |

## Setup for the MQL handoff

| Requirement | Where | Why |
| - | - | - |
| Salesforce or HubSpot connected | **Settings** → **Integrations**. See [Salesforce](/settings/integrations/salesforce) and [HubSpot](/settings/integrations/hubspot). | The trigger watches the CRM, and **Update Record** writes to it. |
| An MQL value in the CRM | Your CRM | The trigger fires on a field value that means MQL, for example `MQL` in the Salesforce `Lead Status` picklist, or the Marketing Qualified Lead stage in HubSpot. |
| A queue with a routing policy, or a published Rules of Engagement ruleset | **Routing** → **Queues** and **Policies**. See [Queues](/queues), [Policies](/policies), and [Rules of Engagement](/rules-of-engagement). | The routing node picks the rep from it. Include **Objects** in the policy's **Assignment Units**. |
| Slack connected | **Settings** → **Integrations**. See [Slack](/settings/integrations/slack). | **Send Slack Message** needs it. |
| Each rep mapped to their CRM user and Slack user | **Settings** → **Users**: open a member and select **Integrations**, or use the **Mappings** tab. See [Users](/settings/users). | Default converts the picked rep into the CRM owner and the Slack recipient through these mappings. |
| Enrichment providers or a waterfall | **Settings** → **Integrations**, and [Waterfalls](/settings/configurations/waterfalls) | **Enrich Data** uses them. You don't need an account or API key with the provider. Default bills enrichment in credits. |

## Fire the workflow once per MQL

The **Condition** on **CRM Record Updated** checks the record as it is after each update. It has no
"changed to" operator and does not remember the previous value, so a condition on the status alone
matches every later update to that lead, including the owner this workflow writes.

| Condition | When the workflow runs |
| - | - |
| `Lead Status` **equals** `MQL` | On every update to a Lead whose status is `MQL`, such as an edited phone number or a new owner. The same lead can be routed again and again. |
| **Fields Updated** **contains any of** `Lead Status`, and `Lead Status` **equals** `MQL` | Only on an update that changes the status, and only when the new status is `MQL`. Later updates that leave the status alone start no run. |

Use the second form. In the condition builder, **Fields Updated** is the list of fields the update
changed, and the record's own fields are under **Object Fields**. Together they mean "changed to
MQL".

* **A lead that returns to MQL runs again.** A lead that leaves MQL, for example when a rep recycles
  it, and later reaches MQL again starts a new run.
* **Salesforce Leads created at MQL fire a different trigger.** A Lead created with `Lead Status`
  already set to `MQL` fires **CRM Record Created**, not **CRM Record Updated**. If forms or imports
  create Leads at MQL, build a second workflow with the same nodes that starts from
  **CRM Record Created**, with the condition `Lead Status` **equals** `MQL`.

## Build the MQL handoff workflow

This example hands every Salesforce Lead that changes to `MQL` to the next sales development rep
(SDR) in a queue named `Inbound SDRs`, writes the SDR as the owner, and sends them a Slack message.

<Steps>
  <Step title="Add the trigger">
    In **Workflows**, create a workflow and add the **CRM Record Updated** trigger. Set **CRM** to
    **Salesforce** and **Record** to **Lead**.
  </Step>

  <Step title="Fire only when the status changes to MQL">
    Under **Condition**, add 2 conditions joined with **And**: **Fields Updated** **contains any of**
    `Lead Status`, and, from **Object Fields**, `Lead Status` **equals** `MQL`.
  </Step>

  <Step title="Fill gaps with enrichment">
    Add **Enrich Data**. Set **Enrichment target** to **Both** and choose a provider or waterfall in
    **Enrichment source**. Default takes the Lead's email from the trigger, so you can leave
    **Email / Domain (optional)** empty.
  </Step>

  <Step title="Pick the rep">
    Add **Round-Robin** and set **Queue** to `Inbound SDRs`. The queue's policy picks the rep and
    passes them to later nodes as **Latest assigned user**.
  </Step>

  <Step title="Write the owner">
    Add **Update Record**. Set **Platform** to **Salesforce**, **Record Type** to **Lead**, and
    **Record to update** to the Lead's record ID from the trigger. Under **Fields**, set `Owner ID` to
    **Latest assigned user**.

    To mark the handoff, also set `Lead Status` to the value your team uses for a lead waiting on its
    rep, for example `Assigned`. That write changes the status, but not to `MQL`, so it does not
    start the workflow again.
  </Step>

  <Step title="Tell the rep">
    Add **Send Slack Message**. Set **Recipients** to **Latest assigned user**, and write a
    **Message** with the lead's name, company, and enriched details. Type `{{` to insert them. To
    keep a team record of handoffs, also pick a channel in **Slack channels**.
  </Step>

  <Step title="Add the lead to the rep's sequence (optional)">
    Add a sequencing node such as **Add to Outreach Sequence**, with **Sending mailbox** set to
    **Latest assigned user**. See
    [Send routed leads to sales sequences](/guides/routed-leads-to-sequences).
  </Step>

  <Step title="Test and publish">
    Select **Test** and choose the trigger. In the sample, fill in the `Email` and `Id` of a test
    Lead, set `Status` to `MQL`, and add `"Status"` to `fieldsUpdated`. Select **Run Test**, then
    check the owner in Salesforce and the message in Slack. Then select **Publish** and check that
    the status next to the [deployment switch](/workflows#the-deployment-switch) reads **Live**. A
    new workflow goes live when you first publish it. If the status reads **Paused**, turn the
    switch on.
  </Step>
</Steps>

<Warning>
  A test performs real actions. It updates the Lead in Salesforce, counts the routing assignment,
  sends the Slack message, and can enroll the lead in a sequence. Use a test Lead.
</Warning>

To route by territory, segment, or company size, use **Rules of Engagement** in place of
**Round-Robin** and set **Ruleset** to your published ruleset. Keep it after **Enrich Data** so the
rules can use the enriched company size. Connect **Resolved** to **Update Record**, and set
`Owner ID` and **Recipients** to **Latest resolved user**. **Resolved** can arrive without a user
when the matched queue has no active members, so check that **Latest resolved user** exists with a
**Multi-Branch** node first. Send **Else**, which runs when no rule picks an owner, to a
**Round-Robin** node on a catch-all queue, followed by its own **Update Record** and
**Send Slack Message** that use **Latest assigned user**, because **Latest resolved user** is empty
on that path. See
[What the workflow receives from Rules of Engagement](/rules-of-engagement#what-the-workflow-receives-from-rules-of-engagement).

## Salesforce and HubSpot differences

| | Salesforce | HubSpot |
| - | - | - |
| **Record** | **Lead**, or **Contact** if your MQLs live on Contacts | **Contact** |
| MQL condition | **Fields Updated** **contains any of** `Lead Status`, and `Lead Status` **equals** your MQL value | **Fields Updated** **contains any of** `Lifecycle Stage`, and `Lifecycle Stage` **equals** `marketingqualifiedlead` |
| Owner field in **Update Record** | `Owner ID` | `Contact owner` |
| How the change reaches Default | Salesforce Change Data Capture, which Default sets up when you publish. Lead uses 1 of your org's Change Data Capture object selections. See [How Salesforce changes reach Default](/settings/integrations/salesforce#how-salesforce-changes-reach-default). | Default checks HubSpot for changed records every few minutes, so a run can start a few minutes after the stage changes. See [How HubSpot changes reach Default](/settings/integrations/hubspot#how-hubspot-changes-reach-default). |
| Where SQL status lives | `Lead Status` set to your SQL value, or the Lead converted to a Contact and Opportunity | `Lifecycle Stage` set to `salesqualifiedlead` |
| Rep mapping in **Settings** → **Users** | The **User ID** field on the **Salesforce** card | The **Owner ID** field on the **HubSpot** card |

In a HubSpot condition, the value list shows HubSpot's internal names for lifecycle stages, so
Marketing Qualified Lead appears as `marketingqualifiedlead`. In a HubSpot test sample, fill in
`email` and `hs_object_id`, set `lifecyclestage`, and add `"lifecyclestage"` to `fieldsUpdated`.

## Hand off leads that reach MQL by score

Many teams set MQL when a lead score crosses a threshold. Pick the path that matches where the score
lives:

* **Your CRM keeps the score.** Build a second, small workflow on **CRM Record Updated** with 3
  conditions: **Fields Updated** **contains any of** your score field, the score **is at least**
  your threshold, for example `80`, and the status **is any of** the values before MQL, such as
  `Open - Not Contacted` in `Lead Status`, or `lead` in a HubSpot `Lifecycle Stage`. Its only node is
  **Update Record**, which sets the status to your MQL value. That status change starts the handoff
  workflow above. The status condition stops later score changes from running it again once the
  lead has moved on.
* **Marketo keeps the score.** A Marketo smart campaign calls a Default webhook when the score
  crosses your threshold, and the workflow starts from **Incoming Webhook**. See
  [Route Marketo leads when they reach a lead score threshold](/guides/marketo#route-marketo-leads-when-they-reach-a-lead-score-threshold).
* **Default computes the score.** A workflow can score or tier the lead and write the result to a
  CRM field. In that same workflow, set the MQL status with **Update Record**, or route the lead
  right away. See [Lead scoring with Default](/lead-routing/lead-scoring).

## Where the rep accepts or rejects the lead

The SQL decision lives on the CRM record, so reports on MQL to SQL conversion use your CRM's own
data. The rep accepts or rejects the lead there:

| | Accept as SQL | Reject |
| - | - | - |
| Salesforce | Set `Lead Status` to your SQL value, or convert the Lead. | Set `Lead Status` to your recycle or disqualify value, with a reason if you track one. |
| HubSpot | Set `Lifecycle Stage` to Sales Qualified Lead. | Set the contact's `Lead Status` property to `Unqualified`, or your own value. |

To act on a rejection, build another workflow on **CRM Record Updated** with **Fields Updated**
**contains any of** `Lead Status`, and `Lead Status` **equals** your rejected value. For example,
post the lead to your marketing operations channel with **Send Slack Message**, or add it to a
nurture sequence.

To follow up when the rep doesn't act, add these nodes to the end of the Salesforce handoff
workflow:

1. **Time Delay**, set to your response window, for example 4 hours.
2. **Match Record** with **CRM** set to **Salesforce** and **Record** set to **Lead**. Under
   **Match Details**, match `Lead ID` to the Lead's record ID from the trigger, so the workflow
   reads the Lead's current status.
3. **Multi-Branch** with a branch where the matched Lead's `Lead Status` still has the handoff
   value you set in **Update Record**, for example `Assigned`. On that branch, message the rep's
   manager with **Send Slack Message**, or route again with **Round-Robin** and **Update Record**.

In HubSpot, match the **Contact** instead and check the property you set in **Update Record**.

## Check that the handoff worked

* **Runs**: open the workflow, select **Runs**, and open a run. **Round-Robin** shows the rep it
  picked, **Update Record** shows the fields it wrote, and **Send Slack Message** shows who received
  the message. See [Run logs](/workflows/run-logs).
* **Assignments**: in **Routing**, select **Assignments**, then **Object assignments**, to see each
  routing decision and the scores behind it. See [Routing logs](/lead-routing/logs).
* **The CRM record**: the Lead or Contact shows the new owner, and the handoff status if you wrote
  one.

An update that does not match the **Condition** starts no run, so it leaves nothing in **Runs**. To
see which condition failed, test with a sample of that record: the test lists the failed
conditions.

## Troubleshoot the MQL handoff

| What you see | What to check |
| - | - |
| The same lead is routed again whenever it is edited | The condition checks only the status. Add **Fields Updated** **contains any of** `Lead Status`, so only a status change starts a run. |
| A Lead set to MQL starts no run | Check that the status reads **Live**. If the Lead was created at MQL, it fired **CRM Record Created** instead. See [Fire the workflow once per MQL](#fire-the-workflow-once-per-mql). |
| The test says the payload wouldn't fire the trigger | Add the status field to `fieldsUpdated` in the sample, and set the status to your MQL value. |
| **Update Record** fails because the Default user has no integration mapping | Map the rep in **Settings** → **Users**: the **User ID** field on the **Salesforce** card, or the **Owner ID** field on the **HubSpot** card. |
| The rep gets no Slack message | Map the rep's Slack **User ID** in **Settings** → **Users**. With only **Recipients** set, a missing mapping fails the node. |
| The lead is routed twice | Another workflow routes the same records, for example a **CRM Record Created** routing workflow or a Marketo webhook flow. Keep 1 workflow responsible for routing MQLs. |

Related: [Lead routing software from Default](https://www.default.com/product/lead-routing-software)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.