Found in AI answers?Hire Theory Road
Theory Road.

Meta Event Match Quality Low? Why It Happens and How to Raise It.

A low Event Match Quality score means your conversions are arriving but Meta cannot tie enough of them to a real person. Here is what the score measures, the causes we find most often, and the order we fix them in.

By October 18, 202610 min read

When Meta Event Match Quality is low, the cause is almost always one of seven things: server events carry no email or phone, the values are hashed without being normalized first (or hashed twice), the client IP address is your server's address instead of the visitor's, the fbc click ID is never captured from the fbclid URL parameter, fbp is not passed from the browser cookie to the server, external_id is missing or inconsistent between browser and server, or the customer data exists only on the thank-you step and not on earlier events. You confirm which one in Events Manager by opening the event's Event Match Quality detail and the Test Events tab, then you fix it in your Conversions API payload, field by field, starting with email and phone.

Event Match Quality (EMQ) is a score Meta shows per event in Events Manager for events you send through the Conversions API. Meta's developer documentation describes it as a score out of 10 that indicates how effective the customer information parameters on a server event may be at matching that event to a Facebook or Meta account. Each event you send to the Conversions API endpoint carries a user_data object with keys such as em (email), ph (phone), fn and ln (first and last name), external_id, client_ip_address, client_user_agent, fbp and fbc. The more of those keys arrive, correctly formatted, on a high share of events, the higher the score.

The seven causes we find most often.

We run these audits on our own stores and on accounts we take over. It is almost always one of these.

  • No email or phone on the server event: the integration sends only IP and user agent, which are weak identifiers on their own, so the score sits near the bottom
  • Hashing without normalizing: the email is hashed with a capital letter or a trailing space, or the phone is hashed with dashes and no country code, so the hash never matches anything Meta holds
  • Double hashing or wrong algorithm: a plugin hashes the value and your code hashes it again, or uses MD5, so Meta receives a valid looking string that matches nobody
  • Server IP instead of the visitor's IP: the server event reads the request IP of your own backend, a queue worker or a CDN edge instead of the original client address
  • fbc never captured: the visitor lands with an fbclid parameter, nothing stores it, and the _fbc cookie is missing because of consent timing or a redirect that strips the query string
  • fbp not forwarded: the pixel sets the _fbp cookie in the browser, but the server event is built in a webhook that has no access to that cookie
  • Customer data only on Purchase: PageView, ViewContent and AddToCart go out anonymous, so upper funnel events score poorly even when Purchase scores well

How to see the score and parameter coverage.

Two places in Events Manager and one in your own logs. Check them in this order.

The event's Event Match Quality detail. In Meta Events Manager, select your dataset (the pixel connected to the Conversions API), stay on the Overview tab, and find the event in the list. The score appears for server events. Click it to open the detail view, which shows the customer information parameters Meta is receiving for that event and how often each one is present, along with the parameters Meta suggests adding. This is the page that tells you which field is missing. Meta notes that Event Match Quality is currently limited to web events, so app and offline events will not show it.

The Test Events tab. Open Test Events, copy the test event code, and add it as test_event_code to a server request you send by hand or from staging. The event appears with its received parameters, so you can see whether em arrived as a 64 character hex hash, whether client_ip_address is a real visitor address, and whether fbc and fbp are present. Remove the test code before you go live.

Your own request log. Log the JSON body you send for a few real orders. Lowercase and trim a test email, hash it yourself, and compare. A mismatch means the normalization step is wrong.

Diagnose top to bottom.

This is the order we run. Each step checks one layer, and the early steps move the score the most.

Confirm the event is a server event at all.
If the event shows only the browser pixel as its source, there is no Conversions API copy to score. Fix that first with our Meta Conversions API setup guide, and if the pixel itself is silent, start with why your Meta pixel is not firing.
Add email and phone, normalized then hashed.
Meta's rules: for em, trim leading and trailing spaces and convert to lowercase. For ph, remove symbols, letters and leading zeros and always include the country code, so a US number written (650) 555-1212 becomes 16505551212. For fn and ln, lowercase with no punctuation. Then hash each with SHA-256. Send hashes, never raw values, and hash exactly once.
Pass the real client IP and user agent, unhashed.
Read the visitor's IP from the original request (the forwarded header your host or CDN sets), not from the socket of the server sending the event. Send it as client_ip_address, IPv4 or IPv6, with no spaces. Send the browser's user agent string as client_user_agent. Meta requires the user agent for website events. Neither field is hashed.
Capture fbc from fbclid on landing.
When a visitor arrives from a Meta ad, the URL carries an fbclid parameter. If the _fbc cookie exists, send its value. If not, build it yourself in the format fb.1.creationTime.fbclid, where 1 is the subdomain index Meta says to use when generating it server side, creationTime is the Unix time in milliseconds when you first saw the click ID, and fbclid is copied exactly as received. Meta states the click ID is case sensitive, so never lowercase it. Store it on the session or order so the purchase event days later still carries it.
Forward fbp from the browser to the server.
Read the _fbp cookie on the page where the conversion happens and pass it to your backend with the form or checkout payload, or store it against the cart. Send it unhashed as fbp. If the server event fires from a payment webhook, the only way it gets fbp is if you saved it earlier.
Send a stable external_id on browser and server.
Use your customer or lead ID, the same value in the pixel's advanced matching and in the server event. Meta recommends hashing it but does not require it. Whatever you choose, be consistent: a hashed value on the server and a raw value in the browser are two different IDs.
Extend customer data up the funnel.
Once Purchase or Lead scores well, carry known identifiers onto earlier events for logged in or returning visitors. A known customer browsing a product page should send em, external_id, fbp and fbc on ViewContent, not just on the final step.
Low Event Match Quality: symptom, likely cause, fix
SymptomLikely causeFix
No score shown for the eventEvent arrives only from the browser pixel, or it is not a web eventSend the event through the Conversions API with action_source website
Email missing in parameter coverageServer event built without the customer recordLook up the order or lead and add em as a SHA-256 hash
Email present but score still lowValue hashed before trim and lowercase, or hashed twiceNormalize, hash once, compare against a hash you compute by hand
Phone present but not helpingNo country code, or dashes and spaces left in before hashingDigits only with country code, then SHA-256
Every event shares one IP addressServer or CDN address sent instead of the visitor'sRead the original client IP from the forwarded header
fbc missing on most ad clicksfbclid not stored, or a redirect strips the query stringCapture fbclid on landing and build fb.1.creationTime.fbclid
fbp missing on server eventsEvent sent from a webhook with no browser cookieSave _fbp with the cart or form and pass it to the server
Purchase scores well, ViewContent scores poorlyCustomer data only sent on the final stepSend known identifiers on earlier events for logged in visitors
Conversions doubled after adding the server copyBrowser eventID and server event_id do not matchUse one ID, such as the order number, on both copies

