A HubSpot portal collects duplicate contacts by default, not by accident. Every form embed, every list import, every third party tool writing through the API is a separate door into the same contact table, and none of them check what is already sitting inside HubSpot before creating something new. This post sets out how to catch and merge those duplicates automatically with n8n, where the matching logic needs to be stricter than it first looks, and where automation should hand control back to a person.
Why HubSpot Duplicates Keep Coming Back
HubSpot ships with a native duplicate management view that surfaces likely duplicates and lets someone review and merge them from inside the CRM. It is a review queue, not a gate. It only ever shows you contacts that HubSpot already created, after the fact, and its matching leans heavily on email address equality with some fuzzy checks on name and company layered on top. Anything that lands under a slightly different email, a personal address instead of a work one, or a typo introduced at data entry, slips straight past it. Contacts created in bulk through an import, a workflow action, or a third party integration writing directly to the API often never surface in that queue at all, because nothing ever flagged them as suspicious in the first place.
The result is a CRM that looks tidy in the duplicate management screen while still carrying thousands of records that no one has looked at. Segmentation, lead routing and reporting all quietly degrade underneath that surface. A workflow that runs continuously and evaluates every new or updated contact against what already exists closes that gap in a way a periodic manual review never fully can.
How Duplicates Actually Enter Your CRM
Before building anything, it helps to name the specific paths duplicates take into HubSpot, because each one implies a different fix:
- Form and chatbot submissions where a returning visitor uses a different email, or the browser autofill introduces a typo that HubSpot has no way to reconcile against the original record.
- Marketing automation platforms or event tools that write to HubSpot through the API without first checking for an existing contact, because their own integration was configured to create rather than upsert.
- Sales reps creating a contact manually before searching, particularly under time pressure during a call, or when the search box returns nothing because the existing record uses a work domain the rep did not think to try.
- List imports carried out after a company acquisition, a trade show, or a change of marketing tool, where the import file was never de-duplicated against the live portal before upload.
- The same person appearing under a personal address and a work address, which most matching logic treats as two entirely separate people unless it is explicitly told otherwise.
Each of these has a different practical fix: form validation catches typos, upsert logic in the sending system catches API duplication, search prompts catch manual creation, and pre-import cleaning catches list merges. The automated workflow described below is the backstop that catches whatever slips past all four.
Preparing HubSpot Before You Automate Anything
Before any workflow runs against production data, audit which properties actually need to survive a merge and in what order. Lifecycle stage, contact owner, original source, and any custom scoring fields all need an explicit precedence rule, because a merge that silently resets a contact from Opportunity back to Subscriber, or reassigns ownership to whichever record happened to be older, causes far more damage than the duplicate it was meant to fix. Export a full contact backup before the workflow goes anywhere near live data, so a bad merge rule can be identified and reversed rather than discovered weeks later in a pipeline report that no longer makes sense.
Connection security matters just as much as the merge logic itself. HubSpot deprecated standalone API keys in favour of private apps and OAuth, so the integration should authenticate through a private app scoped only to the objects it touches, contacts and whichever associated objects the merge needs to read. Scoping it narrowly limits the blast radius if the token is ever exposed, and it makes the permission set self documenting for whoever inherits the workflow later. HubSpot’s developer documentation covers the current authentication model and available scopes for private apps.
Designing Matching Logic That Actually Holds Up
The matching logic is where most deduplication projects succeed or fail, and it deserves more thought than a single email comparison. An exact email match is a safe basis for an automatic merge, because two records sharing the same address are, barring a shared inbox, almost always the same person. A match based only on company domain plus a fuzzy comparison on name is a different category of risk entirely: two different employees at the same firm can easily share a similar surname, and a domain match against a generic inbox such as info@ or sales@ will happily pair up two people who have never met. Treat that tier as a candidate for review, never for an automatic merge.
Phone numbers cause a quieter version of the same problem. A number stored as +44 20 7946 0958 in one record and 020 7946 0958 in another will fail a naive string comparison even though they are identical, so normalising to a single format before comparing is a prerequisite, not an optional refinement. Property precedence needs the same rigour: a sensible default is that the most recently updated non empty value wins for most fields, while lifecycle stage always takes the more advanced of the two values rather than the most recent one, so a merge can never accidentally demote a contact.
Merging two contact records also means combining two sets of personal data into one, which is a data protection decision as much as a technical one. Under UK GDPR, keeping personal data accurate is one of the core principles organisations are expected to meet, and a merge rule that silently overwrites correct information with stale data works against that obligation rather than for it. The ICO’s guidance for organisations sets out what accuracy and data minimisation actually require in practice, and it is worth reading before finalising precedence rules rather than treating them as a purely technical decision.
Building the Deduplication Workflow in n8n
With the matching rules settled, the workflow itself splits into three concerns: detecting a possible duplicate, scoring how confident that match is, and acting on the result. n8n’s documentation covers the HubSpot and HTTP Request nodes used throughout this build in detail, which is worth having open while wiring the workflow together.
Trigger and Duplicate Detection
Start with a HubSpot Trigger node set to fire on contact creation and property update, rather than polling on a schedule, so a duplicate is caught within seconds rather than accumulating between runs. Immediately after the trigger, an HTTP Request node calls HubSpot’s CRM search endpoint with filter groups for the incoming email, and a second filter group for company domain plus name, returning any existing contacts that could plausibly be the same person. This search step is what replaces a naive single field comparison with something closer to how a careful human reviewer would actually check.
Scoring Matches and Branching
Feed the search results into a Code node that applies the precedence rules from the section above and returns a confidence score rather than a simple true or false. A Switch node then routes the record down one of three paths based on that score: an exact email match goes to auto-merge, a domain plus fuzzy name match goes to a manual review queue, and no match at all leaves the record untouched. That branching is exactly what the diagram below sets out.
Executing the Merge and Logging It
For the auto-merge path, call HubSpot’s CRM object merge endpoint rather than trying to reconstruct merge behaviour manually. HubSpot handles carrying associated deals, tickets, notes and timeline activity onto the surviving record and redirects the losing record’s ID, which a hand rolled property copy would not replicate correctly. Every merge, whether automatic or completed from the review queue, should write a row to a log, a Google Sheet or Airtable base works fine, capturing both record IDs, the confidence score, and which properties changed. That log is what makes the workflow auditable rather than a black box, and it becomes the raw material for the metrics covered later in this post.
Testing the Workflow Before It Touches Live Data
Point the workflow at a HubSpot developer test account first, where the object structure mirrors production but nothing real is at risk. Once the logic is stable there, run it against a subset of perhaps a hundred live contacts in dry run mode, where the workflow logs what it would have merged without actually calling the merge endpoint. Compare that log against a manual review of the same hundred contacts. Any disagreement between the two is a sign the scoring thresholds need adjusting before the workflow is trusted with the full contact list. Only move to a full production run once several consecutive dry run batches match manual review closely enough that a reviewer would sign off on them without changes.
Scaling and Monitoring the Workflow Over Time
HubSpot enforces per second and daily API limits that vary by subscription tier, and a workflow that fires on every contact update in a large portal can bump against those limits during busy periods. n8n’s HTTP Request node supports retry with backoff, which handles transient throttling without the workflow failing outright, and batching lookups where possible keeps the request volume predictable rather than spiky. As the portal grows and new tools get connected, form builders, billing systems, event platforms, new sources of duplicates tend to reappear at the ingestion point rather than in the existing dataset, so it is worth adding a lightweight check at each new integration’s entry path rather than relying solely on the central workflow to catch everything downstream. A quarterly manual sample of fifty or so recently created contacts is a cheap way to catch drift in the matching rules before it becomes visible in reporting.
Measuring Whether Deduplication Is Actually Working
Define what success looks like before the workflow goes live, not after. Useful measures include the rate of new duplicates created per week, the proportion resolved automatically versus sent to manual review, and the average time between a duplicate appearing and it being resolved. Downstream, watch email bounce and unsubscribe rates and the size of active marketing lists relative to the underlying customer count, since both tend to move in the right direction once duplicate contacts stop diluting engagement metrics. Equanax has recorded an 86 percent reduction in fixable sync errors across the client environments it has worked in. Validation logic of the kind described in this post, catching and resolving bad or duplicate data before it propagates further, is one of the general mechanisms behind results like that, though the specific number will depend on the state of any individual portal before automation is introduced.
Related Reading
Frequently Asked Questions
Does n8n replace HubSpot’s native duplicate management tool?
No. HubSpot’s built in tool is still useful for ad hoc review, but it only flags likely duplicates for a human to approve and does not catch records created through imports, workflows or third party integrations. The n8n workflow described here runs continuously and does the matching and merging automatically, using HubSpot’s native tool as a backup for anything the automation is not confident enough to touch.
What HubSpot permissions does n8n need to merge contacts?
A private app with contact read and write scopes, plus the merge scope if you are calling the CRM merge endpoint directly. Never use a personal API key for this. HubSpot deprecated API keys in favour of private apps and OAuth, and a private app lets you scope access to exactly the objects the workflow touches.
How do you stop the workflow merging two different people?
By scoring matches instead of merging on any partial signal. An exact email match is high confidence and safe to auto-merge. A shared company domain plus a fuzzy name match is lower confidence and should route to a manual review queue rather than merge automatically, because two different employees at the same company can easily share a similar name or a generic inbox such as info@ or sales@.
What happens to deals, tickets and past activity when two contacts are merged?
HubSpot’s merge behaviour carries associated deals, tickets, notes and timeline activity onto the surviving record, and the losing record’s ID redirects to the survivor. Property values are resolved using the precedence rules you set, such as most recently updated non empty value, rather than being lost.
How often should the deduplication workflow run?
Trigger it on contact creation and update rather than on a schedule, so duplicates are caught within seconds of being created rather than accumulating between batch runs. A scheduled sweep once a week is still useful as a backstop for records that arrive through channels the trigger does not cover, such as bulk imports.
For more on this, see the full HubSpot archive, including Building a Scalable SDR and RevOps Framework with HubSpot and n8n Automation, HubSpot’s Game-Changing Sales and Marketing Tools and Tactics for B2B SaaS Companies, and WorkflowGuard: HubSpot Workflow Version Control & Rollback.
Leave a Reply