Thanks everyone for the suggestions. Here’s what we implemented that solved the issue completely:
Email Normalization Strategy:
We created a pre-processing layer that normalizes emails before the duplicate check. The key was addressing all three focus areas systematically:
- Email Normalization Implementation:
We built a normalization function that handles multiple scenarios:
function normalizeEmail(email) {
let normalized = email.toLowerCase().trim();
let [local, domain] = normalized.split('@');
if (domain === 'gmail.com') local = local.replace(/\./g, '');
return `${local}@${domain}`;
}
-
Enhanced Fuzzy Matching:
Instead of relying on Adobe’s built-in fuzzy matching, we implemented our own similarity scoring. We check against existing leads using the normalized email first, then apply Levenshtein distance for close matches (threshold of 2 characters). This catches typos like “johndoe@compnay.com” vs “johndoe@company.com”.
-
Deduplication Logic Workflow:
- Step 1: Normalize incoming email using the function above
- Step 2: Store normalized email in custom field “emailNormalized” (indexed)
- Step 3: Query API using normalized email: `GET /rest/v1/leads.json?filterType=email&filterValues={normalized}
- Step 4: If matches found, apply fuzzy matching on full email for final verification
- Step 5: If duplicate confirmed, update existing lead instead of creating new
Implementation Details:
We modified our integration middleware to call the normalization function before every lead creation request. For Gmail addresses specifically, we remove all dots from the local part since Gmail treats john.doe@gmail.com and johndoe@gmail.com identically. We also handle plus-addressing by optionally stripping everything after the + sign (configurable based on business rules).
Created a custom field “emailNormalized” (type: string, indexed: true) that stores the normalized version. This field is used as the primary lookup field in our duplicate detection queries, which improved query performance by 40% compared to using computed normalization in WHERE clauses.
Results After Implementation:
- Duplicate lead rate dropped from 8.5% to 0.3%
- Pipeline accuracy improved by 15%
- Sales rep efficiency increased (fewer duplicate contact attempts)
- API response time stayed under 200ms for duplicate checks
Additional Recommendations:
For international domains, we added UTF-8 normalization to handle accented characters. We also implemented a daily batch job that scans existing leads and updates their emailNormalized field to catch any leads created before this system was in place. The batch job identified 1,200 existing duplicates that we were able to merge.
One gotcha: make sure to update ALL integration points - we initially forgot about the Zapier integration which continued creating duplicates for another week until we added normalization there too.
Happy to share more details on the fuzzy matching algorithm if anyone’s interested!
This draft is based on general Adobe Experience Cloud knowledge. It has not been verified against your specific version and environment. Practitioners: verify the steps and share your experience below.