GuideSalesforceLeads

How to merge duplicate leads in Salesforce without waking the wrong automation

When a team says "just merge the duplicate leads," what they usually mean is: do not break Lead Status, do not convert the wrong rows, and do not create a cleanup run that nobody can explain later. Safe lead dedupe starts with reviewable clusters, not with a bulk merge button.

Run preflight first

Check converted LeadStatus values, duplicate rules, and anonymous Apex support before you even think about applying mixed Lead and Contact clusters.

Cluster the duplicates offline

Use enterprise-plan to group Leads and Contacts into reviewable clusters instead of merging individual rows by feel.

Review every mixed cluster

A Lead-to-Contact conversion is only auto-translatable when the cluster is exactly one Lead plus one Contact. Larger mixed clusters should stay manual.

Dry-run before --apply

The Salesforce merge-apply-plan command is dry-run by default, so preview the operation mix and skipped clusters before you execute.

The exact safety loop for leads

First, preflight the org. The code checks whether the org can execute lead conversions cleanly, whether a converted LeadStatus value exists, and whether duplicate rules or Apex constraints are likely to interfere.

Second, plan the run with g-gremlin dedup enterprise-plan. That gives you clusters, review notes, and a cluster-level review queue you can hand to RevOps.

Third, dry-run g-gremlin sfdc merge-apply-plan. The command tells you how many merge operations and convertLead operations would run and how many clusters were skipped because they still need manual review.

Only then do you pass --apply. That is where receipt files, state files, retries, and verify checks matter.

Key lead caveat

Not every mixed cluster should convert automatically

One Lead plus one Contact can become a convertLead operation.
More complex mixed clusters are skipped as manual cross-object resolution.
Lead dedupe and lead status interact. If status drives routing, scoring, or reports, read the lead-status audit before live apply.

Dry-run first

Preview the operation mix before anything mutates.

g-gremlin sfdc merge-apply-plan \
  --plan plan.json \
  --approval-file review_clusters.csv \
  --receipt-file receipt.json

Apply approved lead work

Add converted status when approved mixed clusters will execute as lead conversions.

g-gremlin sfdc merge-apply-plan \
  --plan plan.json \
  --approval-file review_clusters.csv \
  --receipt-file receipt.json \
  --state-file state.json \
  --converted-status "Qualified" \
  --apply

Receipt-backed apply

command and plan digest

The receipt stores the command name, plan path, plan digest, and approval-file digest when approvals are used.

execution posture

dry_run, resume, org alias, and optional state-file path.

operation evidence

All skipped, succeeded, and failed operations are serialized into the receipt payload.

verification path

Verification is separate: merge verify checks master/victim state, and convert-lead verify checks converted status and resulting records.

The buyer-language takeaway

Do not merge duplicate leads from a spreadsheet without a review queue.

Do not trust a mixed Lead and Contact cluster unless a human approved it.

Do not run live apply before you know what Lead Status and conversion will trigger.

Do use dry-run, receipts, and verify so the team can defend what happened afterward.

FAQ

What makes Salesforce lead dedupe risky?

Lead dedupe is risky because merges can touch conversion logic, Lead Status, assignment behavior, and downstream routing. The data problem is only half the job. The other half is understanding what your org will do when those rows change state.

How does Gremlin handle duplicate Lead and Contact pairs?

If a reviewed mixed cluster is exactly one Lead plus one Contact, the apply layer can translate that into a convertLead operation. If the mixed cluster is more complex than that, the workflow skips it with a manual-resolution reason instead of guessing.

Do I need a converted status value?

Yes, for live convertLead operations. If approved mixed clusters are going to execute as lead conversions, the apply command needs --converted-status. Dry-run can still show you the operation mix before live execution.

Keep the conversation going

These pages are meant to help operators solve real problems. If you want the next guide, grab the low-friction option. If you need the implementation, not just the guide, book time.

Stay in the loop

Get the next guide when it ships

I publish architecture guides grounded in real implementations. No generic AI filler.

Use your work email so I can keep the list useful and relevant.

Book Mike directly

Need the implementation, not just the guide?

Book a 15-minute working session with Mike right on his calendar. Tooling, consulting, or a mix of both is fine.

Open Mike's calendar

If you want me to come in with context, leave your email and a short note before the call.

I'll route new requests into the internal website inquiries inbox so I can follow up fast.