Tracking, Attribution, and Enrichment
Analytics vendors, ad conversions, lead journeys, UTM attribution, and real-time enrichment on SDK forms
An SDK form reports the same funnel signals a hosted form does, almost all of it automatically.
Vendor tracking
When the form's settings carry tracking IDs, the SDK bootstraps the vendors and fires the same events as native forms: SurfaceFormStarted, SurfaceFormStepSubmitted, and SurfaceFormSubmitEvent on GTM's dataLayer, Meta trackCustom, and GA4 events.
- Configure in the dashboard (Tracking & Analytics) or over MCP with
update_form_settings(gtmId,gaMeasurementId,metaPixelId,trackPartialResponses,trackCookie). Ad conversion rules and HubSpot tracking are dashboard-only. - Or pass at init:
SurfaceForms.init({ settings: { gtmId, gaMeasurementId, metaPixelId, adsConversions } }). Caller values win.
Ad conversion rules fire once per rule per response, queue until the first save produces a responseId, and terminal rules fire on completion only, never on disqualify. A booking fires the meeting_booked trigger.
Verify on a deployed page: complete a step, inspect window.dataLayer for SurfaceFormStepSubmitted. Preview mode blocks tracking entirely. form.capabilities.tracking reports whether tracking is active.
Lead journey and attribution
All on by default:
- Page-view journey: the
journeyoption tracks page views with the same cookies the Surface Tag uses and stamps the journey ID onto every response. Passjourney: falseonly where the Surface Tag already runs, to avoid double-counting. - URL attribution: the form's URL, query parameters (UTMs), and referrer ride every save.
- Visitor identity:
initidentifies the visitor in the background with the Surface Tag's identity cache; boot never waits, the first save does. After an SPA route change, callform.identify().
URL prefill
Same prefill query syntax as hosted forms: ?<questionId>_<fieldName>=value seeds an answer (splits on the first underscore; url, referrer, cookies are reserved).
Real-time enrichment
With an enabled enrichment provider, a valid email or website domain on the record's enrichment source field triggers enrichment, and the result rides every save as enriched lead attributes. Deduplicated per value, never fired in preview.
No enabled provider means enrichment is silently inert, even if the record declares a source field. Check form.capabilities.enrichment; debug: true warns about the mismatch at boot.
To autofill your own inputs from the result, read state().externalStates.selfServeEnrichment.data via subscribe.
What lands on the response
- Every answer, shaped as the binding map's
answerShape. meta.surfaceTagStatus: "sdk"(distinguishes SDK from hosted submissions).meta.userJourneyIdplus the stitched page-view journey.- URL, UTM parameters, and referrer.
- Email validation verdicts, enriched fields, and
meta.customvalues frommergeMeta.