Flexform logoFlexform
AnalyticsAttributionWorkflow

UTM Tracking and Embed Source Attribution in Forms: A Practical Guide

Atul Kumar· April 28, 2026· 9 min read
Source signals captured at session startURL query params?utm_source=google&utm_campaign=q2Embed parent URLcustomer.com/pricingsubmission.metadatautm + embed + geo + deviceJSONB column · ~2KBCRM recordHubSpot · SalesforceLead Source set
UTM parameters and embed parent URL ride on the submission record into the CRM as Lead Source.

The fastest way to lose attribution on a B2B lead is to ship a form that strips the UTM parameters. The campaign team spends $40,000 driving traffic to a landing page, the form submits, and the CRM record arrives with Lead Source set to "Web" — no campaign, no medium, no source. FlexForm captures the full UTM payload and the embed parent URL on every submission without a tag manager, an extra script, or a hidden-field hack.

This guide walks through how the capture works, how to map UTM data into Salesforce or HubSpot Lead Source, how embed parent URL tracking handles multi-site form rollouts, and where the data shows up across the analytics endpoint and the integration payloads.

What gets captured, automatically

When a respondent opens a FlexForm form, the frontend runs collectSessionMetadata() before the first field renders. The function pulls five values from the URL and one from the parent window, then posts them to the session-create endpoint:

{
  "utm": {
    "source": "google",
    "medium": "cpc",
    "campaign": "summer-launch",
    "term": "form builder",
    "content": "hero-cta"
  },
  "referrer": "https://google.com",
  "pageUrl": "https://flexform.app/f/abc123?utm_source=google&...",
  "embed": {
    "parentUrl": "https://customer-website.com/contact",
    "embedType": "iframe",
    "embedId": "widget-1"
  }
}

The payload lands in form_sessions.metadata at session start and is copied verbatim to form_submissions.metadata on submit. Both columns are JSONB, indexed for the metrics the dashboard uses but free-form enough for downstream queries the dashboard does not surface.

Mapping UTM to CRM Lead Source

UTM in the metadata is only useful if it makes it to the CRM. There are two ways to route the data into Salesforce or HubSpot.

  1. 1

    Native integration field mapping

    In the form's HubSpot or Salesforce action, add a mapping from utm.source to the hs_analytics_source / Lead Source field, and utm.campaign to the campaign property. The native integration reads metadata.utm.* directly — no hidden field required. This is the cleanest path and is what we recommend for new forms.

  2. 2

    Hidden fields with hideAlways

    If you need the UTM values to appear as form answers (for example, to power conditional logic on submit), add five short_answer elements with hideAlways: true and idSuffix matching the UTM parameter name. FlexForm pre-fills them from the URL automatically, and they land in the submission's values payload alongside the rest of the answers.

One gotcha: if your campaign team links to the form page (flexform.app/f/abc) directly, UTM parameters pass straight through. If they link to a marketing page that then embeds the form, the UTMs need to either be preserved in the embedded iframe URL or read from the parent window. FlexForm's embed reads from the parent window automatically when the embed is on the same origin; cross-origin embeds need the URLs preserved in the iframe src.

Embed parent URL tracking

FlexForm captures the parent page URL when the form is rendered inside an embed. This is the metric almost no competitor exposes, and it answers a question every marketing team eventually asks: which page on our site converts best?

For a single form embedded across a pricing page, a contact page, a blog post, and a partner micro-site, the analytics endpoint returns:

{
  "total": 1248,
  "embedCount": 312,         // 25% of submissions came from an embed
  "byEmbedHost": [           // aggregated from metadata.embed.parentUrl
    { "host": "yoursite.com/pricing",  "count": 142 },
    { "host": "yoursite.com/contact",  "count":  98 },
    { "host": "blog.partner.com/post", "count":  41 },
    { "host": "yoursite.com/blog",     "count":  31 }
  ]
}

