# Advanced Matching (/docs/sdk/advanced-matching)



CAPI / Events API let you send hashed PII to improve match rates beyond
just IP + UA. The match happens platform-side: Meta / TikTok hash the
same fields from their own user records and look for overlap.

## How the Layers relay handles PII [#how-the-layers-relay-handles-pii]

Emails and phones can be passed **unhashed** — the server-side relay
does the SHA-256 normalization before forwarding to Meta / TikTok:

* **Email** — lowercased + trimmed → SHA-256 hex.
* **Phone** — all non-digit characters stripped → SHA-256 hex. E.164
  format (`+15550100`) is strongly recommended so the digit stripping
  yields a stable, complete number.

If you prefer to pre-hash client-side, pass the hash directly (see the
field list below).

## Supported fields [#supported-fields]

The relay currently forwards these matching fields to Meta and TikTok:

| Field                           | Meta `user_data` key   | TikTok `user` key      |
| ------------------------------- | ---------------------- | ---------------------- |
| `email` or `email_hash`         | `em`                   | `email`                |
| `phone` or `phone_hash`         | `ph`                   | `phone`                |
| `app_user_id` / `install_id`    | `external_id` (hashed) | `external_id` (hashed) |
| IP address (server-injected)    | `client_ip_address`    | `ip`                   |
| User agent (server-injected)    | `client_user_agent`    | `user_agent`           |
| `idfa` (iOS, consented)         | `madid` (plaintext)    | —                      |
| `country_code`                  | `country` (hashed)     | —                      |
| `subdivision1_code`             | `st` (hashed)          | —                      |
| `client_city` (server-injected) | `ct` (hashed)          | —                      |
| `_fbp` / `fbp`                  | `fbp`                  | —                      |
| `_fbc` / `fbclid`               | `fbc`                  | —                      |
| `ttclid`                        | —                      | `ttclid`               |
| `locale`                        | —                      | `locale`               |

Fields prefixed with `$attribution_click_id_*` are used by the attribution
pipeline to bridge click IDs across batches.

## How to send [#how-to-send]

Pass via `setUserProperties`:

```ts
await layers.setUserProperties({
  email: 'user@example.com',
  phone: '+15550100',
});
```

Or per-event in `properties`:

```ts
await layers.track('purchase_success', {
  revenue: 9.99,
  currency: 'USD',
  email: 'user@example.com',
  phone: '+15550100',
});
```

## Pre-hashing (optional) [#pre-hashing-optional]

```ts
import { createHash } from 'crypto'; // Node
const emailHash = createHash('sha256')
  .update('user@example.com'.trim().toLowerCase())
  .digest('hex');

await layers.setUserProperties({ email_hash: emailHash });
```

## What does NOT happen [#what-does-not-happen]

* **First name, last name, DOB, zip, city** are NOT currently part of
  the relay's Meta/TikTok payload (previous docs listed
  `first_name_sha256`, `last_name_sha256`, `dob_sha256`, `zip_sha256` —
  these are not forwarded). If you need them, let the team know.
* **Apple Search Ads** does not use advanced matching — ASA attribution
  is token-based.
