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

# Preventing and finding duplicate CRM records in Default

> How Default keeps workflows from creating duplicate Salesforce and HubSpot records, how it lists the duplicates you already have, and why merging stays in your CRM.

Default helps with duplicate CRM records at 2 points: its workflows check Salesforce or HubSpot for an
existing record before they create one, and its MCP server can list the duplicates already in your CRM.
Default does not merge records. When 2 records need to become 1, you merge them in Salesforce or
HubSpot.

Duplicate handling is part of CRM hygiene. The other part, filling empty fields on existing records,
is covered in [Backfilling missing CRM fields](/enrichment/backfill).

## What Default does with duplicate CRM records

| Capability | In Default | Where |
| - | - | - |
| Find an existing record before creating one | Yes, Salesforce and HubSpot | [**Match Record**](#check-for-an-existing-record-with-match-record) node |
| Update a record instead of creating a duplicate | Salesforce only | [**Update on conflict**](#update-on-conflict-in-salesforce) on **Create Record** |
| Keep going when the CRM rejects a duplicate | Yes, Salesforce and HubSpot | [**Create Record**](#when-the-crm-rejects-a-duplicate) |
| Convert a Salesforce lead into an existing account and contact | Yes | [**Convert Lead**](#convert-a-lead-into-an-existing-account-and-contact) node |
| Check a list against your CRM before you act on it | Yes, in Tables (beta) | [**Match to CRM**](#check-a-list-against-your-crm-in-tables) |
| List duplicates already in your CRM | Yes, read only | [`crm_duplicates_scan`](#find-existing-duplicates-with-the-mcp-server) on the MCP server (beta) |
| Merge duplicate records into 1 | No | [Merge in Salesforce or HubSpot](#merge-duplicates-in-your-crm) |

## Check for an existing record with Match Record

The **Match Record** node searches Salesforce or HubSpot and follows 1 of 2 branches: **Match** when it
finds a record, **No Match** when it does not. Create records only on the **No Match** branch, so a
lead that the match finds is not created again.

| Field | What it does |
| - | - |
| **CRM** | **Salesforce** or **HubSpot**. |
| **Record** | The object to search, for example **Contact**, **Lead**, **Account**, or **Company**. |
| **Match Details** | The conditions a record must meet, for example email equals the submitted email. |
| **Prioritize matched records by** | Rules, applied in order, that pick 1 record when several match. |

Common checks before a create:

* **People in Salesforce.** Match a **Contact** by email first. On its **No Match** branch, match a
  **Lead** by email. Create a Lead only when both find nothing.
* **People in HubSpot.** Match a **Contact** by email, and create on **No Match**.
* **Companies.** Match an **Account** or **Company** on its website with the **domain matches**
  operator, which compares company domains instead of raw text. `https://www.acme.com/pricing` and
  `acme.com` then count as the same company. See
  [Match an account by company domain](/workflows/steps-crm#match-an-account-by-company-domain).

On the **Match** branch, later nodes can use the matched record's ID and fields, for example to update
it or to route it to its current owner. See [CRM nodes](/workflows/steps-crm#match-record).

## Update on conflict in Salesforce

For Salesforce, **Create Record** can find and update a record instead of creating a new one. Turn on
**Update on conflict** and choose a **Match field**, a Salesforce field that identifies the record, for
example email. The match field must also have a value in **Mapped Fields**.

| Records with that match field value | What Create Record does |
| - | - |
| 0 | Creates a new record. |
| 1 | Updates that record with the mapped fields. |
| 2 or more | Stops with an error that several records match, and changes nothing. |

On a match, every mapped field is written to the existing record, including the owner if you map it.
To give new records an owner without reassigning existing ones, use **Match Record** instead and set
the owner only on the **No Match** branch.

HubSpot's **Create Record** has no **Update on conflict**. Use **Match Record** first.

## When the CRM rejects a duplicate

Salesforce duplicate rules and unique fields can reject a new record, and so can a HubSpot property
that must be unique. When that happens, **Create Record** does not treat it as a failed run:

* It creates nothing and writes none of the mapped fields.
* It logs a warning, either that the record already exists and the workflow continues with it, or that
  creation was skipped.
* When the CRM reports which record already exists, Default passes that record to later nodes, so they
  can still use its ID and fields.
* It marks the step as errored in the run log, and the rest of the workflow runs.

## Convert a lead into an existing account and contact

The **Convert Lead** node converts a Salesforce Lead. To avoid creating a second account or contact
during conversion, set:

* **Account to merge into (optional)**: an existing Account ID, usually from a **Match Record** node.
* **Contact to merge into (optional)**: an existing Contact ID.

The lead then converts into those records instead of new ones. This is Salesforce lead conversion. It
does not merge 2 existing accounts or contacts.

If a Salesforce duplicate rule refuses the conversion, the step fails with a message that names the
matching record. See [Convert lead](/workflows/steps-crm#convert-lead).

## Check a list against your CRM in Tables

<Note>
  **Tables is in beta.** It is turned on per workspace. If you do not see **Companies** and **People**
  under **Views** in the sidebar, contact Default.
</Note>

The **Match to CRM** action in Tables looks up each row of a view in Salesforce or HubSpot, for example
a list you uploaded as a CSV:

1. Open the view and select **Actions**, then **Match to CRM**.
2. Choose the CRM, the record type, the CRM field to compare, and **Exact match** or **Contains**.
3. Choose the row field to compare it with, for example the email column.
4. Select **Match**, followed by the number of records, for example **Match 100 records**. Each row
   then shows **Matched** with the CRM record ID, or **No match**.

1 run covers up to 250 records.

## Find existing duplicates with the MCP server

Default's [MCP server](/mcp-server) has a read-only tool, `crm_duplicates_scan`, that lists duplicate
records already in your CRM. Ask a connected AI client, such as Claude or Cursor, a question like
"Scan my CRM for duplicate contacts."

What the scan checks:

| Scan | Groups records that share | Records it covers |
| - | - | - |
| Contacts | The same email address | Salesforce Contacts and Leads, and HubSpot contacts |
| Companies | The same domain | Salesforce Accounts and HubSpot companies |

Each group lists the CRM record IDs, which CRM each record is in, and when Default last saw it. Because
Salesforce Contacts and Leads are scanned together, a Lead that duplicates an existing Contact shows up
as a group.

What to know before you act on the results:

* **Exact matches only.** The same person under 2 different emails does not show up.
* **Personal email domains are flagged.** Groups on personal email domains, such as `gmail.com`, are
  marked, because they often hold junk data.
* **Shared inboxes can appear.** Addresses such as `info@` or `sales@` can group unrelated contacts.
* **Groups can span CRMs.** A group can hold a Salesforce record and a HubSpot record. That is useful
  hygiene signal, but the 2 records cannot be merged with each other.
* **It changes nothing.** The scan only reads.
* **It covers the records Default has seen.** The scan reads Default's identity graph, which links
  CRM record IDs to the emails and domains Default has seen through your CRM connection.

Use `identity_resolve` to look up everything Default links to 1 email or domain in a group.

The scan needs the **admin** or **owner** role and belongs to the identity tools, which Default turns on
per workspace. See [Identity graph](/mcp-server#identity-graph).

## Merge duplicates in your CRM

Default does not merge Salesforce or HubSpot records, and no Default workflow node or tool combines 2
records into 1. To clean up duplicates:

1. List them with `crm_duplicates_scan`.
2. Merge each group in Salesforce or HubSpot, using the record IDs from the scan.
3. Stop new duplicates at the source with **Match Record** before every **Create Record**, and with
   **Update on conflict** in Salesforce.

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


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