GoHighLevel // Contact Cleanup

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.

By Joe Asis, Senior GoHighLevel Expert | Updated September 17, 2026 | 8 min read
Proof, not promises: 5 years in GoHighLevel daily. 100+ client systems built. 400 to 700+ subaccounts supported. 70+ VAs and students coached.
Snapshot-to-launch delivery, plus subaccount QA and cleanup work.
Portfolio: joe-asis-portfolio.vercel.app | Booking: /booking
IN THIS GUIDE 1. Why duplicate records appear
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 lookup field, so the field you did not choose is the one that lets a second record through.

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.

Three rules I set before the first merge.

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's merge documentation lists conversations as combining, but it does not promise that the full activity feed of the record you remove survives. Accounts on HighLevel's own feedback board report losing the non-master activity feed and message thread. Signed documents do not transfer automatically. So open the record you plan to drop, screenshot or export the thread, and download the signed documents before you touch the merge button.

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.

How Do You Stop Duplicates From Coming Back?

Merging only cleans up what is already there. These settings and habits stop new duplicates.

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. Signed documents do not transfer automatically. 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.

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