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

# Salesforce lead-to-account matching in Default

> How Default matches Salesforce leads to existing accounts: the Match Record node, matching by company domain, tiebreakers when several accounts match, the No Match branch, and converting the lead into the matched account.

Default matches Salesforce leads to accounts inside a workflow. A **Match Record** node searches your
Salesforce Accounts for the lead's company, usually by comparing each Account's **Website** with the
domain of the lead's email, then follows its **Match** or **No Match** branch. Later nodes use the
matched Account to route the lead to the account owner, show the owner's calendar, or merge the lead
into that Account with **Convert Lead**.

Matching is built from workflow nodes, so each rule can be tested and each decision shows in the run
logs. The nodes are documented in [CRM nodes](/workflows/steps-crm). For a signal that names a company
but no person, such as a website visit, see
[Salesforce account and HubSpot company matching](/lead-routing/matching/accounts-and-companies).

## How lead-to-account matching works in Default

A lead-to-account workflow in Default runs these steps:

1. **A trigger starts the run with the lead.** Use **CRM Record Created** on the Salesforce **Lead**
   for leads that already exist in Salesforce, or **Form Submission**, **API**, or **Incoming Webhook**
   for leads that arrive with form or request data. See [Triggers](/workflows/triggers).
2. **Match Record searches Accounts.** Set **Record** to **Account**. The conditions under
   **Match Details** decide which Accounts count as the lead's company.
3. **Tiebreakers pick 1 Account.** When several Accounts match, the rules under
   **Prioritize matched records by** choose 1 of them.
4. **The node branches.** **Match** carries the chosen Account's ID and fields to later nodes.
   **No Match** runs when no Account qualifies.
5. **Later nodes act on the result.** On **Match**, route the lead to the account owner or convert it
   into the Account. On **No Match**, route the lead through a queue.

## Match options for Salesforce accounts

**Match Details** compares Account fields with values from the trigger or earlier nodes. It lists the
Account fields that Salesforce lets you filter on, including custom fields. Combine conditions with
**and** or **or**.

