14. More Destinations & Enrichment
Google Ads enhanced conversions, TikTok Events API, and LinkedIn CAPI as variations of one recipe — plus the HTTP Request tag, backend webhook events, and enrichment patterns that only a server can do.
Chapter 13 ended with the observation that Meta's recipe — two legs, a shared event ID, hashed PII match keys, a quality score, a test console — is really the industry's recipe. This chapter cashes that in: three more platforms in a fraction of the space, then the two patterns that turn a tagging server from a relay into an asset — events flowing in from your backend, and enrichment on the way through.
Google Ads: enhanced conversions
Google's variant of the hashed-PII play is enhanced conversions — and
it's an augmenter, not a replacement. Ads attribution still runs on click
IDs (gclid → _gcl_*, Chapter 7's Conversion Linker — still mandatory).
Enhanced conversions attach normalized, SHA-256-hashed user data (email,
phone, name/address) to each conversion so that when the click-ID chain
breaks — ITP-shortened cookies, cross-device journeys — Google can recover
the join against its own logged-in users.
In the sGTM setup the flow is pleasingly boring by now:
- Web side: the Google tag collects user-provided data (a dedicated variable mapping email/phone fields or data layer keys) and it travels inside the GA4 stream to your server.
- Server side: the Google Ads Conversion Tracking tag (plus its server-side Conversion Linker companion) consumes the event, the click ID, and the user data, and reports the conversion server-to-server.
Two flavors exist — enhanced conversions for web (above) and for leads (you send hashed lead contact info; matching happens later when the CRM deal closes). The for-leads variant pairs naturally with the webhook pattern below.
TikTok: Events API
A near-verbatim Meta clone, which after Chapter 13 is a compliment:
server-to-server events endpoint, an access token generated in TikTok's
Events Manager (server-side secret — same rule, same audit findings),
event_id deduplication against the browser pixel, match keys from the
_ttp cookie and ttclid click ID riding your first-party requests, plus
normalized-and-hashed email/phone. Gallery templates (TikTok's own and the
community's) map GA4 event names to TikTok's vocabulary
(purchase → CompletePayment). Verification through TikTok's test-events
view. If you can run Meta CAPI cleanly, this is configuration, not learning.
LinkedIn: Conversions API
The B2B-flavored variant. LinkedIn's matching leans on its own logged-in
ecosystem: the li_fat_id click ID (cookie-captured by the Insight Tag,
Chapter 7) and hashed email are the workhorse keys. The conversions you send
server-side are matched against members and deduplicated against Insight
Tag conversions via a shared eventId on both legs (when both arrive, the
browser event wins). Where LinkedIn CAPI shines is exactly where browser tags
can't reach: CRM-stage conversions — the demo-became-opportunity event
that happens days after the site visit — pushed from your backend with the
stored identifiers. For pipeline-driven B2B, that's often the first
genuinely new data server-side delivers, not just recovered data.
One table, four platforms
Meta TikTok LinkedIn Google Ads EC
───────────── ───────────── ───────────── ───────────── ─────────────
server API Conversions Events API Conversions via Ads
API API conversion tag
dedup key event_id event_id event id vs transaction ID
vs pixel vs pixel Insight Tag (+ click join)
cookie keys _fbp, _fbc _ttp, ttclid li_fat_id gclid, _gcl_*
hashed PII em, ph, ext_id em, ph em em, ph, address
quality metric EMQ score match feedback match rate diagnostics tab
test console Test Events Test events — Ads diagnosticsSame dish, different seasoning — and all of them fed by the one GA4-format stream the browser sends (Chapter 10's N×M decoupling, now fully cashed).
The HTTP Request tag: the "anything" arrow
Chapter 10's diagram had an arrow labeled anything; this is it. The generic HTTP Request tag builds an arbitrary call — URL, method, headers, JSON body templated from event data — to whatever has an API:
- affiliate-network postbacks (server-side, finally un-blockable);
- your data warehouse's ingest endpoint (every event, first-party, no vendor in the loop);
- internal alerting ("purchase over €5k → ping ops").
No template, no vendor, no gallery review — which cuts both ways: it's also the server-side equivalent of Custom HTML (Chapter 6), so treat outbound URLs and payloads with the same audit suspicion.
Webhooks in: the backend as an event source
Everything since Chapter 12 assumed events born in a browser. Drop that
assumption — it's the last one left. A client (Chapter 10) can claim
any HTTP request, including a POST from Stripe, Shopify, or your own
backend:
Stripe webhook ──▶ POST pulse.shop.example/webhook/order-paid
│ custom client claims, maps to event model
▼
{ event_name:"purchase", currency, value,
em: sha256(order.email), event_id: order.id, … }
│ the SAME tags fan out
▼
GA4 · Meta CAPI · Ads · warehouseRefunds, subscription renewals, failed payments, offline store sales,
CRM-stage changes — revenue truth the browser never sees, entering the same
pipeline, deduplicated by the same event_id discipline (the webhook
purchase and the thank-you-page purchase carry the same order ID — dedup
handles the race for free).
The catch, and the pro move that separates working offline tracking from
wishful thinking: the backend event needs identifiers, and the backend
only has them if you saved them. At checkout, persist the tracking context
into the order record — client_id/FPID, _fbp, _fbc, gclid,
consent state. The webhook replays them days later, and suddenly a refund
can un-count the right conversion and a renewal matches the original ad
click. Without that stored context, backend events match on hashed email
alone — workable, weaker.
Enrichment: the checkpoint earning rent
The patterns that justify Chapter 9's "programmable checkpoint" framing, in ascending order of ambition:
- Normalization — one place to fix currencies, round values, map event-name dialects. Boring; priceless.
- Filtering — drop known bots, internal IPs, and junk before they poison five platforms' optimization. Client-side you filter in five places, after the fact; here, once, before.
- Lookup enrichment — Firestore Lookup (Chapter 10) or an HTTP call:
order ID → margin, product cost, customer LTV tier, lead score. The
flagship use: send profit, not revenue, as the conversion value, and
let Smart Bidding optimize on margin. Same campaigns, same spend,
meaningfully different outcomes — and structurally impossible to do
honestly in the browser (publishing your margins in
gtm.js— see Chapter 4 — is not a strategy). - Redaction — Transformations stripping PII per destination and per consent state, centrally (Chapter 17's enforcement arm).
Keeping it alive
A server pipeline fails differently than browser tags: not loudly at launch but silently, months later — an access token expires, a vendor bumps an API version, a template update changes a default. Production discipline:
- watch outbound failure rates (server preview shows per-tag responses while testing; in production, container logs and your host's monitoring — Chapter 15 — carry that duty);
- alert on volume cliffs per destination (Meta events dropping 40% overnight is a token, not a trend);
- calendar a quarterly re-verification: one test event through every destination, EMQ/match-quality review, token expiry audit.
Part 3 complete: you can now build the machine — transport, identity, destinations, enrichment, backend ingestion. What's left is judgment calls around it: where to run it (Chapter 15), what the managed vendors actually sell (Chapter 16), and what the law requires of it (Chapter 17).