GoHighLevel Duplicate Contacts: How to Clean Up a Messy Subaccount Safely
Your contact list has the same person three times, the conversation history is split across all three, and you are afraid to merge because a live workflow is attached. Here is the order that fixes it.
2. The two ways to merge in HighLevel
3. What the Merge Contact workflow action does
4. What survives a merge
5. What happens to workflows, appointments, and payments
6. The safe cleanup order
7. How to stop duplicates coming back
8. How this fits a snapshot import cleanup
A messy contact list is not one bug. It is several intake paths writing to the same list with different matching rules. Once the duplicates pile up, every count, report, and conversation becomes unreliable.
I clean up subaccounts for a living. Below is the order I work in, what HighLevel moves during a merge, and the settings that stop the same duplicate from appearing next week.
Why Do GoHighLevel Duplicate Contacts Appear?
Most duplicates trace back to four sources. Fix the source, or you will be merging the same person again next month.
CSV imports with inconsistent data
HighLevel states that its CSV import merges contacts by phone number or email and cannot create duplicates on its own. The same documentation still lists CSV imports as a common duplicate source. Both are true: the file creates the mismatch. One row carries an email, the next carries the same person's phone, or the phone format changes between rows. HighLevel matches on one field, misses the other, and you end up with two records. Normalize the file before upload: one phone format across every row, one email per record.
Form submissions plus calendar bookings
If a lead fills out a form and then books a call, one visit can create two records. The form collects an email and the calendar collects a phone. The Find Existing Contacts Based On setting lets you pick email or phone as the primary lookup field, with an optional secondary. If a submission carries only the field you did not set, it can slip past the match and create a second record. See the deduplication preferences documentation.
Third-party tools and manual entry
The deduplication preferences apply to Forms, Zapier, Facebook, and Instagram Messenger. When Allow Duplicate Contact is on, HighLevel creates a new record even if the email or phone already exists in the list. Manual entry and messenger conversations add to the pile whenever a name does not match exactly.
Second imports and snapshot pushes
Import the same list twice, or push a snapshot into a subaccount that already has contacts, and you get two of everything.
What Are the Two Ways to Merge Duplicates in HighLevel?
HighLevel gives you two manual paths plus one automated action. Only subaccount admins can merge contacts. Merges are permanent.
Path 1: manual merge from the contacts list
Select the contacts you want to combine in the Contacts list, open the More menu in the top action bar, and choose Merge. In the Merge Contacts window you choose which record stays as the Master, then review the fields where the records disagree.
Path 2: the Manage Duplicates tool
Open Contacts, click the three-dot menu beside the list, and choose Manage Duplicates (HighLevel's changelog calls the scan Find Duplicates). Pick a Find By criterion: Email, which HighLevel recommends as the default, or Phone, or Name, then run the scan. The tool groups potential matches and merges up to 10 contacts per pass into a single master. You can also reject a pair so it stops appearing in future scans. Name matching produces the most false positives, so treat those groups as suggestions and check each one.
- Pick the master by history, not by name.
- Export the contact list first. Merges are permanent.
- Name the one admin who will run the merges.
What Does the Merge Contact Workflow Action Do?
The Merge Contact workflow action handles deduplication inside a workflow instead of in the contacts list. Add it as a step and choose a Match By option: Email, Phone Number, or Email and Phone Number. When the workflow runs, HighLevel looks for an existing contact that matches the enrolled contact on that criterion.
Two behaviors matter. First, you cannot choose the survivor. The newer record is always merged into the older one. Second, if nothing matches, the action changes nothing and the contact continues down the path. HighLevel writes every merge to the workflow Execution Logs, with the matched contacts and the criteria it used.
One exception: if the surviving master is already enrolled in that same workflow, the duplicate is removed from the workflow rather than merged into the run, and the log says so.
What Survives a Merge, and What Moves to the Master Record?
The record you pick as master stays, and it keeps its existing values by default. Other records fill in a custom field only when the matching field on the master is blank, so an existing master value is never overwritten. Tags, notes, opportunities, tasks, conversations, courses, community groups, and products combine from the selected records.
The Merge Contacts window shows you the fields where the records differ and lets you deselect what you do not want. That review step is your only control.
What burns people is history, not fields. HighLevel documents that conversations, notes, tasks, and opportunities combine into the master, and that appointments, payments, orders, and invoices default to the master's values. Because merges are permanent, I still open the record I plan to drop and export or screenshot its message thread and any payment history before I touch the merge button. That is a precaution, not a documented gap.
What Happens to Workflows, Appointments, and Payments on the Record That Goes Away?
Workflows. If a duplicate contact is deleted in the merge, HighLevel transfers the workflow execution to the master contact so the automation continues. If the master is already in that workflow, the duplicate leaves the workflow instead, and the Execution Logs show which outcome happened. Check the logs after each batch instead of assuming.
Appointments. These default to the master's values, so appointment history on the record you remove is not guaranteed to survive. If a booked call matters, confirm the master already holds it.
Payments, orders, and invoices. They follow the same rule and default to the master. This is where a careless merge gets expensive, because recurring subscriptions and paid invoices sit on that record. Review the payment history, then reconcile the merged contact against the payments list afterward.
My working rule: the master carries the most financial and appointment history. Recency and a tidier name are not reasons to promote a record.
What Is the Safe Cleanup Order for a Live Subaccount?
Do not open the duplicate tool and start clicking. Contain first, then merge in waves.
- Audit first. Scan by email, then phone, then name, and export the contact list before any change.
- Separate real duplicates from lookalikes. Same email is safe. A shared family phone is not. Reject the false pairs.
- Freeze risky sends. Pause workflows that fire on contact creation or tag change, and stop active bulk sends.
- Test with a fake pair. Create two records with the same email, enroll one in a workflow, book an appointment on the other, then merge and check the logs, appointment, and thread.
- Merge in batches. Same-email groups first, up to 10 per pass, then phone matches, then name-only groups after manual review.
- Verify between batches. Check Execution Logs, appointments, and payments before the next group.
- Log what you did. Keep the masters you chose, the pairs you rejected, and the batches you merged.
How Do You Stop Duplicates From Coming Back?
Merging only cleans up what is already there. These settings and habits stop new duplicates.
- Set the lookup field. Under Settings,
Find Existing Contacts Based Onlets you choose a primary lookup field, Email (the default) or Phone, with an optional secondary field. HighLevel explains that it checks the primary field first and falls back to the secondary. Pick what your intake collects most consistently. - Turn
Allow Duplicate Contactoff unless you have a reason. Matching submissions then update the existing contact. CSV imports merge on email or phone regardless of that setting. - Make intake paths agree. Decide whether the form or the calendar creates the record, and make the other update it.
- Add the Merge Contact action to new contact workflows with Match By set to email and phone.
- Scan on a schedule. Weekly for high volume, monthly otherwise, and always after a bulk import.
- Fix the source. If the same client appears twice every week, one integration is posting contacts without looking them up.
How Does This Fit a Snapshot Import Cleanup?
When a snapshot lands in a subaccount that already has contacts, or contacts get imported on top of a snapshot build, you inherit a second copy of everything. Two pipelines watch the same lead, two welcome sequences are live, and the same contact sits in the list twice. Clean the structure before you clean the records. Get the imported workflows, calendars, and custom values working first, then dedupe the contact list once the sends are stable. If you are mid-rescue, the structural side is covered in GoHighLevel snapshot rescue, and this guide handles the records. Merging contacts while two conflicting workflows are live is how a cleanup turns into an incident.
This is the work I do daily: 5 years in GoHighLevel, 100+ client systems built, 400 to 700+ subaccounts supported, and 70+ VAs and students coached. Snapshot-to-launch delivery and subaccount QA sit alongside it.
FAQ
Why do GoHighLevel duplicate contacts appear?
Duplicates come from several intake paths writing to the same list: form submissions, calendar bookings, messenger conversations, manual entry, and third-party tools such as Zapier. HighLevel's CSV importer merges on email or phone and does not create duplicates on its own, but a file with inconsistent phone formats or a missing email can still produce two records for one person.
What happens to workflows when I merge duplicate contacts?
If the duplicate contact is deleted in the merge, HighLevel transfers the workflow execution to the master contact so the automation continues. If the master is already enrolled in that same workflow, the duplicate is removed from the workflow instead, and the Execution Logs show which of the two happened.
What happens to appointments and payments after a merge?
Appointments, payments, orders, and invoices default to the values on the master record you selected. Pick the record with the longest payment and appointment history as the master, review the merge preview before you confirm, and reconcile the payments list afterward.
Can I undo a merge in GoHighLevel?
No. HighLevel states that contact merges are permanent, and only subaccount admins can run them. Export your contacts before you start and keep a log of the masters you chose, so you have a reference if you need to rebuild something later.
Sources
Product behavior in this guide comes from HighLevel's own documentation. Check it again before you clean a live account, because the product changes.
- How to Manage and Merge Duplicate Contacts
- Merge Contact workflow action
- Allow Duplicate Contacts (Contact Deduplication Preferences)
Contact list out of control?
Send me subaccount access and the count you are working with. I will audit the duplicates, map the risky workflows, and clean it up in batches with logs you can check.
Book Your Cleanup Call