How Do You Track Which Ad a Lead Came From?

To track which ad a lead came from, tag each ad's destination URL with UTM parameters, keep those values when the visitor submits a form, and store them on the lead record. Then the lead itself shows the campaign and ad. Tools like Trakt remember the UTMs in the same browser and record each form submission with them.

  1. Tag your ad links with UTMs. Every ad that drives traffic to your site carries utm_source, utm_medium, utm_campaign, utm_content, and optionally utm_term.
  2. Capture the UTMs at the form level. Hidden fields read the UTM values from the URL when the page loads and submit them silently with the form.
  3. Store the UTMs in the lead record. Map the hidden fields to custom CRM properties so the values stay with the contact through the funnel.
  4. Persist the UTMs across multi-page journeys. A first-party cookie keeps the values available when the form isn't on the page the visitor landed on.

The ad-to-lead chain, in four steps

A tagged ad URL is read by hidden form fields, CRM lead properties store the UTMs, and a first-party cookie carries them across pages.

If the CRM lead is missing its source, one of those links is broken, so the fastest fix is to find which one rather than rebuild everything.

Where Does the Ad Trail Break?

Each step has one common way of failing. Find the one that matches what you see in your CRM:

StepWhat goes wrongWhat you see
1. Tag ad linksInconsistent UTM naming (LinkedIn, linkedin, li)The same source split across several values
2. Capture at the formNo hidden fields on the form, the step most teams skipCRM leads with no source data
3. Store in the CRMUTM fields never created or mappedValues submitted but missing on the lead record
4. Persist across pagesThe form is on a page with no UTMs in its URLBlank source after a multi-page visit

Why Ad Platform Pixels Don't Match Your CRM Leads

Ad platforms tell you how many clicks your ads got. They'll also report conversions, if you install their pixel and define a conversion event.

The problem with pixel-based conversion tracking is that it lives in the ad platform's system, uses the ad platform's attribution model, and counts in the ad platform's favor. It isn't the same thing as a lead in your CRM, it doesn't tell you whether that lead became a customer, and when you compare it to your CRM data the numbers almost never match.

UTM-based tracking works differently. You tag your ad URLs, capture the parameters at the form, and store them in the lead record, so the record itself says "I came from this campaign."

How to Track Form Submissions by Source, Step by Step

Every ad that drives traffic to your site should have UTM parameters on the destination URL. The five parameters:

  • utm_source: the platform (google, facebook, linkedin, tiktok)
  • utm_medium: the channel type (cpc, paid-social, email)
  • utm_campaign: the campaign name (q2-enterprise-retarget, product-launch-may)
  • utm_content: the specific ad or creative (cta-demo, image-v2, carousel-a)
  • utm_term: optional, useful for Google Ads keywords (project-management-software)

A well-tagged URL looks like this:

https://yoursite.com/demo?utm_source=linkedin&utm_medium=paid-social&utm_campaign=q2-enterprise-retarget&utm_content=cta-demo

Build your tagged URLs with the Trakt UTM Builder. It keeps your naming conventions consistent, and inconsistent UTM naming (utm_source=LinkedIn vs. linkedin vs. li vs. Linkedin) is one of the most common reasons attribution breaks.

Step 2: Capture UTMs at the form level

Once a visitor lands on your page with UTMs in the URL, those UTMs need to survive the form submission. That requires hidden fields on every form. The hidden fields read the UTM values from the URL when the page loads, then submit them silently alongside the form.

This is the step most teams skip, which is why their CRM leads don't have source data.

Step 3: Store UTMs in the lead record

Your form captures the UTMs. Now they need to land in the right place in your CRM:

  • HubSpot: create custom contact properties for each UTM parameter and map the form hidden fields to those properties.
  • Salesforce: create custom Lead fields (UTM Source, UTM Medium, and so on) and map them in your form integration or Zapier workflow.
  • GoHighLevel: custom fields work the same way. Create them, then map the form fields.

Once the UTM values are in the lead record, they follow the contact through your funnel. When the lead becomes an opportunity, the UTM data is there, and when it closes, you can attribute that revenue.

Step 4: Persist UTMs across multi-page journeys

Here's a scenario that breaks Step 2: your ad sends someone to your homepage. They browse, read a blog post, move to your pricing page, then fill out the contact form. The UTMs were in the URL of the homepage, not the pricing page, so by the time they reach the form there are no UTM parameters left to read.

The fix is a first-party cookie. When a visitor first lands on your site with UTMs in the URL, store those values in a cookie. When any form on your site loads, check for the cookie and pre-populate the hidden fields from it, regardless of which page the form is on.

