Customer Match Hashing Requirements
What Customer Match Actually Does
Google Ads Customer Match, Meta Custom Audiences, and LinkedIn Matched Audiences all let you upload a list of your own customer identifiers (email, phone, mailing address) to target or exclude those specific people in paid campaigns, or to seed lookalike/similar audiences. The platform matches your uploaded identifiers against its own logged-in user records to find overlapping accounts — but it never receives your identifiers in plaintext. You hash them client-side (or server-side, before upload) using a specified algorithm, and the platform hashes its own stored identifiers the same way, then matches on the resulting hash values.
The Exact Normalization Rules Matter More Than the Algorithm
All three major platforms specify SHA-256 as the hashing algorithm, but SHA-256 of an un-normalized string produces a completely different hash than SHA-256 of the normalized version — and a mismatch here is the single most common cause of unexpectedly low match rates. The standard required normalization steps, consistently across Google, Meta, and most Customer Match implementations:
- Email: trim leading/trailing whitespace, convert to lowercase. Google additionally strips dots from the local part of Gmail addresses in some contexts and removes any +subaddress tagging for Gmail specifically — check current platform documentation, since this detail has changed across platforms.
- Phone: convert to E.164 format (e.g., +14155551234) — country code required, no spaces, dashes, or parentheses.
- Address-based matching (first/last name + zip, etc.): lowercase, remove punctuation, and strip accents/diacritics before hashing each field separately.
import { createHash } from "crypto";
function sha256(value: string): string {
return createHash("sha256").update(value).digest("hex");
}
function hashEmail(raw: string): string {
const normalized = raw.trim().toLowerCase();
return sha256(normalized);
}
function hashPhoneE164(raw: string, defaultCountryCode = "+1"): string {
const digitsOnly = raw.replace(/[^0-9+]/g, "");
const e164 = digitsOnly.startsWith("+") ? digitsOnly : `${defaultCountryCode}${digitsOnly}`;
return sha256(e164);
}
// Upload payload: only hashed values ever leave your system.
const uploadRow = {
hashed_email: hashEmail(" Jane.Doe@Example.com "),
hashed_phone: hashPhoneE164("(415) 555-1234"),
};Hash Before Upload, Never Rely on the Platform's Upload Form
Platform Hashing Specifics
| Platform | Algorithm | Minimum List Size | Key Normalization Quirk |
|---|---|---|---|
| Google Customer Match | SHA-256 | Varies by product (often 1,000+ for similar audiences) | Gmail dot/plus-tag handling has changed over time — verify current docs |
| Meta Custom Audiences | SHA-256 | No strict minimum, but very small lists underperform | Multiple identifier types matched simultaneously, improves match rate |
| LinkedIn Matched Audiences | SHA-256 | Minimum audience size before activation, typically in the hundreds | Business email vs. personal email matters for match quality |
Match Rates Are Inherently Capped by Logged-In Coverage
What's Next?
Email hashing is one instance of a broader identity-resolution pattern used across ad platforms — the mechanics generalize directly to first-party ID networks and universal ID solutions covered next.
I build these systems professionally.
Whether it's a RAG pipeline, analytics migration, or AI workflow — let's talk.