That single chart usually retires an entire spreadsheet of A/B-tested embed placements. The pricing page converts 1.5x what the contact page does on the same form — the contact page copy needs the work, not the form. For multi-tenant SaaS where partners embed FlexForm widgets on their own sites, the same data tells you which partners drive volume and which need help with placement. Embed reference covers the configuration.

When UTM and embed source disagree

A common case: the campaign team runs a Google ad pointing at yoursite.com/pricing?utm_source=google&utm_campaign=q2. The pricing page embeds a FlexForm contact form. On submit, the metadata contains both:

  • utm.source = google, utm.campaign = q2 (from the URL preserved into the embed)
  • embed.parentUrl = yoursite.com/pricing (from the parent window)

The two values describe different things: UTM is where the visitor came from, embed parent URL is where the form was rendered. They are most useful as complementary attribution signals — UTM tells you which campaign earned the click, embed parent URL tells you which page on your site converted it. The analytics dashboard surfaces both in separate breakdowns; the CRM mapping can use either depending on which signal your funnel cares about more.

A worked example: a 30-day attribution audit

A FlexForm design partner ran a 30-day audit on a contact form embedded on five sites. They asked one question: which embed placements drive enough volume to justify the maintenance cost?

Embed parent URLSessionsSubmissionsTop UTM source
yoursite.com/pricing1840142google / paid
yoursite.com/contact221098direct
blog.partner.com/post-a61241partner / referral
yoursite.com/blog/feature-x48031twitter / social
docs.yoursite.com/guide2904direct

The docs embed converted 4 submissions on 290 sessions — 1.4%. The pricing embed converted 142 on 1,840 sessions — 7.7%. The team killed the docs embed (and the form-design effort that went with it), doubled down on the pricing-page copy, and reinvested the time into shipping a partner-specific variant for the partner blog. The decision took about ten minutes once the data was in front of them.

Frequently asked questions

What UTM parameters does FlexForm capture on a form submission?

FlexForm reads the five standard UTM parameters from the URL when the form session is created: utm_source, utm_medium, utm_campaign, utm_term, and utm_content. They are stored on the submission's metadata under the utm key and surface in the analytics endpoint's bySource aggregation. No tag manager and no extra script are needed — the capture is built into the embed and the hosted form URL.

How does FlexForm track which website a form was submitted from?

When the FlexForm embed loads inside another site, the script reads the parent window's URL via document.referrer (or window.parent.location when the embed is on the same origin) and stores it as embed.parentUrl in the submission's metadata. This lets you attribute submissions to specific landing pages, partner sites, or blog posts that embedded the same form.

Can I send UTM parameters into a hidden form field?

Yes. Add a short_answer field with hideAlways set to true and an idSuffix matching the UTM parameter name (utm_source, utm_campaign). FlexForm pre-fills the field from the URL automatically, and the value lands in the submission's values payload alongside the rest of the answers — ready to map into Salesforce or HubSpot as a Lead Source.

Does FlexForm work with Google Analytics or GA4 for attribution?

FlexForm's UTM tracking is independent of GA4 and runs even when GA4 is blocked. The two systems complement each other: GA4 sees the page visit, FlexForm sees the form submission with the same UTM payload attached. Because the UTM data lives on the submission record, attribution survives even when the respondent disables analytics cookies.

How does embed source tracking help with multi-site form rollouts?

When one FlexForm form is embedded on a marketing site, a pricing page, a partner portal, and a blog post, the embed.parentUrl field tells you which of those drives the most submissions. The analytics endpoint's embedCount surfaces the embed-vs-direct split at the form level, and the raw parentUrl per submission lets you drill into specific pages — useful for prioritising which embed placements to tune first.

Stop losing campaign attribution at the form

UTM and embed parent URL captured on every submission. Free Starter plan. Native HubSpot & Salesforce mapping on Founders.

Start Free →
A

Atul Kumar

Co-Founder & CTO, FlexForm