podium-contact-dedup
Installation
SKILL.md
Podium Contact Dedup
Overview
Deduplicate Podium contacts in production and operate the dedup pipeline at scale. This is not a one-shot cleanup script — it is the data-quality layer your integration runs continuously to keep the contact corpus sane while messages, calls, webchats, and reviews keep mutating it. Run it once and Sydney's "0412 345 678" walk-in stops creating a fifth contact next to the four that already exist as +61 412 345 678, (04) 1234-5678, +61412345678, and 0412345678.
The six production failures this skill prevents:
- Phone format inconsistency —
+61 412 345 678,0412 345 678,(04) 1234-5678,+61412345678are all the same phone but produce four contacts. Operators paste numbers from a CRM, a phone screen, a written form, and a stored fragment; Podium dedups on exact string match, so all four survive and the next caller appears as a fifth. - Merge API ordering loses fields — Podium's merge endpoint takes a
primaryand aduplicate; whichever you pick asprimarykeeps its own fields, the other's fields are discarded. Pick the wrong record (newer but emptier) as primary and the older, richer record's name, tags, and conversation links vanish silently. - Opt-out flag lost on merge — duplicate had
marketing_opt_out=true, primary hadmarketing_opt_out=false; naive merge keeps primary's flag and re-enables marketing on a person who explicitly opted out. This is a compliance incident (TCPA, GDPR Article 21, ACMA Spam Act) and a trust incident — the customer opted out, you marketed at them anyway. - Soft-delete vs hard-delete semantic confusion — Podium's
DELETE /contacts/{uid}is reversible; the record is hidden, not destroyed. Treat it as terminal and you ship a "contact reappeared after we deleted them" support ticket every time an admin restores a contact via the UI. Hard-delete (purge) is a separate, irreversible endpoint with different scopes. - Duplicate detection across locations — same phone calls Sydney AND Burleigh Heads, two contacts created (one per location), per-location dedup misses it entirely. Cross-location dedup needs a separate routine keyed by
phone_natural_keyacross the union of contacts in every location_uid, not just within one. - Merge conflicts on simultaneous edits — two operators (or one operator + one automated job) merge overlapping clusters at the same time; the second merge's
primarymay have already been merged into another record, the API silently merges into a now-stale target, and one operator's intent is dropped without surfacing the conflict.