Skip to main content
Some platforms address the same person with two interchangeable ids — WhatsApp uses both <lid>@lid and <phone>@s.whatsapp.net. Identity canonicalization maps every alternate form to one stable id before the gateway keys the session, memory, allowlist, and pairing on it, so one person is never split into two principals.

Quick Start

1

WhatsApp: nothing to configure

WhatsAppBot wires WhatsAppIdentityCanonicalizer on the web-mode message path automatically. LID and phone forms of the same person resolve to one identity — no flags, no config.
2

Implement it for another platform

The extension point is a dependency-free, runtime-checkable Protocol. Implement canonicalize and return the stable id — or the raw id unchanged when you don’t know it.

How It Works

Canonicalization is the first step of identity resolution. Every downstream key — session, memory, allowlist, pairing — is derived from the reconciled id, so alternate address forms of the same person collapse to one principal. The contract is deliberately small and safe:
  • Deterministic. The same input always maps to the same output.
  • Fail-open. An unknown address returns unchanged, so a missing mapping is never worse than passing the raw id through. With no canonicalizer registered, resolution is unchanged.
  • First in line. It runs before any key is derived, so the allowlist and session see the reconciled id — not the raw one.

WhatsApp implementation

WhatsAppIdentityCanonicalizer learns the LID↔phone mapping from whatsmeow’s SenderAlt alternate-JID field and reconciles the sender toward the phone form. It only accepts an exact @lid@s.whatsapp.net pairing — a group @g.us, an unexpected domain, or an LID-to-LID pair is rejected, so a malformed or hostile alternate JID never stores a bogus identity. See WhatsApp Bot → Identity: LID vs phone JID.

Protocol Reference

Import from the gateway package:
IdentityCanonicalizerProtocol is a @runtime_checkable Protocol, so any object with a matching canonicalize method satisfies isinstance(...) without subclassing.

Common Patterns

Learn a mapping, then canonicalize

Guard against wrong-shape addresses

Only reconcile pairs you positively recognise; return the raw id for anything else so a hostile or malformed address can’t hijack another user’s identity.

Best Practices

Return raw_user_id unchanged whenever you can’t map it. A missing mapping must never corrupt identity — it should be exactly today’s behaviour.
Reconcile the id first, then derive session, memory, allowlist, and pairing keys from the result. Canonicalizing after a key is derived reintroduces the split.
Validate the shape of both addresses before storing a mapping. Reject group, cross-type, or unexpected-domain pairs so a hostile alternate id can’t map onto a real user.
The same raw id must always map to the same canonical id within a process. Non-deterministic output splits sessions and breaks allowlist matches.

WhatsApp Bot

The built-in LID ↔ phone canonicalizer in action

Bot Routing

How reconciled identities flow through channel routing