contact.merged
Emitted when two or more contacts are folded into one surviving contact
type: contact.merged
Fired after a merge commits. One or more contacts have been retired into a single survivor - the same person reached you on two channels, or two records turned out to be one.
Why this event exists
Without it, a merge would look like a deletion to your subscriber: the loser contacts simply stop existing, and their history appears to vanish. This event is the forwarding pointer that tells you where it went.
A merge does not emit contact.deleted for the retired contacts. If you only subscribe to contact.deleted you will never learn that a merge happened, and your copy of the data will drift out of sync silently.
When it fires
- An operator merges contacts from the People page or the contact profile.
- Wexio's merge reconciler folds duplicates together after resolving identities across channels.
It fires after the merge has committed, so a read issued when you receive it already reflects the new state.
data shape
type Data = {
contact: {
from: string[]; // the retired (loser) contact ids
into: string; // the surviving (winner) contact id
};
mergedAt: string; // ISO-8601 UTC
};fromalways has at least one entry.intois never one of thefromids.
Example envelope
{
"id": "evt_01JV4QEJX54A0E3KJ9W8R1Z4DP",
"type": "contact.merged",
"timestamp": "2026-04-24T12:14:22.000Z",
"data": {
"contact": {
"from": ["6804f4d5a6f9f35f6e66f1a2", "6804f4d5a6f9f35f6e66f1b7"],
"into": "6804f4d5a6f9f35f6e66f1c9"
},
"mergedAt": "2026-04-24T12:14:22.000Z"
},
"meta": {
"eventId": "evt_01JV4QEJX54A0E3KJ9W8R1Z4DP",
"event": "contact.merged",
"occurredAt": "2026-04-24T12:14:22.000Z",
"organisationId": "6640f3d5c8a0d7e8b7f20222",
"connectionId": "6640f45ac8a0d7e8b7f2014a",
"apiVersion": "2026-04-01",
"attempt": 1
}
}How to handle it
- Look up your local records for every id in
from. - Re-point them at the record for
into, or merge them into it. - Keep the
fromids as aliases - messages you already stored still reference them.
Notes
- Key your own records on
contactId(the merge-winner id, present onContactPayloadandChatPayload) rather than onpeopleId, and merges reconcile cleanly. - A winner's
ContactPayload.merged.loosersIdscarries the same information on subsequent contact reads. - Merging is plan-gated and role-gated inside Wexio, but the event shape is the same however it was triggered.
Related
contact.split- the mirror image, when a merge is undonecontact.updated- ordinary field changes- Shared Types -
ContactPayload, includingmerged