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

# HubSpot contact-to-company matching in Default

> How Default finds the HubSpot company for a contact: Match Record on property values such as the company domain, Match by association from a contact an earlier step found, tiebreakers, the No Match branch, and Create Association.

Default matches HubSpot contacts to companies inside a workflow. A **Match Record** node finds the
Company either by property values, such as the **Company Domain Name** compared with the domain of
the contact's email, or with **Match by association**, which looks up the companies already
associated with a contact an earlier step found. **Create Association** then links a contact to the
company it matched.

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). To find or create the contact
first, see [HubSpot contact matching](/lead-routing/matching/hubspot-contacts). For a signal that names
a company but no person, see
[Salesforce account and HubSpot company matching](/lead-routing/matching/accounts-and-companies).

## How HubSpot contact-to-company matching works in Default

A HubSpot matching workflow in Default runs these steps:

1. **A trigger or earlier step supplies the contact.** Use **CRM Record Created** or
   **CRM Record Updated** on the HubSpot **Contact**, or a **Match Record** step that found the contact
   from form or API data.
2. **Match Record finds the Company.** Set **Record** to **Company**, then match on property values or
   turn on **Match by association**.
3. **Tiebreakers pick 1 Company.** When several companies qualify, the rules under
   **Prioritize matched records by** choose 1.
4. **The node branches.** **Match** carries the Company's ID and properties to later nodes.
   **No Match** runs when no Company qualifies.
5. **Later nodes act on the result.** **Create Association** links the contact to the matched
   Company, and other nodes can use the Company's properties, such as its owner.

## Ways to match a HubSpot contact to a company

| Method | How to set it up | When to use it |
| - | - | - |
| Company domain | **Record** set to **Company**. In **Match Details**, **Company Domain Name** **domain matches** the contact's email, with **Domain from email** chosen in the value picker. | The contact is not linked to a company yet, for example a new contact from a form. |
| Match by association | **Record** set to **Company**. Turn on **Match by association**, set **Source record type** to **Contact**, and choose the contact's ID from an earlier step as **Source record**. | The contact is already associated with its company in HubSpot. |
| Primary company ID | **Record** set to **Company**. In **Match Details**, **Record ID** (`hs_object_id`) **equals** the contact's primary company ID (`associatedcompanyid`). | You need the contact's primary company, and the contact may be associated with several. |
| Company name | **Record** set to **Company**. In **Match Details**, the company name property (`name`) **equals** the company name from the form. | A fallback only. Names are spelled differently across records, so a domain is more reliable. |
| Contacts at a company | **Record** set to **Contact**. In **Match Details**, the primary company ID (`associatedcompanyid`) **equals** a Company ID from an earlier step. Or turn on **Match by association** with **Source record type** set to **Company**. | You start from the company and need a contact at it. |

**Match by association** and **Match Details** do not combine:

* With **Match by association** on, the node ignores **Match Details** and considers only records
  associated with the **Source record**. The workflow can be published without match conditions.
* With it off, **Match Details** needs at least 1 condition before the workflow can be published.
* **Match by association** does not check HubSpot association labels. Any associated company counts,
  so use the primary company ID method when the primary company matters.

**Match Details** lists the properties you can filter on for the chosen object, including custom
properties. **Record ID** and the contact's primary company ID are always offered, even though HubSpot
treats them as system properties.

<Tip>
  Use **domain matches** instead of **contains string** on **Company Domain Name** and website
  properties. **domain matches** ignores `https://`, `www.`, paths and subdomains, never matches a
  lookalike such as `companyhp.com` for `hp.com`, 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).
</Tip>

## When several HubSpot companies match

A domain can belong to more than 1 Company record, for example a parent and its subsidiaries, and a
contact can be associated with more than 1 company. **Prioritize matched records by** picks 1. Select
**Add tiebreaker**:

| Tiebreaker | Where to find it | What it does |
| - | - | - |
| **Most recently modified** | **Suggested** | Prefers the company modified most recently. |
| **Newest created** | **Suggested** | Prefers the most recently created company. |
| **Oldest created** | **Suggested** | Prefers the first company created, often the original record. |
| **Largest by employees** | **Suggested** | Prefers the company with the highest number of employees. |
| **Has a parent company** | **Suggested** | Prefers companies that have a parent company. |
| **Sort by a field…** | **Advanced** | Sorts by any date or number property. Dates sort **Newest** or **Oldest**. Numbers sort **Highest** or **Lowest**. |
| **Prefer records where…** | **Advanced** | Prefers the matched companies that meet the conditions you set. |

How Default applies the rules:

* **Only when 2 or more companies match.** When exactly 1 company matches, the node uses it and runs
  no rule. Put a hard requirement in **Match Details** instead.
