Opens in a new tab
Home/Blog/Event Match Quality: what the score means and how to raise it

Event Match Quality: what the score means and how to raise it

Server-Side Tracking ExplainedPhillip StemannOctober 14, 2026

Last updated: October 19, 2026

Title card reading Event Match Quality: what the score means and how to raise it, on a dark slate background with an orange glow
In this article
Key takeaways
  • Event Match Quality (EMQ) is a score out of 10 for how well the customer information on a server event can be matched to a Meta account. Per Meta, it is currently available only for web events, and it is calculated for each event, not for your account as a whole.
  • Meta names email, client IP address, first and last name, and phone as the high-quality parameters. It also asks you to keep fbp and fbc fresh. Meta does not publish a point value for each parameter, so any guide quoting exact weights is guessing.
  • Events made up only of weak fields are rejected, not merely scored low. Examples from Meta: fn + ge, db + client_user_agent, or city, state, zip, country and gender with a user agent.
  • On WordPress, most of the work is capturing identifiers where they exist (checkout, forms, cookies, the visitor’s request) and carrying them to the moment the server event is sent.
  • Meta’s setup guide suggests aiming for a score of 6.0 or higher. A PageView from an anonymous visitor and a Purchase with a billing address are never going to score alike, and that is normal.

You open Events Manager and your Purchase event shows a middling Event Match Quality score. Another event, a plain PageView, shows a different one. Neither tells you what to fix. This post explains what the score actually measures, what Meta documents about the parameters behind it, how to collect each one on a WordPress site, and in what order to improve things.

I fetched Meta’s developer documentation in October 2026 and link each fact inline. Meta’s Business Help article on Event Match Quality did not load for me in a readable form, so I rely on the developer docs and say plainly where a detail could not be confirmed. If you have not set up the Conversions API yet, start with our complete guide to the Meta Conversions API for WordPress.

What Event Match Quality measures

Meta’s best-practices page describes it this way: an event’s EMQ score, out of 10, “indicates how effective your server event’s customer information may be at matching it to a Facebook or Meta account.” The same page notes that EMQ is currently available only for web events. Meta’s verifying-setup guide adds that you should aim for a score of 6.0 or higher to help decrease cost per action.

Three things follow from that wording:

  • It is about the customer information, not the event itself. A Purchase with perfect value and currency but no email scores no better for it. EMQ looks at who the event is about, not what happened.
  • It is per event. Your Purchase, Lead and PageView events each carry their own score, because each carries different data. There is no single account-wide number to chase.
  • It matters because only matched events do any work. Meta states that you can use only matched events for ads attribution and ad delivery optimization, and that higher matching quality produces better results. An unmatched event is a conversion Meta received but cannot attach to anyone.

That is also why EMQ is a diagnostic rather than a trophy. A high score means your identifiers are rich and well formatted. It does not mean your tracking is complete, deduplicated or correctly valued. For deduplication, see our event_id explainer.

What contributes to the score

The inputs are the customer information parameters in the user_data block of the request. Meta’s best-practices page singles out four as high-quality: email (em), IP address (client_ip_address), name (fn and ln) and phone number (ph). It also says fbp and fbc should be refreshed regularly, and the parameters page recommends external_id and stresses sending country “even if all of your country codes are from the same country”, because Meta matches on a global scale.

What Meta does not publish is a formula. I found no official statement that email is worth a given number of points, or that adding phone moves a score by a given amount. Many third-party blog posts quote exact weights and “benchmark” scores. I could not trace those to Meta, so I do not repeat them. The diagram below therefore ranks parameters by what Meta explicitly names, and nothing finer.

Three tiers of Meta customer parameters: email, phone, names and IP named as high-quality; fbp, fbc and external_id as browser and ID signals; address, country, gender, birth date and user agent as supporting fields
A qualitative ranking from Meta’s documentation, October 2026. Meta does not publish numeric weights per parameter.

In practice the tiers mean this:

  • Identifiers that point to a person (email, phone, name) are the strongest levers, and each is also the one a visitor has to hand over.
  • Technical signals (IP, fbp, fbc, user agent) are available on most web events without asking anyone for anything. They help, but they describe a browser, not a person.
  • Soft attributes (city, state, zip, gender, date of birth) are supporting evidence. Used alone they are not just weak, they can get the event rejected.

