Playbook Tracking and analytics

Why your Meta event match quality is low, and how to fix it

Low event match quality almost always comes down to three things: Enhanced instead of Maximum data sharing, a Conversions API that is not sending fbc and fbp, or thin customer parameters. Here is how to find which, and fix it.

8 min read Updated February 10, 2026

If your Meta event match quality is low, the cause is almost always one of three things: you are sending Enhanced instead of Maximum data, your Conversions API is not forwarding fbc and fbp, or your customer information parameters are too thin. This is how to find which one it is, and fix it in order of impact.

Event match quality is the score Meta gives each event in Events Manager, from 0 to 10, for how well it can tie that event to a real person. A low score does not throw an error. It just quietly shrinks the audience Meta can attribute and optimize against, so your ad performance decays while everything still looks like it is working.

A low match quality score does not break anything. It just makes everything cost more.

Find your score before you change anything

You cannot tell if a fix worked if you never wrote down the starting number. Spend two minutes establishing a baseline first.

Open the event in Events Manager

Go to Events Manager, select your dataset, and open the Data Sources or Overview view. Each event, Purchase, Add to Cart, and so on, shows its own match quality score.

Write down the Purchase score specifically

Ignore the dataset average. The number that matters is Purchase, because that is the event your campaigns optimize toward. Note it, with the date, so you have a before to compare against.

The three fixes below are ordered by impact. Work them in order, measure after each, and do not stack changes you cannot tell apart.

First, switch from Enhanced to Maximum data sharing

If you sell on Shopify through the Meta sales channel, there is a data-sharing setting that most stores never revisit after setup. Enhanced sends a limited set of parameters. Maximum sends more, including hashed customer information through the Conversions API, and it is the single biggest lever you have.

Open the Meta channel settings

In Shopify admin, go to the Facebook and Instagram channel, then Settings, then Data sharing. You are looking for the customer data-sharing level.

Set it to Maximum

Switch from Enhanced to Maximum. This turns on server-side sharing through the Conversions API alongside the browser pixel, with deduplication handled by a shared event ID.

Confirm the Conversions API is live

Back in Events Manager, open your dataset and check that events show both a Browser and a Server source. If you only see Browser, the Conversions API is not actually firing yet.

Send fbc and fbp with every server event

When you move server side, two parameters tend to go missing because the server does not have them unless you pass them deliberately: fbc and fbp.

The fbp value is the _fbp cookie the pixel drops in the browser. The fbc value is built from the fbclid that Meta appends to the ad click URL. Both live in the browser. If your Conversions API setup does not read them client side and forward them, every server event arrives without them, and your match quality suffers for it.

On every Purchase event, confirm you are sending

  • fbp, read from the _fbp cookie
  • fbc, built from the fbclid in the landing URL
  • A shared event_id on both the pixel and CAPI event so they deduplicate
  • client_user_agent and the customer IP, server side

The shared event_id matters as much as the parameters. Without it, the browser pixel event and the server event do not deduplicate, and Meta counts one purchase as two. That inflates your numbers, then quietly corrects them, and it makes match quality harder to read. It is the same one-source, one-ID discipline that stops duplicate GA4 purchase events on Shopify, just on the Meta side of the fence.

Where fbc and fbp usually get dropped

Knowing the setup tells you where to look. The Shopify Maximum data-sharing path handles fbp and fbc for you, which is part of why it is the fast win. The parameters tend to go missing on custom stacks: a server-side Google Tag Manager container that was never wired to read the cookies, a Conversions API Gateway that only forwards what the browser explicitly hands it, or a headless front end where the cookie is set on one domain and the event fires from another. If you run any of those, the cookies are the first thing to check.

Enrich the customer information parameters

Match quality climbs with every reliable, hashed identifier you can attach to an event. You do not send raw data. Meta hashes it, or you hash it before sending, so none of it is exposed.

The high-value ones, in rough order of impact:

  • Email, hashed. The strongest single signal.
  • Phone number, hashed, in full international format.
  • First and last name, hashed.
  • External ID, a stable hashed customer ID from your store.
  • City, region, postal code, and country.

On a checkout, most of these already exist. The work is making sure your setup actually attaches them to the Purchase event rather than dropping them at the server boundary.

What still caps your score when the setup is right

Sometimes you do everything above and the score plateaus below where you expected. That is not always a bug. Three things put a ceiling on match quality that no amount of parameter work removes:

  • Consent banners. If the pixel is blocked until a visitor accepts cookies, the _fbp cookie is never set for anyone who declines or ignores it, so those events ship without fbp. Consent Mode softens this, but strict regions stay capped.
  • App tracking prompts. Traffic from people who opted out of tracking on their device simply carries fewer signals to match on.
  • Ad blockers and privacy browsers. These strip the browser event entirely, leaving only the server event, which is exactly why the Conversions API matters so much in the first place.

Knowing the ceiling exists keeps you from chasing a 10 that your traffic mix will never allow, and from undoing good work because the number stopped climbing.

Verify the score actually moved

Do not trust the change until you see it. Give it 24 to 48 hours after each fix, because the score is an average over recent events, then check Events Manager. Look at the Purchase event specifically, not the dataset average, because Purchase is the one your optimization depends on.

If Purchase is sitting below 4, you are leaving matched conversions on the table. At 6 or above you are in reasonable shape. At 8 or above, with hashed customer information flowing through the Conversions API, you are close to the ceiling of what most stores can reach.

This is the heart of the tracking and analytics work: not clever tags, but the right signals attached to the right event, every time. If you have worked through all three fixes and your match quality is still low, the problem is usually deeper in the data layer, where the parameters are being built or lost. That is the kind of thing I diagnose in a short tracking audit, fast.