How to Validate Your Meta CAPI Event Match Quality
Your Meta CAPI is firing. Events Manager shows green checkmarks. But your Event Match Quality (EMQ) score is 4.2, and ROAS has been declining for three weeks.
This is the second most common CAPI failure I see after deduplication issues. The events reach Meta, but the user matching data is so poor that Meta can't connect conversions back to the people who saw your ads. You're sending conversion signals into a black hole.
What Event Match Quality Actually Measures
EMQ scores how well Meta can match your server-side conversion events to users in their system. It's measured on a scale of 1-10, where 10 means perfect matching and anything below 6 indicates significant data quality problems.
Meta uses customer information parameters (user_data in the CAPI payload) to perform this matching: hashed email, phone number, first name, last name, zip code, state, country, and external ID. The more parameters you send, and the higher quality they are, the better your EMQ score.
But here's what most implementations miss: it's not just about sending more fields. It's about sending clean, properly formatted, correctly hashed data that matches how users actually entered their information on your site.
In a recent audit, I found a site sending 8 customer parameters but scoring EMQ 3.8. The email field contained "N/A" for 40% of events (where email wasn't collected). The phone numbers weren't normalized -- some had country codes, some didn't, some had dashes, some had spaces. Meta couldn't match any of it.
When your EMQ is below 6, Meta's algorithm can't properly attribute conversions back to ad impressions. This creates a feedback loop where the algorithm thinks your ads aren't driving conversions (because it can't match them) and reallocates budget toward audiences that appear to convert better but are just easier to match. Your actual best-performing audiences get starved of budget.
How to Check Your Current EMQ Score
Go to Events Manager → Data Sources → your Pixel → Overview. Scroll down to "Event Match Quality" and select your conversion event (Purchase, Lead, etc.). Meta shows your current score and a breakdown of which customer information parameters you're sending.
The interface also shows parameter quality warnings. Common ones:
- "Email parameter quality is low" -- usually means emails aren't properly normalized or contain placeholder values
- "Phone parameter quality is low" -- phone numbers aren't in E.164 format or contain formatting inconsistencies
- "Name parameters are missing or low quality" -- first/last names contain test data, special characters, or are concatenated incorrectly
Click on any parameter to see specific issues Meta has detected.
What Breaks EMQ (And How to Fix Each One)
1. Placeholder and Test Data in Production
The most common EMQ killer. Your form processing code sends "test@example.com" or "N/A" when an email field is empty. Your phone field defaults to "000-000-0000" for users who don't provide a number. Meta sees these as valid parameters but can't match them to real users.
Check: Inspect your last 100 CAPI events in Meta Events Manager Test Events or your server logs. Look for:
- Emails: test@, example.com, noreply@, admin@, placeholder values
- Phone: 000-000-0000, 123-456-7890, (555) 555-5555
- Names: "test", "user", "firstname lastname"
- Addresses: "123 Main St", "N/A", "Same as billing"
Fix: Only send customer parameters when you have real data. If email is empty, don't include the email field in the CAPI payload at all. Meta handles missing parameters better than fake ones.
// Instead of this:
const userData = {
em: email || 'noreply@example.com',
ph: phone || '000-000-0000'
};
// Do this:
const userData = {};
if (email && email !== 'noreply@example.com') {
userData.em = hashEmail(email);
}
if (phone && phone !== '000-000-0000') {
userData.ph = hashPhone(normalizePhone(phone));
}
2. Email Normalization Issues
Emails must be lowercase and trimmed before hashing. But there are subtler normalization rules that most implementations miss.
Common failures:
- Gmail's dot ignoring: "john.doe@gmail.com" and "johndoe@gmail.com" are the same mailbox
- Gmail's plus addressing: "john+newsletter@gmail.com" and "john@gmail.com" are the same user
- Domain case sensitivity: Some servers treat "John@GMAIL.COM" differently than "john@gmail.com"
Fix: Normalize before hashing:
function normalizeEmail(email) {
if (!email) return null;
email = email.toLowerCase().trim();
const [localPart, domain] = email.split('@');
if (!localPart || !domain) return null;
// Handle Gmail dot and plus normalization
if (domain === 'gmail.com') {
const cleanLocal = localPart.split('+')[0].replace(/\./g, '');
return `${cleanLocal}@gmail.com`;
}
return email;
}
3. Phone Number Format Inconsistency
Meta expects phone numbers in E.164 format (+12125551234) but most sites collect them in local format (212-555-1234) with inconsistent formatting.
I've seen phone EMQ destroyed by:
- Mixed country codes (some have +1, some don't)
- Formatting characters (parentheses, dashes, spaces)
- Extension numbers appended (2125551234x123)
- International numbers without proper country codes
Fix: Convert everything to E.164 before hashing:
function normalizePhone(phone, defaultCountry = 'US') {
if (!phone) return null;
// Remove all non-digit characters except leading +
phone = phone.replace(/[^\d+]/g, '');
// Handle US numbers without country code
if (phone.length === 10 && defaultCountry === 'US') {
phone = '+1' + phone;
}
// Ensure it starts with + and has proper country code
if (!phone.startsWith('+')) {
if (defaultCountry === 'US' && phone.length === 11 && phone.startsWith('1')) {
phone = '+' + phone;
} else {
return null; // Can't determine country code
}
}
return phone;
}
4. Name Field Issues
Names look simple. They're not.
Full names stuffed into the first name field. Business names where a person's name should be. Honorifics that throw off matching. I've seen "Dr. John Smith" in fn more times than I'd like.
Fix: Strip honorifics, separate first/last, and lowercase before hashing. If you only have a full name field, split on whitespace. First token is first name, everything else is last name. Don't send the name field at all if it contains a business name.
5. Hashing Order
This one is subtle and I see it constantly: the code hashes the data before normalizing it. SHA-256 of "John@Gmail.com" and "john@gmail.com" produce completely different hashes. Meta can't match either one.
Fix: Always normalize first, then hash. No salt, no pepper, just SHA-256 on the cleaned string. And make sure you're actually using SHA-256, not MD5.
The Extra Parameters That Move the Needle
Once the five issues above are fixed, there are a few more parameters worth sending:
External ID. If you have a CRM customer ID, send it as external_id. It's often the highest-quality matching parameter because it's consistent across every interaction. Use the same value you send in offline conversion uploads and customer lists.
Click IDs. Pass fbp (Facebook browser ID) and fbc (Facebook click ID) from the client side through to your CAPI payload. These give Meta additional attribution context on top of the user matching.
Address fields. ZIP code, state, and country are low-effort, high-signal. States as 2-letter lowercase ISO codes, ZIP as 5 digits. Only send them when you have real data.
After fixing data quality issues, EMQ scores typically improve within 24-48 hours. The algorithm optimization benefits take 7-14 days as Meta rebuilds audience models with higher-quality attribution signals.
What You're Aiming For
Target EMQ by vertical: e-commerce 8+, lead gen 7+, B2B SaaS 6-8, mobile apps 6-7. Don't chase a 10. You can get there by only sending events with perfect data, but you'll exclude 30-40% of real conversions. EMQ 7-8 with maximum conversion coverage beats EMQ 10 with gaps.
Why This Keeps Breaking
EMQ degrades. Form changes introduce new placeholder text. CRM updates change how data gets normalized. A/B tests modify collection without updating the server-side processing. An engineer adds a third-party integration that starts sending test data through production.
After fixing EMQ across 15+ CAPI implementations, I typically see 2-4 point improvements in the first week and 15-35% ROAS gains over the following month. But keeping it there requires someone watching the pipeline. The fixes aren't hard. Knowing they need to be made before your ROAS starts sliding is the hard part.