Server-Side Tracking with Meta Conversions API
A server-side GTM architecture that sends consent-aware, deduplicated events to Meta through the Conversions API alongside the pixel.
- Type
- Demonstration project
- Focus
- Server-side measurement
- Scope
- sGTM · Meta CAPI · Consent
- Environment
- Demo tagging server
Demonstration project. This is a demonstration project built in a demo environment to show how I approach this kind of work. It does not represent a real client, real data or real results.

01 Browser
Meta Pixel + web GTM
02 Server GTM
Server container
03 Meta
Conversions API
Overview
This project demonstrates how I design a server-side setup for Meta: the browser pixel and the Conversions API working together, with one shared definition of every event.
It is built in a demo environment to show the architecture and the reasoning behind it — particularly the parts that are easy to get wrong, such as deduplication and consent handling.
Business challenge
Adding the Conversions API to an existing pixel introduces a second source of the same events. Without a careful design, that causes new problems:
- The same conversion being counted twice — once from the browser, once from the server
- Browser and server events carrying different names, values or currencies
- Customer information being sent without a clear consent basis
- No reliable way to confirm what the server is actually sending
Solution
A single event definition in the web container feeds both the pixel and the server container, so the two routes can never drift apart.
- Web GTM container sends events to both the Meta Pixel and the server container
- A unique event ID is generated once in the browser and used by both routes
- The server container forwards events to Meta through the Conversions API
- Consent state travels with every event and is checked before forwarding
- Customer information parameters are normalised and hashed before sending
Implementation
01
Browser events
Standard events (PageView, ViewContent, AddToCart, InitiateCheckout, Lead, Purchase) are triggered from the data layer, each with a generated event ID.
02
Server container
A server-side GTM container on a first-party subdomain receives the events through a GA4 client and makes them available to server tags.
03
Meta CAPI
A Conversions API tag in the server container maps event data to Meta's parameters and sends it with the access token stored securely on the server.
04
Event matching concepts
Where the user has consented, hashed customer information (such as email and phone) and browser identifiers are included to help Meta match events to accounts.
05
Deduplication
The browser and server versions of each event share the same event name and event ID, so Meta keeps one and discards the other.
06
Consent considerations
The consent state from the consent platform is passed to the server. If marketing consent is not granted, the event is not forwarded to Meta.
Technology stack
Google Tag Manager
Google Cloud
Meta Conversions API
Meta Pixel
Google Analytics 4
Project visuals
A closer look at the build.
01 Browser
- User actionlead · purchase
- Data layerevent + event_id
02 Web GTM
Web containerconsent check
Meta Pixelbrowser event
03 Server GTM
Server containerfirst-party subdomain
04 Meta
Conversions APIserver event
Event flow
One event definition in the web container feeds both the pixel and the server container, which forwards it to Meta through the Conversions API.
{
"event_name": "Purchase",
"event_id": "evt_10482_a7f3",
"action_source": "website",
"user_data": {
"em": "3f6a…hashed",
"ph": "9b1c…hashed"
},
"custom_data": {
"value": 4999.00,
"currency": "INR"
}
}Illustrative payload · demo values
Server event payload
The server event mirrors the browser event: same name, same event ID, with customer information hashed before it is sent.
Marketing consent granted
- GA4forwarded
- Meta CAPIforwarded
- Google Adsforwarded
Events are forwarded to each platform with the agreed parameters.
Marketing consent denied
- GA4not sent
- Meta CAPInot sent
- Google Adsnot sent
Marketing events are not forwarded. Behaviour follows the consent configuration agreed for your site.
Consent considerations
Consent state is passed to the server and evaluated before any event is forwarded to Meta.
Browser · Meta Pixel
sent from the visitor's device
- event_name
- "Purchase"
- event_id
- "evt_10482_a7f3"
Server · Conversions API
sent from your server container
- event_name
- "Purchase"
- event_id
- "evt_10482_a7f3"
Same name + same ID
Counted once
deduplicated
Deduplication
Browser and server versions of the same conversion share an event name and event ID, so Meta counts it once.
Deliverables
What a project like this hands over.
- Architecture diagram of the event flow
- Server-side GTM container configuration
- Event mapping document (browser ↔ server)
- Deduplication and consent logic documentation
- Validation record from Meta's test events tool
Key learnings
What this kind of work teaches.
- Deduplication has to be designed in from the first event, not patched in afterwards.
- Generating the event ID once in the browser keeps both routes aligned.
- Consent must be evaluated on the server too — moving a tag server-side doesn't change what the user agreed to.
- Meta's own test tools are the fastest way to prove an implementation is correct.
Start a conversation
Need something like this?
Share a few details about your website and what you want to measure or build. I'll come back with how I'd approach it.
Prefer email? hello@talktohariom.in