Why weak combinations get rejected

Since Graph API v13.0, Meta enforces rules about which parameter combinations are valid at all. The best-practices page lists the ones it rejects when they are all an event contains:

  • ct + country + st + zp + ge + client_user_agent
  • db + client_user_agent
  • fn + ge
  • ln + ge

Meta applies the same rule to subsets, and gives the example that an event with only ge, ct, st and country would be rejected as invalid. Every one of these is made of fields that are easy to collect and hard to match on. Add one stronger identifier, such as a hashed email or an IP address, and the event is no longer built from weak fields only.

This is a practical trap for forms that collect only a name and a city. The server sends what it has, Meta says no, and the lead never appears. Because one invalid event can also sink a whole batch, read the batch rules in the complete guide and log the response body for every request.

List of four parameter combinations Meta rejects when they are all an event contains, with a note that adding one stronger identifier makes the event valid
Combinations Meta rejects when they are the only customer data on an event. Source: Meta best practices, October 2026.

Where to get each parameter on a WordPress site

The score is only as good as what reaches the payload. On WordPress the identifiers appear at different moments, and most of the problem is carrying them from the moment they exist to the moment the event is sent.

Table of Meta parameters with the place each comes from on WordPress and the catch to watch for
Where each identifier lives on a typical WordPress or WooCommerce site.

Email, phone and names

These come from forms and checkout. WooCommerce has billing email, phone and first and last name on every order. Contact Form 7, WPForms, Gravity Forms and Elementor forms only have them if you added the fields, and many contact forms deliberately collect nothing but a message. If a form can legitimately ask for an email, ask. For form-specific wiring, see tracking form submissions in WordPress and Elementor form tracking beyond GA4. For shops, WooCommerce server-side tracking covers the order-side events.

Logged-in visitors are the easiest case: the account already holds their email and often their name and phone. A PageView or a Lead fired for a logged-in user can carry them without any form.

fbp and fbc

Per Meta, fbp is the browser ID stored in the _fbp cookie. fbc is the click ID in _fbc, built as fb.{subdomain_index}.{creation_time}.{fbclid}, and only exists when the visitor arrived from a Meta ad click with an fbclid in the URL. Both are sent in plain text. Meta’s Parameter Builder library gives rules worth keeping: capture the cookies early, ideally on landing, do not modify them, and remember that _fbc is case-sensitive and must never be lowercased.

The catch on WordPress is timing. A server event sent later, from a payment webhook or a queue, has no browser attached, so read the cookies while the visitor is still on the site and store them with the order or lead. In WooCommerce, order meta written at checkout works:

add_action( 'woocommerce_checkout_create_order', function ( $order ) {
    $order->update_meta_data( '_capi_fbp', sanitize_text_field( $_COOKIE['_fbp'] ?? '' ) );
    $order->update_meta_data( '_capi_fbc', sanitize_text_field( $_COOKIE['_fbc'] ?? '' ) );
    $order->update_meta_data( '_capi_ip', WC_Geolocation::get_ip_address() );
    $order->update_meta_data( '_capi_ua', sanitize_text_field( $_SERVER['HTTP_USER_AGENT'] ?? '' ) );
} );

That one hook also stores the IP address and user agent while the real visitor request is in front of you, which brings us to the next pair. Browsers also limit how long they keep some cookies, which is one more reason to capture early; our post on Safari ITP and WordPress cookies covers what that does and does not affect.

Client IP address and user agent

Meta says to always provide the real IP address, and not to hash it. The Parameter Builder guidance prefers IPv6 where available. client_user_agent is likewise sent in plain text.

Two WordPress-specific failure modes show up again and again:

  • Proxy or CDN addresses. Behind a CDN or load balancer, REMOTE_ADDR is the proxy’s address, not the visitor’s. Use your host’s documented forwarded-address header, or a helper like the WooCommerce one above, and check what it returns against a request from your own phone.
  • Webhook-sent events. If a payment gateway confirms the order by calling your site, the IP and user agent on that request belong to the gateway. Sending them to Meta attaches your payment provider to your customer. Capture the visitor’s values at checkout and send those.