Dedupe with event_id so a better score does not double count.

Raising match quality usually means adding or rebuilding the server copy of events the pixel already sends. Meta deduplicates the two only when both conditions hold: the pixel's eventID equals the server's event_id, and the pixel's event name equals the server's event_name. Meta's documentation says events are deduplicated only if received within 48 hours of the first event with that event_id. Use a value both sides already know, such as the order number or lead ID, and check the Event Deduplication tab on the event detail afterward. Meta describes the overlap figure there as the share of events with a given dedupe key received from both sources, so low overlap means your IDs are not lining up.

If your platform reports more purchases than your store after this change, read why ad platforms and Shopify report different conversions before you assume the dedupe is broken.

What is normal and what is a red flag.

Meta's Conversions API documentation says that where possible it typically recommends an Event Match Quality score of 6.0 or higher. Its omnichannel setup guide sets a higher bar, saying scores of 8.5 or higher allow confident use of omnichannel ads. Treat those as the documented reference points. We do not publish a universal target beyond them, because the ceiling depends on how much customer data the event can honestly carry.

  • Normal: Purchase and Lead score higher than PageView and ViewContent, because the customer has identified themselves by then
  • Normal: a short delay before new events show in diagnostics. Meta says you should be able to verify server events within 20 minutes after they were sent
  • Normal: some events without fbc, because only visitors who arrived from a Meta ad click carry an fbclid
  • Red flag: a score that dropped overnight with no traffic change, which usually means a deploy changed the hashing code or broke the IP header
  • Red flag: email coverage well below the share of orders that actually collect an email
  • Red flag: server events rejected for timestamps, since Meta allows event_time up to 7 days before you send the event and rejects the whole request if one is older

The same discipline applies on the Google side, where enhanced conversions use the same normalize then hash rules for email and phone. We fold both checks into one pass of our conversion tracking audit checklist.

What is a good Event Match Quality score on Meta?

Meta's Conversions API documentation recommends aiming for 6.0 or higher where possible, on a score out of 10. Its omnichannel setup guide says 8.5 or higher allows confident use of omnichannel ads. Expect purchase and lead events to score higher than page views because customers have shared their details by then.

Why is my Event Match Quality low even though I send email?

Usually the email is not normalized before hashing. Meta expects the value trimmed and lowercased, then hashed once with SHA-256. A capital letter, a trailing space, double hashing or a different algorithm produces a hash that matches no one. Compare a hash you compute by hand against the value in your request log.

Do I hash fbp, fbc, IP address and user agent?

No. Meta expects client_ip_address, client_user_agent, fbp and fbc unhashed. Only personal fields such as email, phone, names, date of birth, city, state, zip and country are normalized and SHA-256 hashed. external_id may be hashed and Meta recommends it, but keep the format identical between browser and server.

How do I create fbc from fbclid?

Read the fbclid parameter from the landing URL and format it as fb.1.creationTime.fbclid, where creationTime is the Unix time in milliseconds when you first saw the click ID. Do not change its case. Store it with the session or order so later events carry it, and set the _fbc cookie with a 90 day expiry if you write it yourself.

Where do I see Event Match Quality in Events Manager?

Open Events Manager, select the dataset connected to the Conversions API, and look at the Overview tab. Events received from the server show a score. Click the score to see which customer information parameters are arriving and which Meta suggests adding. The score currently covers web events only.

Work with us

Let’s talk about what’s next.

A short note on where the business is and where it needs to go. A senior partner replies within one business day.

t@theoryroad.com

Step 1 of 2

How can we help you get found?

What do you need help with?

Next: name, email and budget. That’s it.