If you want each submission recorded with its ad source, pre-register for Trakt.

What You Can Answer Once It's Working

Once UTM data is flowing into your CRM, these are the questions you can answer directly from the lead record:

QuestionHow to answer it
Which campaign generated the most leads this quarter?Filter contacts by utm_campaign and count them.
Which ad creative drives the highest lead-to-close rate?Filter closed-won deals by utm_content and compare conversion rates by creative variant.
Are our Google Ads generating pipeline, or just traffic?Filter opportunities by utm_source=google and utm_medium=cpc. If the pipeline exists, it shows up.
Which channels should we cut?Sort channels by closed revenue, not lead volume. Channels that drive low-quality leads look worse measured by close rate than by form fills.

Why Ad Platform and CRM Attribution Never Fully Agree

Your ad platform's attribution and your CRM's attribution will not agree completely, and that's okay. Each ad platform counts conversions by its own rules, and none of those rules reflect what actually happened in your sales process.

CRM-level UTM attribution reflects the actual form submission with the actual campaign tag. It's more conservative, since it doesn't count view-through conversions, but it's also more accurate for understanding what is working. When leadership asks about ROI, the CRM number is the one that matters.

Tracking Ad Source Per Client for Agencies

If you manage paid campaigns for multiple clients, UTM hygiene matters even more. Every client's campaigns should have distinct, consistent UTM values that can't be confused with another client's.

Use a naming convention that includes a client code: utm_campaign=clienta-q2-retarget rather than just q2-retarget. Agree on the convention up front, so whoever builds the links that week uses the same one.

Why Manual UTM Capture Breaks in Practice (And How Trakt Closes the Gap)

The four steps above all work, and each one depends on someone doing the right thing every time. The weak points are predictable:

  1. Hidden fields get skipped. The setup lives on each form, so a new form or landing page can go live without it.
  2. Multi-page visits lose the UTMs. Without cookie logic on your site, the source is gone by the time the visitor reaches the form.
  3. Naming drifts. Different people tag the same source differently, and reports fragment.

How Trakt closes the gap

Trakt stores UTM values in a first-party cookie on first landing and injects them into hidden fields on any form page, even if the visitor has navigated away from the original landing page. Per-client UTM templates can be stored in Trakt's dashboard, so whoever builds the links uses the correct naming convention. It handles the capture and persistence, so leads reach your CRM with their ad source attached. See how Trakt tracks forms.

Manual UTM Capture vs. Trakt, By Requirement

RequirementManual (DIY)Trakt
Hidden fields on formsAdded to every form, per form platformInjected into hidden fields on any form page
UTMs across multiple pagesNeeds your own cookie and pre-fill logicFirst-party cookie set on first landing
Naming consistency per clientA convention people have to rememberUTM templates stored per client in the dashboard
CRM property setupSame either way: create the custom UTM fields and map them in HubSpot, Salesforce, or GoHighLevelSame either way: create the custom UTM fields and map them in HubSpot, Salesforce, or GoHighLevel

Frequently Asked Questions

How do I track which ad a lead came from?

Tag every ad's destination URL with UTM parameters, capture those parameters in hidden fields on your forms, and map the fields to custom properties in your CRM. The lead record then carries the campaign and ad that produced it. Use utm_content to identify the specific ad or creative.

Do I need a tracking pixel to see which ad drove a lead?

No. A pixel lives in the ad platform's system, uses its attribution model, and rarely matches the leads in your CRM. UTM-based tracking puts the source on the lead record itself, so you don't have to cross-reference ad platform dashboards.

How do I keep UTMs when a visitor browses several pages before filling out a form?

Store the UTM values in a first-party cookie when the visitor first lands on your site. When any form loads, check for the cookie and pre-populate the hidden fields from it, regardless of which page the form is on. Without that, the UTMs stay behind in the URL of the first page.

How do I track form submissions by source in HubSpot, Salesforce, or GoHighLevel?

Create a custom property or field for each UTM parameter, then map the form's hidden fields to them. In HubSpot these are custom contact properties, in Salesforce custom Lead fields, and in GoHighLevel custom fields. Once the values are stored, you can filter contacts and deals by source, campaign, or creative.

How do I track ad source when I run campaigns for multiple clients?

Use a UTM naming convention that includes a client code, such as utm_campaign=clienta-q2-retarget instead of q2-retarget, so one client's campaigns can't be confused with another's. Keep templates per client so everyone who builds links follows the same convention.