external_id

This is your own identifier for a person: a WordPress user ID, a customer ID, a loyalty number. Meta’s parameters page says to match the format across channels, so the value on your Pixel events and on your server events should be identical. Hashing is recommended but not required. It is only available for visitors you can recognise, so in practice it means logged-in users and returning customers. It also feeds the fallback deduplication path described in our dedup rules reference.

Normalizing and hashing: where good data turns into bad data

A correctly captured email can still match nothing if you format it wrongly, because the hash of “Jane.Doe@Example.com ” is not the hash of “jane.doe@example.com”. Meta’s rules from the parameters page:

  • em: trim leading and trailing spaces, lowercase everything, then SHA-256.
  • ph: remove symbols, letters and leading zeros, include the country code. (650)555-1212 becomes 16505551212.
  • fn, ln: lowercase, no punctuation, UTF-8 for special characters.
  • ct, st, zp: lowercase, no spaces or punctuation; US state as a 2-letter code, US zip as the first 5 digits.
  • country: lowercase 2-letter ISO 3166-1 alpha-2 code.
  • ge: f or m. db: YYYYMMDD.

Do not hash client_ip_address, client_user_agent, fbp or fbc. And hash only once: Meta’s Parameter Builder notes say to apply normalization and hashing on either the client or the server, not both. Hashing an already-hashed value is a classic cause of a flat, low score. Our complete guide has the full hashing cheat sheet. Here is a PHP version for phone numbers, with the caveat that real-world numbers need proper parsing:

function tr_normalize_phone( $raw, $country_code = '45' ) {
    $digits = preg_replace( '/\D+/', '', $raw );   // symbols and letters out
    $digits = ltrim( $digits, '0' );                // leading zeros out
    if ( strpos( $digits, $country_code ) !== 0 ) {
        $digits = $country_code . $digits;          // add the country code
    }
    return hash( 'sha256', $digits );
}

The prefix check is deliberately naive: a local number that happens to start with the country code digits will not get one added. For production, derive the calling code from the customer’s billing country or use a phone-number library.

Before and after: the same purchase

This is what the difference looks like in the user_data block. The left payload is valid, but all Meta can match on is a browser. The right one adds the person.

Side by side Meta Conversions API user_data blocks: one with only IP, user agent and fbp, and one that adds hashed email, phone, names, country, external_id and fbc
Invented values; hashes are real SHA-256 digests of the example inputs, shortened. Field rules from Meta’s documentation.

Nothing in the second payload requires anything exotic. Every added field came from a checkout form or a cookie the site already had.

Checking EMQ in Events Manager

  1. Open Events Manager and select the Pixel or dataset that receives your server events.
  2. On the Overview page, click the event you care about. Meta’s verifying-setup guide describes this page and the Event Details view, including tabs for Event Freshness and Event Deduplication.
  3. Find the Event Match Quality section for that event and read the score. I could not confirm the exact layout of this section from Meta’s pages, and Meta changes the interface often, so look for the section by name.
  4. Third-party guides report that Events Manager also lists which customer parameters were received. Treat that as something to look for, not a guaranteed feature of your account.
  5. Check the connection method too. EMQ is about server events, so an event arriving only from the browser will not improve by changing server code.

Test with test_event_code first (see the testing steps in the complete guide), and when you make a change, make one at a time. A score that moves after you add phone numbers tells you something. A score that moves after you changed five things tells you nothing.

If you use a forwarding service, its delivery log is the other half of the picture: what was sent and how Meta responded for each event. Traculo’s delivery log, for example, shows the response from each integration per event, which is where you would spot an event Meta refused.

Realistic expectations by event type

I will not give you target numbers per event, because Meta does not publish any and the ones in blog posts come from agencies’ own accounts. Meta’s only stated guideline is the 6.0 or higher figure above. What you can reason about from the parameters is which events can plausibly carry which data:

