What EMQ Enricher does
Meta Event Match Quality (EMQ) improves when Purchase and later events include hashed email, phone,
and click cookies. Checkout often has phone; a delayed COD fire or webhook often does not have
_fbp. EMQ Enricher stores identifiers from earlier events and fills empty fields
on the event that is firing now.
- Lookup: phone → email → Cookie Keeper
_pf_mid→_fbp - Fill empty only — incoming values always win
- Consent-safe — no PII restore/persist when GDPR Consent Mode denies
ad_user_data - Plans: Pro and Enterprise only (not Free, not Starter)
/g/collect
stay unchanged until you pick Automatic or Semi-automatic on the Power-up
(sGTM, default Off). Webhooks and COD still use POST /data.
Which requests are enriched
| Path | EMQ |
|---|---|
| POST /e, /track (incl. GET /e?k=&d=) | Yes (proxy) |
| POST /data | Yes (sGTM Data Client / COD fire) |
| /g/collect, /j/collect, /a/c, /a/j | Opt-in (Automatic or Semi-automatic) |
| /ck, Custom Loader scripts, /cod/hold | No (hold unchanged; fire via /data or /e is yes) |
Step 1 — Confirm Pro or Enterprise
The feature string is exactly EMQ Enricher. Free and Starter cannot enable it;
KV sync forces enabled: false even if someone toggles the setting.
This is not the geo Event Enrichment card (always-on for proxy containers).
Step 2 — Enable the Power-up
- Open your container in PixelFly → Power-ups.
- Enable EMQ Enricher (default is off). Wait a few seconds for KV sync.
- Or Edit container → EMQ Enricher toggle → Save.
No WooCommerce plugin setting is required. Cookie Keeper _pf_mid is optional lookup key #3.
On sGTM containers, choose Custom Loader restore under the Power-up:
- Off (default) — Custom Loader
/g/collectis unchanged. Use this until you are ready to canary. - Automatic — fill standard Event Data (email, phone,
_fbp). Tags just work. The GA4 Client also sees that PII. - Semi-automatic — write
enricher_ep.user_data.email,enricher_fbp, etc. Map those in sGTM so the GA4 Client does not get PII.
POST /data (Data Client / COD) always fills standard user_data when EMQ is on, regardless of this radio.
Step 3 — Know your container type
- Proxy — PixelFly tag, plugin, or GTM send JSON to
/e. Profiles fill automatically. Continue to step 4. - sGTM — custom domain (e.g.
server.yourstore.com) fronts server GTM. Pick Off / Automatic / Semi for Custom Loader, and keep Data Client for webhooks and COD. Continue to steps 5–8.
Step 4 — Proxy: send events to /e
Any POST /e (or GTM GET /e?k=&d= with Cookie forwarded) that includes
phone, email, _fbp, or _pf_mid writes an encrypted profile (TTL ~90 days).
A later Purchase with the same key gets empty CIP filled, then SHA-256 hashed for destinations.
curl -sS -X POST 'https://YOUR_FIRST_PARTY_DOMAIN/e' \
-H 'Content-Type: application/json' \
-H 'X-PF-Key: pf_live_YOUR_KEY' \
-H 'Cookie: _fbp=fb.1.1730000000000.1234567890' \
-d '{"event_name":"Purchase","event_id":"emq-test-1","user_data":{"ph":"01712345678"}}'
Send a second request with the same phone and no fbp — Meta CAPI should receive the restored cookie.
Step 5 — sGTM: Data Client on path /data
- Open the server GTM container (not web).
- Templates → Clients → import Stape Data Client.
- Accepted path:
/data(exact). Save and publish. - Meta CAPI / Google Ads tags that need restored identity: trigger on Client Name = Data Client.
PixelFly COD Approve & Fire already POSTs /data when fire path is sGTM —
those purchases are enriched when this Power-up is on.
Step 6 — Preview header (testing only)
To see /data in server GTM Preview (same pattern as COD):
- Server GTM Preview → ⋮ → Send requests manually → copy
X-Gtm-Server-Preview. - PixelFly → Power-ups → sGTM Preview header → paste → Save.
- Disable that Power-up after testing so live traffic is not sent to Preview.
Web Tag Assistant (GTM-… on the shop) is not server Preview.
Step 7 — Test POST /data
Replace the host with your PixelFly custom domain.
1 — Persist phone + fbp
curl -sS -X POST 'https://ddd.yourstore.com/data' \
-H 'Content-Type: application/json' \
-d '{"event":"purchase","event_name":"purchase","user_data":{"ph":"01712345678","fbp":"fb.1.1730000000000.1234567890"}}'
2 — Same phone, no fbp (should restore)
curl -sS -X POST 'https://ddd.yourstore.com/data' \
-H 'Content-Type: application/json' \
-d '{"event":"purchase","event_name":"purchase","user_data":{"ph":"01712345678"}}'
Bangladesh 01… phones are normalized to 8801… on all proxy and /data events.
Step 8 — Verify
- PixelFly Logs —
purchase(or similar) on path/data. Rows with a GA4measurement_idlikeG-…are collect — not EMQ. - Server Preview — Client = Data Client; Event Data shows filled
user_data.fbp. - Meta Events Manager — Test Events: hashed phone/email and fbp on that Purchase.
Optional — seed from the browser
With Custom Loader restore Off, add a web GTM Data Tag (or HTTP request)
to https://YOUR_SERVER_DOMAIN/data with user_data and cookies.
With Automatic or Semi-automatic, Custom Loader collect can also seed the profile.
Architecture
Event with phone / email / _fbp / _pf_mid
→ Worker EMQ (if Power-up on + Pro/Enterprise)
→ Fill empty CIP from D1 profile
→ Persist in background (never blocks tracking)
Proxy: POST /e → hash → Meta / GA4 / …
sGTM: POST /data → Data Client → your CAPI / Ads tags
sGTM: /g/collect Off | Automatic (standard keys) | Semi (enricher_*)
Not rewritten: /cod/hold /ck Custom Loader scripts
FAQs
Does this replay historical PageViews?
No. It only fills holes on the event that is firing now. Same event_id is not reused to send an old PageView.
Automatic or Semi-automatic?
Automatic fills standard Event Data so Meta/Ads tags work with no mapping.
Semi-automatic writes enricher_* keys so you map them in sGTM and keep PII off the GA4 Client.
Leave it Off unless you want Custom Loader collect restored (canary).
Why do I only see page_view + G-… in Logs?
That is GA4 collect through Custom Loader. It is only restored if Custom Loader restore is Automatic or Semi-automatic.
COD and webhooks still use JSON on /data, or a proxy container with /e.
Is Cookie Keeper required?
No. It only adds _pf_mid as a third lookup key. Phone, email, or _fbp is enough.
Does this replace Event Enrichment?
No. Geo / device / UTM enrichment on proxy stays always-on and separate.
What about consent?
Proxy skips restore/persist in GDPR regions when consent is denied.
sGTM /data skips if the event sets consent.ad_user_data (or consent_settings) to denied.