
GoHighLevel Duplicate Contacts: Merge & Prevent (2026)
By Dr Priya Jaganathan, GoHighLevel Certified Admin · HL Growth Partner, Australia · Updated 25 September 2026 · 9 min read
Some links below are affiliate links — if you sign up through them, HL Growth Partner may earn a commission at no extra cost to you. It never changes what we recommend. Full disclosure.
GoHighLevel duplicate contacts are almost never a bug. They are the predictable result of a sub-account setting, a phone number format and three or four intake channels that were each built on a different day by a different person.
Once you understand what HighLevel actually matches on, the mess stops being mysterious. This guide covers the mechanics, the merge, the bulk clean-up, and the prevention architecture that stops duplicates reappearing.
Quick Facts
| What GHL matches on | Primary email and primary phone only — not secondary fields (HighLevel Support Portal, 2026) |
| Where the setting lives | Settings → Business Profile → Contact Deduplication Preferences |
| Default primary field | Email, with an optional secondary field checked only when the primary finds no match |
| Channels the setting governs | Forms, Zapier, Facebook and Instagram Messenger |
| Channel it does not govern | CSV imports, which match and merge regardless of the setting |
| Merge batch limit | Up to 10 records per merge; Agency and Sub-Account Admins only |
| Reversible? | No. HighLevel states contact merges cannot be undone |
How GoHighLevel decides two records are the same person
Deduplication in a sub-account is controlled from Settings → Business Profile → Contact Deduplication Preferences. That panel is where the "Allow Duplicate Contact" toggle lives, and it does less than most people assume.
You choose a primary matching field — email by default, or phone — and optionally a secondary field. HighLevel checks the primary first; the secondary is only consulted when the primary produces no match.
What the toggle actually changes
With Allow Duplicate Contact switched ON, a new submission with the same email or phone creates a separate record. With it OFF, the incoming data updates the existing contact instead.
Per HighLevel's own Allow Duplicate Contact documentation, the setting applies to Forms, Zapier, Facebook and Instagram Messenger — and explicitly does not apply to CSV imports, which match on phone or email either way.
The limitation nobody reads
Duplicate detection supports the primary email and primary phone fields only. A second email stored in a custom field is invisible to it.
That single sentence explains most HighLevel duplicate contacts in real accounts. One record with [email protected] and one with [email protected] are two different people to the platform — even with an identical mobile — if email is your primary field and you never set a secondary.
Where GoHighLevel duplicate contacts actually come from
In audits, six sources account for nearly all of it. Diagnose by source, not symptom — otherwise you merge for a fortnight and the count climbs back.
| Source | Root cause | The fix |
|---|---|---|
| CSV imports | Phone written as 0412 345 678 in one file and +61412345678 in another; blank email column | Normalise to E.164 before upload; import as "Update only" where appropriate |
| Facebook and Instagram lead ads | Lead supplies the Facebook-registered email, not the one used on your site form | Set phone as primary or secondary match field; make phone required on the lead form |
| Forms and surveys | One form maps phone to the standard field, another maps it to a custom field | Audit every form's field mapping to standard Contact fields |
| Inbound calls | Unknown caller creates a phone-only record with no email to match against | Phone as primary or secondary field; tag and review phone-only records weekly |
| Zapier and webhooks | Integration calls create instead of upsert, or sends a partial payload | Switch to the upsert endpoint so one record is the target, not a new row |
| Multiple funnels | Lead magnet, webinar and booking funnels each capture different field sets | Standardise the capture schema across funnels; one source of truth per channel |
The cost of leaving it
Duplicates are not a tidiness problem. They are a revenue and deliverability problem, and each copy of a lead does damage in three places at once.
- Inflated contact counts. Every duplicate is billed, stored and counted like a real person, so your database looks bigger and performs worse than it is.
- Broken attribution. The first-touch source sits on record A and the closed opportunity on record B, so your source reporting credits the wrong channel. This is where most GoHighLevel attribution reporting problems begin.
- Double-sends. Two records in the same Workflow means two emails and two SMS to one human — wasted send credits, more unsubscribes and spam complaints, and a real hit to sender reputation.
What survives a merge, and what quietly does not
There are two ways to merge by hand. Search, select between two and ten records, then More → Merge. Or open Contacts → three-dot menu → Manage Duplicates and scan by Email, Phone or Name.
Either way you nominate a master record — the one that survives. Choose the record with the most accurate and current information, not simply the oldest.
The retention rules that matter
According to HighLevel's merge duplicate contacts guide, the behaviour differs by data type.
- Custom fields: a value from the non-master record is written only where the master's field is blank. Existing values on the master are never overwritten.
- Tags, notes, conversations, tasks and opportunities: combined into the master record.
- Appointments, payments, orders and invoices: default to the master contact's values.
- Workflows: execution transfers to the master, and duplicate runs are cancelled.
The practical trap is the custom-field rule. If the master holds a stale value and the duplicate holds the correct one, the stale value wins. Fix the master first, then merge.
And note the finality: merges cannot be undone. On any account you did not build, take a backup before a bulk pass — the same discipline covered in our sub-account backup and restore process.
Merging inside a Workflow
HighLevel also ships a Merge Contact workflow action, matching on email, phone, or both. The documented behaviour is worth memorising: the newer contact is merged into the older one, so the older record is preserved as the primary. Useful as a safety net behind a form trigger — not a substitute for fixing the capture layer.
Cleaning up an inherited account without losing history
Ten records per merge sounds crippling until you sequence the work. The goal of pass one is not zero duplicates — it is a stable count.
The order I run it in
- Stop the inflow first. Fix the setting, the form mappings and the webhooks before merging a single record, or you are bailing out a boat with the hole still open.
- Export everything. A full contact export is your only undo button.
- Scan by phone before email. Phone duplicates are usually formatting artefacts and the safest merges to make.
- Build smart lists for records with no email, no phone, or no tags — these are where junk hides.
- Merge in themed batches and record what you rejected. Once an identifier is rejected in Manage Duplicates, it is not offered again on later scans.
For badly fragmented data, re-importing a cleaned CSV over the top is often faster than merging in the UI. That path is worth reading on properly first — see our GoHighLevel contact import and CSV mapping walkthrough before you upload anything.
HighLevel's import documentation confirms the match order for updates is Contact ID → Email → Phone, with a choice of Create only, Update only, or Create and Update. "Update only" is safest for a clean-up import. CSVs are capped at 30 MB, one sheet per file.
Not on HighLevel yet? Start with a free 30-day trial here — long enough to build everything in this guide before you pay a cent.
The prevention architecture that keeps duplicates from coming back
Merging is maintenance. Architecture is the fix, and it comes down to four decisions you make once.
1. One phone format, everywhere
HighLevel's CSV format documentation recommends E.164 with country code and the plus sign. For Australia that means +61412345678 — never 0412 345 678, never 04 1234 5678.
Enforce it at every entry point: form validation, the spreadsheet you import from, and the payload your webhooks send. One format means phone matching actually works.
2. One source of truth per channel
Each channel gets exactly one writer into the CRM. Facebook lead ads write through the native LeadConnector integration, not also through Zapier. Your website writes through one form, not a form plus a Zap plus a webhook. Where two systems both write, decide which owns each field and make the other read-only.
3. Upsert, never create
HighLevel's API exposes POST /contacts/upsert, which creates or updates according to your location's deduplication configuration and returns a new boolean telling you which happened. There is also GET /contacts/search/duplicate for a pre-flight lookup by email or number.
If a Zap or custom integration is calling create, that is your duplicate factory. Repoint it — the patterns are set out in our GoHighLevel webhooks and Zapier integration guide.
4. Naming and tagging discipline
Every intake point stamps a source tag in a fixed convention — src-fb-leadad, src-web-form, src-inbound-call. When a duplicate appears you can see instantly which two channels collided.
Keep the vocabulary short and enforced, the way we lay out in the HighLevel tags strategy and structure framework. Free-text tags are how naming discipline dies.
Common mistakes to avoid
- Leaving Allow Duplicate Contact ON by default and assuming the platform will tidy up later. It will not — every form and Zap submission becomes a new record.
- Setting email as the only match field in an account where most leads arrive by phone from lead ads or inbound calls.
- Merging before fixing the inflow. You will do the same work again in a month.
- Choosing the oldest record as master without checking its custom fields. Blank-only writing means stale values on the master survive the merge.
- Storing a second email or mobile in a custom field and expecting deduplication to see it. Detection reads primary email and primary phone only.
- Running a bulk merge with no export first. Merges are irreversible, and there is no recycle bin for the record that disappeared.
If you want an audit of your sub-account's deduplication settings and a staged clean-up plan for an inherited database, book a strategy call with the HL Growth Partner team.
Or if you just need the software first: grab the 30-day HighLevel trial and book us when you're ready to scale it.
Frequently asked questions
Where is the duplicate contact setting in GoHighLevel?
It sits in the sub-account under Settings → Business Profile → Contact Deduplication Preferences. From there you choose a primary matching field, optionally a secondary field, and toggle Allow Duplicate Contact on or off. The setting is per sub-account, so it must be checked on every location you manage.
What does the Allow Duplicate Contact setting actually change?
When it is on, a submission matching an existing email or phone creates a separate record; when it is off, the existing contact is updated instead. HighLevel's documentation states it applies to Forms, Zapier, Facebook and Instagram Messenger. It does not apply to CSV imports, which match on email or phone regardless of the toggle.
Does GoHighLevel match duplicates on email or phone?
Both are supported, but only the primary email and primary phone fields are used — a second email or mobile stored in a custom field is invisible to detection. You nominate one as the primary match field and may add a secondary, which is only checked when the primary finds no match. Email is the platform default.
What happens to tags, notes and opportunities when I merge contacts in HighLevel?
Tags, notes, conversations, tasks and opportunities are combined into the master record you nominate. Custom field values from the non-master record are written only where the master's field is blank, so existing master values are never overwritten. Appointments, payments, orders and invoices default to the master contact's values.
Can a contact merge in GoHighLevel be undone?
No. HighLevel states clearly that contact merges cannot be undone, so the selection must be verified before you confirm. Before any bulk clean-up, export your full contact list so you have a record of what existed. On an inherited account, take a sub-account backup as well.
How many contacts can I merge at once in GoHighLevel?
Up to 10 records can be merged in a single batch, and the interface notifies you when the limit is reached. Access to the Manage Duplicates tool is restricted to Agency and Sub-Account Admins. Note that once you reject a suggested duplicate identifier, it is not offered again in later scans.
How do I stop Zapier and webhooks creating duplicate contacts in GoHighLevel?
Point the integration at HighLevel's upsert endpoint, POST /contacts/upsert, which creates or updates based on your location's deduplication configuration and returns a "new" boolean indicating which happened. You can also pre-check with GET /contacts/search/duplicate by email or number. Most duplicate-generating integrations are calling a plain create action instead.
Related Articles on HL Growth Partner
Data hygiene and structure
- Custom objects and data modelling in GoHighLevel
- Client offboarding and clean data export
- Syncing GoHighLevel with Google Sheets
Lead capture and routing
- Multi-step forms and conditional logic
- Phone system setup and call tracking
- Building a lead scoring workflow