Event Data usually available What to expect
PageView, ViewContent IP, user agent, fbp; fbc after an ad click; email and external_id only for logged-in users Mostly technical signals for anonymous visitors, so a lower ceiling. Do not judge your tracking by this score.
Lead Everything above, plus whatever the form collected: email, phone, name Depends almost entirely on the form fields. A name-only form has little to work with.
Purchase Billing email, phone, name, address, country; external_id for accounts The richest event you have, and the one most worth getting right, since it is usually the one you optimise on.

That table is reasoning from Meta’s parameter list, not measured data. Your own Events Manager is the benchmark that matters: compare your Purchase today with your Purchase after a change, not with a number in an article.

One more consideration: only send identifiers you are entitled to send. Collecting an email on a lead form and forwarding it hashed to an ad platform is a legal and consent question as well as a technical one. Our posts on server-side tracking and consent and Consent Mode v2 are the place to start, and your adviser has the final say.

A prioritized improvement checklist

If your score is low and you do not know where to start, work down this list. It follows the parameters Meta names, in the order they are cheapest to fix on WordPress.

Seven-step checklist to raise Event Match Quality: IP and user agent, email, phone and names, fbp and fbc, external_id, country and address, then check Events Manager
Priority order for WordPress sites. Not a scoring formula.
  1. Fix IP and user agent first. They are on every request and cost nothing, and wrong values (proxy or gateway addresses) are the most common silent error.
  2. Add hashed email wherever you have one. Checkout, lead forms, account sign-ups, logged-in users.
  3. Add phone, first name and last name with correct normalization.
  4. Carry fbp and fbc unchanged from landing to conversion.
  5. Add external_id for logged-in users, identical across Pixel and server.
  6. Add country, then city, state and zip where you hold them, never as the only customer data.
  7. Re-check Events Manager per event after the changes have been live on real traffic.

Frequently asked questions

What is a good Event Match Quality score?

Meta’s verifying-setup guide suggests aiming for 6.0 or higher to help decrease cost per action. It does not publish tiers or per-event benchmarks, so treat any other number as one site’s experience, not a standard.

Does EMQ apply to app or offline events?

Meta’s best-practices page says Event Match Quality is currently available only for web events.

Why does my PageView score lower than my Purchase?

A PageView from an anonymous visitor has no email or phone to send, only technical signals such as IP, user agent and the fbp cookie. A Purchase carries checkout data. A gap is expected, though I cannot give you its size from Meta’s documentation.

Can I just send more fields to raise the score?

Send more correct fields. Wrongly formatted values do not match, double-hashed values do not match, and weak-only combinations are rejected. Also only send data you are allowed to share with Meta.

Does a higher EMQ mean better deduplication?

No. Deduplication relies on event_name plus event_id, with a fallback on fbp or external_id. EMQ measures matching to an account. They are separate checks, and you need both.

Related reading

If you would rather see exactly what Meta received for each event, Traculo’s WordPress plugin forwards events to Meta and other ad platforms and logs each response. Check the server-side event tracking page and the integrations to see whether it fits your setup.

ShareLinkedInXEmail

About the author

Track what matters, without the guesswork

Traculo gives WordPress sites analytics, funnels and server-side event forwarding in one dashboard. Start on the free plan with 10,000 events a month.

Try Traculo free

Related articles

Title card reading GCLID, GBRAID and WBRAID: what they are and when each appears, on a dark slate background with an orange glow

GCLID, GBRAID and WBRAID: what they are and when each appears

What Google's click IDs are, when gclid, gbraid and wbraid appear, the upload rules, how WordPress loses them and how to capture them reliably.

Read more
Title card reading Google Ads offline conversions for WordPress leads on a dark slate background with an orange glow

Google Ads offline conversions for WordPress leads

Capture GCLIDs on WordPress, store them with each lead and upload qualified leads to Google Ads. Formats, limits, hashing and common errors explained.

Read more
Title card reading GA4 Measurement Protocol limits: the cheat sheet, on a dark slate background with an orange glow
Data Accuracy & AttributionOctober 19, 2026

GA4 Measurement Protocol limits: the cheat sheet

Every GA4 Measurement Protocol limit on one page: 25 events, 130 kB, 72 hours, reserved names, sessions, consent, validation and how to debug missing events.

Read more