> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.pivolio.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.pivolio.com/_mcp/server.

# Match quality

An ad platform can only optimize against a conversion it can tie back to a
person who saw an ad. Send a purchase with nothing but an IP address and it may
match nobody; send the same purchase with a click ID and a hashed email and it
almost certainly matches.

**Match quality** is a 0–100 score summarizing how much matchable signal each
conversion carried when it left for a destination.

> **Warning**
>
> The score is computed **from what we send**, not from what the platform did with
> it. **No ad platform returns a per-event match score.** A 90 means you gave Meta
> excellent material to work with — it does not mean Meta found the user.

## How it's calculated

Each identifier a platform accepts carries a weight. The score is the summed
weight of the identifiers actually present, divided by the platform's summed
weight for **click ID + email + phone + IP + user agent**, expressed as a
percentage.

That denominator is the point. It's the realistic best case for a well
instrumented web conversion — not the sum of every field the platform will
accept. Fields outside the denominator (a browser ID, an external ID, a full
postal address) still add to the numerator, which is why a very complete event
can push the score high.

## Weights per platform

Each platform values identifiers differently, so the same event scores
differently at each destination.

#### Meta

| Identifier    | Weight |
| ------------- | ------ |
| `click_id`    | 35     |
| `email`       | 30     |
| `phone`       | 25     |
| `external_id` | 15     |
| `browser_id`  | 15     |
| `ip`          | 8      |
| `user_agent`  | 8      |
| `name`        | 8      |
| `zip`         | 6      |
| `city`        | 4      |
| `state`       | 4      |
| `country`     | 3      |

Meta accepts the widest set, so it's the platform where filling in address
fields actually moves the number.

#### Google Ads

| Identifier | Weight |
| ---------- | ------ |
| `click_id` | 40     |
| `email`    | 30     |
| `phone`    | 25     |
| `name`     | 8      |

Google weights the click ID highest of any platform and accepts the
narrowest set — `gclid` plus email does most of the work.

Note that hashed PII only reaches Google Ads if **enhanced conversions** is
enabled on the destination. It's off by default.

#### TikTok and Reddit

| Identifier    | Weight |
| ------------- | ------ |
| `click_id`    | 35     |
| `email`       | 30     |
| `phone`       | 25     |
| `external_id` | 15     |
| `ip`          | 8      |
| `user_agent`  | 8      |

Both use the same table.

The dashboard bands scores as **Excellent**, **Good**, **Fair**, and then red.

## Improving it

The weights tell you exactly where to spend effort, and it's the same short list
everywhere.

* **Collect email at conversion.** Worth 30 at every destination, and it's the
  identifier that survives longest — a click ID expires, an email doesn't. See
  [Identity resolution](/documentation/core-concepts/identity-resolution).
* **Collect phone where it's natural.** Another 25, and it matches people whose
  email you don't have.
* **Keep click IDs flowing.** 35–40 points, and the highest-confidence match
  there is. Don't strip query strings in redirects, and let click backfill
  attach earlier clicks to conversions that arrive without one.
* **Send server-side events with real context.** IP and user agent are only 8
  each, but they're free from a browser event and frequently missing from
  backend ones.
* **Fill the address fields for Meta.** Zip, city, state and country add up to
  17 at Meta alone.

> **Note**
>
> Consent shapes the ceiling. The browser SDK strips PII traits when
> `ad_user_data` is denied and click IDs when `ad_personalization` is denied, so
> those events genuinely carry less signal and score lower.
>
> Separately, a destination configured to *require* a denied category skips the
> send altogether — that event has no score for that destination rather than a
> low one. See [Consent & privacy](/documentation/core-concepts/consent-privacy).