Contact Matching

Contact matching automatically recognizes that two incoming records belong to the same real person — even when they arrive through different channels (WhatsApp number, email address, Instagram ID). Goal: a single customer record per person, no duplicates.

What is contact matching?

Contact matching (often "identity resolution" or "duplicate detection") is the logic that lets a platform decide: "This incoming WhatsApp message from +49 170 123 4567 belongs to the same person whose email [email protected] we already know." The result is one customer record, not a graveyard of half-profiles.

Why matching is essential

Without matching you quickly end up here:

  • Anna is on the email list as [email protected]
  • Anna is a WhatsApp contact at +49 170 …
  • Anna signed up via newsletter form as "Anna K."
  • Three records, one real person — without matching, all three get addressed separately.

The consequences: duplicate marketing messages, miscalculated lifetime value, fragmented service history, GDPR issues on data subject requests.

Match signals

Platforms typically use these identifiers:

SignalStrengthNote
Phone number (E.164 format)Very strongUnique if uniformly formatted.
Email addressVery strongUnique, but typos happen.
Platform ID (WhatsApp ID, Telegram ID, Instagram handle)Very strongIssued by the provider, immutable.
NameWeakMany Annas in the system — only useful in combination.

Three modes compared

ModeWhat happens on collisionWhen to use
Auto-merge (default)The existing contact is updated rather than a new one created. The older contact stays primary; missing fields get filled in.Default for most SMBs. Delivers a clean customer record without manual work.
Allow duplicatesBoth contacts are created. The platform reports in the response that duplicates may exist (suggestion list).Rare — e.g., marketplace setups where each signup is meant to be its own account.
Block duplicatesThe platform rejects the creation (HTTP 409) and returns the existing contact.When you want strict uniqueness — e.g., in B2B sales.

Merge rules (what happens on a merge)

  • Oldest contact stays primary. Both IDs continue to resolve to the surviving record.
  • Non-empty values win. On conflict, the older creation date decides.
  • Sticky fields: is_blocked and is_archived stay "true" if either record had them — a merge must never silently unblock a contact.
  • History moves over: Conversations, messages, notes, tags, custom fields, contact methods all land on the survivor.
  • System note in the audit log: What was merged, what conflicted — fully documented.

What happens to old IDs

External integrations, webhooks, CRMs often reference old contact IDs. After a merge those old IDs must not 404. Solution: the API transparently resolves the old ID to the survivor, additionally returns a merged_from field and sets an X-Merged-Into header. Existing integrations don't break.

Channel edge case: first contact on a new channel

Important exception: when a WhatsApp message comes in for a phone number we already know — but the contact has no WhatsApp ID yet — that's not a duplicate. It's a new contact method on the existing contact. Auto-merge applies regardless of mode.

Manual merge

Not every duplicate is detected automatically. Phonetically similar names, swapped first/last names, deliberately separated accounts — these need a manual merge. A "Find Duplicates" view shows candidates grouped by match signal, with a bulk-merge option.

Contact matching at SendSeven

SendSeven supports all three modes (Auto-merge as default, Allow, Block), a per-request override via the duplicate_mode field, manual merging in the UI, and via the REST API (POST /contacts/{id}/merge). Match signals are phone, email, platform ID, and name (as a weak signal in the suggestion list). All merges are recorded in the audit log; old UUIDs remain resolvable.