* **In order, top to bottom.** 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 company** and
  **Prefer records where…** keep only the companies that meet them. When none of the remaining
  companies meets a filter rule, Default skips that rule, keeps the companies 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 company HubSpot returns, and that
  order is not defined. With **Match by association** and no rules, that is the first associated
  company.
* **Rules see a limited window.** With tiebreakers, **Match by association** compares up to 100
  associated companies. Property matches read a limited number of results too, and the run log warns
  when that limit is reached.

## When no HubSpot company matches

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

| Case | What happens |
| - | - |
| No company has the contact's domain | HubSpot returns no results. The run log shows **No matching records found**. |
| **Match by association** is on and the contact has no associated company | Default finds no associated records and follows **No Match**. |
| The contact's email uses a public email provider, such as `gmail.com` | **domain matches** is false for every company. |
| A value in **Match Details** is empty for this run | Default does not search. The run log warns 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. |

Personal email addresses also end on **No Match**, so do not create a company straight from this
branch. Leave the contact unlinked for review, or send it to an
[enrichment node](/workflows/steps-enrichment) that can find the company first.

## Build a workflow that links new contacts to their company

This example links each new HubSpot contact to the Company with the same domain, unless the contact
already has an associated company.

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

  <Step title="Check for an existing association">
    Add **Match Record** from the **Records** section. Set **CRM** to **HubSpot** and **Record** to
    **Company**. Turn on **Match by association**, set **Source record type** to **Contact**, and
    choose the contact's record ID from the trigger as **Source record**.

    Leave the **Match** branch empty. The contact is already linked.
  </Step>

  <Step title="Match the company by domain">
    On the **No Match** branch, add a second **Match Record** for **Company** with
    **Match by association** off. Under **Match Details**, select **Edit**, choose
    **Company Domain Name** and **domain matches**, pick the contact's **Email** from the trigger, and
    choose **Domain from email**. Select **Save changes**.

    Under **Prioritize matched records by**, add **Largest by employees** and then
    **Most recently modified**.
  </Step>

  <Step title="Associate the contact with the company">
    On the second node's **Match** branch, add **Create Association**. Set **From record type** to
    **Contact** and **From record** to the contact's record ID from the trigger. Set
    **To record type** to **Company** and **To record** to the Company's ID from the second
    **Match Record** step. Leave **Association type** set to **Default**.
  </Step>

  <Step title="Handle contacts without a company">
    Leave the second **No Match** branch empty, or add an enrichment node to find the company.
  </Step>

  <Step title="Test and publish">
    Select **Test**, choose the trigger, and fill in a sample contact whose email domain belongs to an
    existing company. Select **Run Test** and check the contact's companies in HubSpot. 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 HubSpot. Use a test contact.
</Warning>

Choose **Labeled** as the **Association type** only when your HubSpot account uses a specific
association label for this relationship, then pick it under **Label**.

## Find the company for a contact an earlier step matched

A form or API workflow usually matches the contact by email first. The company lookup can then start
from that contact:

1. Add **Match Record** with **Record** set to **Contact**, matched on **Email** from the trigger.
2. On its **Match** branch, add **Match Record** with **Record** set to **Company**, turn on
   **Match by association**, set **Source record type** to **Contact**, and choose the contact's ID
   from the first **Match Record** step as **Source record**.
3. Later nodes can use the Company's properties. For example, a **Display Scheduler** node can use
   the **Company owner** as a custom host, so the person books with the rep who owns the account.

On the contact's **No Match** branch, match the company by domain instead, because a new contact has
no associations yet. To find or create the contact itself, see
[HubSpot contact matching](/lead-routing/matching/hubspot-contacts).

## Check and troubleshoot HubSpot company matching

Open the workflow, select **Runs** at the top, and select a run. Each **Match Record** step shows its
conditions and the record it chose. See [Run logs](/workflows/run-logs).

| What you see | What to check |
| - | - |
| Contacts with a work email follow **No Match** | Check the Company's **Company Domain Name** value and the other conditions in **Match Details**. |
| The wrong company is chosen | Add or reorder tiebreakers. With **Match by association**, use the primary company ID method when the contact has several companies. |
| The run log warns that a Prefer rule matched none of the remaining candidates and was skipped | None of the matched companies met that filter rule, so the next rules chose the company. Fix the rule's condition, or move it to **Match Details** when it is a hard requirement. |
| **Match by association** fails because the source record is missing | **Source record** was empty for this run. Choose a contact ID from a step that always runs before this node. |
| 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. |
| HubSpot rate limits the search | Default retries rate-limited searches with a backoff. If the retries run out, the node fails. |

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.