Server side conversion tracking
Server side conversion tracking sends a conversion from your server to an advertising platform, in place of, or alongside, a pixel in the visitor’s browser. This guide covers how it works with the Meta (Facebook) Conversions API and Google Ads, what the click identifiers do, and where consent fits.
Why conversions move server side
A browser pixel reports a conversion only if the pixel loads, runs and reaches the platform. Ad blockers, browser tracking protection, refused consent and pages that close before the request completes all lose conversions. The platform then optimises against an undercount.
A server side request has none of those failure points. It also gives you control over what is sent: the conversion and a match key, and nothing else unless you add it.
Click identifiers
When someone clicks an ad, the platform appends an identifier to the landing page URL:
| Platform | Parameter | Example |
|---|---|---|
| Meta | fbclid |
?fbclid=IwAR2x... |
| Google Ads | gclid |
?gclid=Cj0KCQ... |
The identifier is the platform’s own record of the click. Sending it back with a conversion lets the platform attribute the conversion to the click, without the platform needing a cookie or an email address.
The identifier arrives only on the landing page. A server side setup therefore has to capture it at landing and keep it with the session until the conversion happens.
The Meta Conversions API
Conversions are posted to the Graph API, to the events endpoint of a pixel:
POST https://graph.facebook.com/<api-version>/<pixel-id>/events
with an access token generated for the pixel. A minimal event:
{
"data": [{
"event_name": "Lead",
"event_time": 1790870400,
"action_source": "website",
"event_source_url": "https://example.com/signup/complete.html",
"event_id": "1782693098872-7xzwuxbzd-signup",
"user_data": {
"fbc": "fb.1.1790870112000.IwAR2x..."
}
}]
}
fbcis built from thefbclid:fb.1.<time the click was seen, in milliseconds>.<fbclid>.event_idlets Meta deduplicate when the same conversion is also sent by the browser pixel. Use the same value in both.event_timeis in seconds.
Meta accepts further user_data fields, such as hashed email, IP address and
user agent, which raise match rates. Each one is additional personal data
sent to Meta, and each one is a decision to make deliberately.
Google Ads
Google Ads takes server side conversions through conversion uploads: the
gclid, the conversion action, and the conversion time and value, sent
through the Google Ads API or an offline import. The principle matches Meta:
the click identifier from the landing URL is the match key.
The hard part is the definition
The request is the simple half. The difficult question is which sessions count as a conversion, and keeping that answer correct as the site changes. A conversion fired from a thank-you page breaks silently when the page is renamed. A conversion fired from a button click counts bots and double clicks.
How Clientlog does it
Clientlog already holds the two things a server side relay needs.
- The click identifier. Query strings are parsed into fields during
enrichment, so
fbclidandgclidon the landing page are captured with the session, with no extra instrumentation. - The definition. A conversion is a rule in your repository, evaluated
against the completed session, tested in CI, and deployed with
planandapply.
- rule_id: signup
tag: converted
description: Completed a signup, human traffic only
logic:
{"and": [
{"in": ["user.signup.success", {"var": "session.actions"}]},
{"==": [{"var": "session.ua.is_bot"}, false]}
]}
A relay attached to a rule sends a conversion to the destination you nominate when a session matches, keyed on the click identifier the platform placed in the URL. Bot sessions and sessions the rule excludes never reach the platform.
The relay is implemented and enabled per project on request during early access. It is off by default.
Consent
Sending a click identifier back to Meta or Google links that visit to a person’s advertising account. That is processing for advertising, and the statistical-purposes exception in PECR does not cover it. Treat the relay as advertising measurement: it needs a lawful basis, a place in your privacy notice, and, where device storage or tracking is involved, consent.
Clientlog itself stores nothing beyond the session identifier in
sessionStorage. The relay changes where data goes after it arrives, and
that change is yours to account for.
Checklist
- Capture
fbclidorgclidat landing and keep it with the session. - Define the conversion in one place, with a test.
- Exclude bots before sending.
- Send an
event_id, and reuse it in any browser pixel, for deduplication. - Send the minimum
user_datathat meets your match rate needs. - Record the lawful basis and consent position for the relay.
To discuss enabling the relay, see early access.