| Match on | Condition in **Match Details** | When to use it |
| - | - | - |
| Company domain from the lead's email | **Website** **domain matches** the lead's email, with **Domain from email** chosen in the value picker | The standard choice for inbound leads. It ignores `https://`, `www.`, paths and subdomains, and never matches a public email provider such as `gmail.com`. See [Match an account by company domain](/workflows/steps-crm#match-an-account-by-company-domain). |
| Company domain from enrichment | **Website** **domain matches** the company domain an enrichment node returned | The lead used a personal email, and an [enrichment node](/workflows/steps-enrichment) found the company. |
| A custom domain field | Your custom domain field **domain matches** the lead's domain, joined to the **Website** condition with **or** | Your Accounts store domains in more than 1 field. |
| Company name | **Account Name** **equals** the lead's **Company** | A fallback only. Names are spelled differently across records, so a domain is more reliable. |
| A known Account ID | **Account ID** **equals** an ID from the trigger or an earlier node | The form or API call already passes a Salesforce Account ID. |
| The Account owner | **Owner ID** **equals** a queue, shown as **Queue:** and the queue name, or **All Salesforce users** | Limit matches to Accounts owned by members of a Default queue, or to Accounts owned by a Salesforce user instead of a Salesforce queue. |

**Match Details** needs at least 1 condition before the workflow can be published.

<Tip>
  Use **domain matches** instead of **contains string** on **Website**. **contains string** compares
  raw text, so `hp.com` also matches `companyhp.com`, and a lead from `eu.hp.com` misses a website
  stored as `https://www.hp.com`.
</Tip>

## When several Salesforce accounts match

A company often has several Accounts, for example a parent and its subsidiaries, or duplicates
created by different teams. **Prioritize matched records by** decides which one the workflow uses.
It is optional. Select **Add tiebreaker** to add a rule:

| Tiebreaker | Where to find it | What it does |
| - | - | - |
| **Most recently modified** | **Suggested** | Prefers the Account with the latest **Last Modified Date**. |
| **Newest created** | **Suggested** | Prefers the most recently created Account. |
| **Oldest created** | **Suggested** | Prefers the first Account created, often the original record. |
| **Largest by employees** | **Suggested** | Prefers the Account with the highest **Employees** value. |
| **Has a parent account** | **Suggested** | Prefers Accounts that have a **Parent Account ID**. |
| **Sort by a field…** | **Advanced** | Sorts by any date or number field. Date fields sort **Newest** or **Oldest**. Number fields sort **Highest** or **Lowest**. |
| **Prefer records where…** | **Advanced** | Prefers the matched Accounts that meet the conditions you set. |

How Default applies the rules:

* **Only when 2 or more Accounts match.** When exactly 1 Account matches, the node uses it and runs
  no rule. Put a hard requirement, such as the Account owner, in **Match Details** instead.
* **In order, top to bottom.** Drag a rule to reorder it. A sort rule directly below another sort
  rule breaks its ties. Empty values sort last.
* **Filter rules narrow the list but never empty it.** **Has a parent account** and
  **Prefer records where…** keep only the Accounts that meet them. When none of the remaining
  Accounts meets a filter rule, Default skips that rule, keeps the Accounts for the next rules, and
  adds a warning to the run log. Tiebreakers never send the node to **No Match**.
* **Without rules, the first result wins.** Default takes the first Account Salesforce returns, and
  that order is not defined. Add at least 1 rule whenever more than 1 Account can match.
* **Rules see a limited window.** When Default sorts or filters the matches itself, it reads a
  limited number of matching Accounts. If that limit is reached, the run log shows a warning with the
  query limit, and better matches beyond it are skipped. Narrow **Match Details** so fewer Accounts
  match.

For example, add **Largest by employees** and then **Most recently modified**. The lead goes to the
largest Account for its domain, and the most recently updated Account wins a tie.

To send leads only to Accounts owned by a current rep, add **Owner ID** **equals** a queue of your
account executives to **Match Details**, joined to the **Website** condition with **and**. Accounts
owned by anyone else never match, so those leads follow **No Match** and go to round robin.

## When no Salesforce account matches

The node follows **No Match** in these cases:

| Case | What happens |
| - | - |
| No Account has the lead's company domain | The search returns nothing. |
| The lead's email uses a public email provider, such as `gmail.com` | **domain matches** is false for every Account, so Default does not guess a company. |
| A value in **Match Details** is empty for this lead, for example a form submitted without an email | Default does not search. The run log shows a warning that the match conditions could not be built because upstream data was missing. When the empty value is in a condition joined with **or**, Default drops that condition and searches with the others, so the node can still follow **Match** with no warning. |

Give **No Match** its own path. Route the lead through a [queue](/queues) with a **Round-Robin** node,
send it to an [enrichment node](/workflows/steps-enrichment) to find the company first, or both.

## Build a Salesforce lead-to-account workflow

This example sends each new inbound Salesforce Lead to the owner of its company's Account. Leads
without a matching Account go to the next member of a queue named `Inbound Leads`.

<Steps>
  <Step title="Add the trigger">
    In **Workflows**, create a workflow and add the **CRM Record Created** trigger. Set **CRM** to
    **Salesforce** and **Record** to **Lead**. Optionally, add a **Condition**, for example
    `Lead Source` is `Inbound`.
  </Step>

  <Step title="Add Match Record for the Account">
    Select **Add Node** and choose **Match Record** from the **Records** section. Set **CRM** to
    **Salesforce** and **Record** to **Account**.

    Under **Match Details**, select **Edit**. Choose **Website** as the field and **domain matches**
    as the operator. For the value, pick the Lead's **Email** from the trigger and choose
    **Domain from email**. Select **Save changes**.
  </Step>

  <Step title="Add tiebreakers">
    Under **Prioritize matched records by**, select **Add tiebreaker** and choose
    **Largest by employees**. Add a second tiebreaker, **Most recently modified**.
  </Step>

  <Step title="Route matched leads to the account owner">
    On the **Match** branch, add **Update Record**. Set **Platform** to **Salesforce** and
    **Record Type** to **Lead**. For **Record to update**, choose the Lead's record ID from the
    trigger.

    Under **Fields**, add **Owner ID**. For its value, open the data picker and choose the Account's
    **Owner ID** from the **Match Record** step.
  </Step>

  <Step title="Round-robin the rest">
    On the **No Match** branch, add **Round-Robin** from the **Actions** section and set **Queue** to
    `Inbound Leads`. Then add **Update Record** for the Lead and set **Owner ID** to
    **Latest assigned user** under **Round robin**.
  </Step>

  <Step title="Test and publish">
    Select **Test**, choose the trigger, and fill in a sample Lead whose email domain belongs to an
    existing Account. Select **Run Test** and check the Lead owner in Salesforce. 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 workflow test performs real actions in Salesforce. Use a test Lead.
</Warning>

An owner copied from the Account does not count toward any queue's round robin. Only an owner that
comes from a **Round-Robin** node counts as a queue assignment.

For a lead that arrives from a form, check for an existing Lead or Contact first, so a repeat form
fill does not create a duplicate. See [Salesforce contact matching](/lead-routing/matching/salesforce-contacts).

To book the lead with the account owner, add **Display Scheduler** on the **Match** branch. Turn off
**Use event hosts** and add the Account's **Owner ID** from the **Match Record** step as the host. The
owner needs a Salesforce mapping in [**Settings → Users**](/settings/users) so Default can find their
calendar. See [Routing and scheduling nodes](/workflows/steps-routing-scheduling#display-scheduler).

## Convert a matched lead into the existing account

**Convert Lead** turns a Salesforce Lead into a Contact under an Account. Set
**Account to merge into (optional)** to the matched Account, and Salesforce adds the new Contact to
that Account instead of creating a second Account for the same company.

Add **Convert Lead** after the **Match** branch of the Account **Match Record** node:

| Field | Value for a merge into the matched Account |
| - | - |
| **Lead to convert** | The Lead's record ID from the trigger. |
| **Account to merge into (optional)** | The Account's ID from the **Match Record** step. |
| **Contact to merge into (optional)** | Leave empty to create a new Contact. To merge into a Contact that already exists, see [Salesforce contact matching](/lead-routing/matching/salesforce-contacts#merge-a-duplicate-lead-into-the-existing-contact). |
| **Connect Converted Lead to Opportunity** | **None**, or **New** with an **Opportunity name** when every converted lead starts a deal. |
| **Owner (Optional)** | Leave empty when you merge into an existing Account. Default sends an owner to Salesforce only when this field is set. |
| **Override LeadSource field** | Leave off to keep the source values already on the Account and Contact. |
| **Send notification E-Mail** | Turn on only when the owner must receive Salesforce's conversion email. |

What to know before you convert:

* **Salesforce only.** **Convert Lead** works on Salesforce Leads and has no HubSpot version.
* **Converted status.** Default uses the first converted lead status in your Salesforce organization,
  by sort order.
* **Already converted.** If the Lead is already converted, the node returns its existing Account,
  Contact, and Opportunity IDs and continues without converting again.
* **Outputs.** Later nodes can use the Lead, Account, Contact, and Opportunity IDs.
* **Author Apex.** Default converts leads through Apex, so the Salesforce user connected to Default
  needs the **Author Apex** permission.
* **Duplicate rules apply.** A duplicate rule set to block stops the conversion, and the node fails.
  A rule set to allow with an alert lets it through.
* **Permanent.** Salesforce cannot undo a lead conversion. Test with a test Lead.

## Check a Salesforce lead-to-account match

Open the workflow, select **Runs** at the top, and select a run. In the run details, the
**Match Record** step shows its conditions, how many Accounts Salesforce returned, and the Account it
chose. When
**domain matches** dropped a lookalike domain, the step also shows how many candidates survived. See
[Run logs](/workflows/run-logs).

## Troubleshoot Salesforce lead-to-account matching

| What you see | What to check |
| - | - |
| Leads follow **No Match** although the Account exists | Check the Account's **Website** value and the lead's email domain. A personal email address never matches. Check the other conditions in **Match Details**. |
| The wrong Account is chosen | Add or reorder tiebreakers under **Prioritize matched records by**. Without them, the first Account Salesforce returns wins. |
| The run log warns that a Prefer rule matched none of the remaining candidates and was skipped | None of the matched Accounts met that filter rule, so the next rules chose the Account. Fix the rule's condition, or move it to **Match Details** when it is a hard requirement. |
| The run log warns that the query limit was reached | More Accounts matched than Default reads for the tiebreakers. Add conditions to **Match Details** so fewer Accounts match. |
| The run log says the match conditions could not be built because upstream data was missing | The value used in **Match Details** was empty for this run, for example a missing email. |
| **Convert Lead** fails because the connected user needs the **Author Apex** permission | Give the Salesforce user connected to Default the **Author Apex** permission. |
| **Convert Lead** fails because Salesforce refused the conversion as a duplicate | Set **Account to merge into (optional)** or **Contact to merge into (optional)** to the existing record, or review the Salesforce duplicate rule. |
| **Convert Lead** fails because no converted lead status is configured | Add a lead status marked as converted in Salesforce. |

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.