How-To Guide 3 min read

How to Hash PII for Enhanced Conversions: Normalization and SHA-256 Guide

A detailed guide to normalizing and hashing PII (email, phone, name) for Enhanced Conversions across Google Ads, Meta, Microsoft Ads, and TikTok. The Upload Offline Conversions App explains the normalize-then-hash pipeline.

Last verified: 2026-11-05

Enhanced Conversions require all personally identifiable information (PII) to be SHA-256 hashed before sending to ad platforms. But hashing alone isn’t enough — you must normalize the data first. This guide covers the exact normalization and hashing pipeline for every supported field.

The Golden Rule: Normalize → Hash

RAW DATA → NORMALIZE → SHA-256 HASH → SEND TO PLATFORM

Never skip normalization. The hash of John@Email.COM is completely different from john@email.com, but they’re the same email address. If you hash without normalizing, your data won’t match the platform’s records.

Email Normalization and Hashing

Step-by-Step

Raw:        "  John.Doe@Gmail.COM  "
Step 1:     "John.Doe@Gmail.COM"         ← Trim whitespace
Step 2:     "john.doe@gmail.com"         ← Lowercase
Step 3:     SHA-256("john.doe@gmail.com") ← Hash
Result:     "e8b6c3a4f2d1b5e7..."        ← 64-char hex string

Platform-Specific Email Rules

RuleGoogle AdsMetaMicrosoftTikTok
Trim whitespace✅✅✅✅
Lowercase✅✅✅✅
Remove Gmail dots✅❌✅❌
Remove + aliases❌❌❌❌

Gmail dot removal: Google treats john.doe@gmail.com and johndoe@gmail.com as the same address. Before hashing for Google Ads, remove dots from the local part of @gmail.com addresses:

"john.doe@gmail.com" → "johndoe@gmail.com" → hash
"john.doe@yahoo.com" → "john.doe@yahoo.com" → hash (NOT Gmail, keep dots)

Meta does NOT do this — hash the email as-is (with dots).

Code Example

function normalizeEmail(email, platform = 'google') {
  let normalized = email.toLowerCase().trim();
  
  // Google-specific: remove dots from Gmail local part
  if (platform === 'google' || platform === 'microsoft') {
    if (normalized.endsWith('@gmail.com')) {
      const [local, domain] = normalized.split('@');
      normalized = local.replace(/\./g, '') + '@' + domain;
    }
  }
  
  return normalized;
}

Phone Normalization and Hashing

Step-by-Step

Raw:        "(555) 123-4567"
Step 1:     "5551234567"              ← Remove non-digits
Step 2:     "+15551234567"            ← Add country code (E.164)
Step 3:     SHA-256("+15551234567")   ← Hash
Result:     "d4f5c3b1e72a..."        ← 64-char hex string

E.164 Format Rules

FormatExampleValid?
+15551234567US number✅
+445551234567UK number✅
5551234567Missing country code❌
(555) 123-4567Not stripped❌
1-555-123-4567Missing +❌

The + is included in the hash for all platforms.

Use the E.164 Formatter tool to verify your phone formatting.

Code Example

function normalizePhone(phone, countryCode = '1') {
  // Remove all non-digit characters
  let digits = phone.replace(/\D/g, '');
  
  // Handle US numbers
  if (countryCode === '1') {
    if (digits.length === 10) {
      digits = '1' + digits;
    }
    if (digits.length === 11 && digits.startsWith('1')) {
      return '+' + digits;
    }
  }
  
  return '+' + digits;
}

Name Normalization and Hashing

Step-by-Step

Raw:        "  John  "
Step 1:     "John"                ← Trim whitespace
Step 2:     "john"                ← Lowercase
Step 3:     SHA-256("john")       ← Hash
Result:     "a8cf5e2d..."        ← 64-char hex string

Rules

  • Trim leading/trailing whitespace
  • Lowercase
  • Do NOT remove middle names, suffixes (Jr., III), or accented characters
  • Hash first name and last name separately

Address Normalization

FieldNormalizationExample
CityLowercase, trim" New York " → "new york"
State2-letter abbreviation, lowercase"California" → "ca"
ZipFirst 5 digits only (US)"90210-1234" → "90210"
CountryISO 2-letter, lowercase"United States" → "us"

Address fields are lower priority for matching but can improve match rates when combined with email and phone.

Common Mistakes

MistakeWhat Goes WrongFix
Hash before normalizeZero matchesAlways normalize first
Use MD5Zero matchesUse SHA-256 only
Include whitespaceLower match ratesTrim before hashing
Wrong phone formatZero phone matchesUse E.164 (+1XXXXXXXXXX)
Hash twiceZero matchesHash exactly once
Uppercase hex outputMay cause issuesUse lowercase hex
Don’t remove Gmail dots (Google)Lower match ratesRemove dots for @gmail.com

Verifying Your Hashes

Manual Verification

Use the SHA-256 Hasher tool to verify:

  1. Enter a normalized email: john@example.com
  2. Click Hash
  3. Compare the output with your implementation’s output
  4. They must match exactly

Programmatic Verification

// Known test vector
const input = "john@example.com";
const expected = "fd876f5e45d2e29fd23fd8a4c8579323fb18c2d1e79c2e749fc603e3c03a1c78";
const actual = await sha256(input);
console.assert(actual === expected, "Hash mismatch!");

How TUOCA Handles Hashing

TUOCA automates the entire pipeline:

  1. Raw PII input — You provide unhashed data from your CRM/call tracking
  2. Platform detection — TUOCA identifies the destination platform
  3. Platform-specific normalization — Gmail dot removal for Google, standard for Meta, etc.
  4. SHA-256 hashing — All PII fields hashed after normalization
  5. Format validation — Verifies 64-character lowercase hex output
  6. Upload — Sends hashed PII to the appropriate API

You never need to pre-hash your data. TUOCA handles everything automatically.

Frequently Asked Questions

SHA-256 produces completely different outputs for inputs that differ by even one character. The hash of 'John@Email.com' is different from 'john@email.com'. If you hash without normalizing, your hash won't match the platform's hash (which is computed from normalized data). Always: normalize first, then hash.

For email: lowercase, trim whitespace. For phone: remove all non-digit characters, add country code (E.164 format: +15551234567). For names: lowercase, trim whitespace. Google additionally removes dots from Gmail addresses before hashing.

Yes. TUOCA automatically normalizes and SHA-256 hashes all PII fields before uploading to any platform. You provide raw, unhashed data from your CRM or call tracking tool, and TUOCA applies the correct normalization rules for each destination platform. You never need to hash manually.

Stop Guessing. Start Proving ROI.

TUOCA connects your CRM and call tracking data directly to your ad platforms. Set up in minutes.