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:
| Signal | Strength | Note |
|---|---|---|
| Phone number (E.164 format) | Very strong | Unique if uniformly formatted. |
| Email address | Very strong | Unique, but typos happen. |
| Platform ID (WhatsApp ID, Telegram ID, Instagram handle) | Very strong | Issued by the provider, immutable. |
| Name | Weak | Many Annas in the system — only useful in combination. |
Three modes compared
| Mode | What happens on collision | When 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 duplicates | Both 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 duplicates | The 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_blockedandis_archivedstay "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.