
Executive Summary – What You’ll Learn
- Using server-side conversions without client-side context
- What to do to enrich server-side ad conversion events
- Example of enrichment using Google Tag Manager and HubSpot Forms
- How this data can then be used in CDP to improve ad platform match rates downstream
Server-side conversion events let you optimize on actions that don’t happen in the browser. Some of the most valuable signals, like lifecycle changes, qualified leads, or revenue, happen after the initial session. If those events aren’t sent back to ad platforms, optimization is limited to surface-level activity.
We had a specific use case: when a HubSpot Contact moves through lifecycle stages, we wanted to send ad platforms conversion events. We wanted those events to include browser context and ad platform match identifiers for optimal match rates. This would unlock very high match rates in ad campaigns, on behavior that identifies a highly qualified ad target.
By providing ad platforms like Meta, LinkedIn, and Reddit, with richer data, we could ensure conversions were matched more accurately and improve campaign performance everywhere. Here’s the approach we took.
The Problem
We were already triggering server-side conversion events when a HubSpot Contact entered specific lifecycle stages.
However, those events lacked critical browser-level context:
- User agent
- Facebook _fbp
- Facebook _fbc
- Reddit Click ID (rdt_cid)
- Reddit UUID (rdt_uuid)
- Screen width
- Screen height
Without these identifiers, match quality in ad platforms suffers.
The challenge: How do we reliably capture client-side browser context and attach it to HubSpot Contacts so that it’s available later when lifecycle events fire server-side?
Architectural Decisions
We evaluated two approaches for getting browser context into HubSpot.
The first was form-based: create Contact properties, add hidden fields to forms, and populate them with JavaScript. When a form is submitted, the data is written directly to the Contact record.
The second was event-based: capture the same data in Segment and use a HubSpot Actions destination to upsert Contact properties in real time, bypassing forms entirely.
Both approaches work, but we ultimately chose the form-based route. It kept our CDP layer simpler and leaned on native HubSpot behavior, even if it meant updating forms.
What We Captured (and What We Didn’t)
We focused only on browser-accessible data that improves match rates:
- User agent
- _fbp and _fbc
- Reddit identifiers (rdt_cid, rdt_uuid)
- Screen dimensions
We avoided anything not reliably available client-side or unlikely to improve match quality (like IP address). That constraint kept the implementation clean and privacy-conscious.
If it doesn’t improve match rates, it’s not worth collecting.
Implementation
We used Google Tag Manager to capture key browser context like cookies, user agent, and screen size, and made those values available to both HubSpot forms and Segment events. We were able to leverage the HubSpot forms API to fill hidden fields.
On the HubSpot side, we created matching Contact properties and added hidden fields to all lead forms. When a form was submitted, those values were written directly to the Contact record.
From there, we updated our lifecycle workflows. When a Contact moved stages, a webhook sent the enriched data through Segment to ad platforms like Meta, LinkedIn, and Reddit.
The Outcome
By attaching browser context to server-side conversion events, we saw a significant lift in match rates across ad platforms. Events that previously struggled to with low match quality started resolving at a much higher rate.
That improvement had a direct impact on optimization. Instead of learning from partial or low-confidence signals, platforms can confidently associate downstream conversions with actual users and campaigns.
The result: better audience targeting, more reliable optimization, and performance that aligned more closely with real pipeline outcomes, not just on-site activity.
Why This Matters
Server-side conversions are more than moving event firing off the browser. They are about maintaining accurate attribution in a privacy-constrained ecosystem. Without browser context, match rates drop, optimization weakens, and campaign performance suffers over time.
By enriching Contacts early and carrying context forward into lifecycle events, we created a durable, scalable attribution pipeline. This pipeline supports Meta’s CAPI, LinkedIn’s Conversions API, Reddit’s Conversion API, and analytics reporting everywhere we needed it.
Key Takeaways
- Enrichment should happen before lifecycle transitions, with Contact properties serving as the durable storage layer
- Server-side events should inherit client-side match context
- Both form-based and event-based ingestion are viable; the right choice depends on your stack maturity and operational needs
- When done properly, enriched lifecycle events drive higher match rates, better ad performance, and more reliable attribution

Leave a Reply