Attribution & Analytics

Tracking Leads Across Subdomains and Multiple Funnel Domains

Funnels that hop between subdomains, page builders and booking tools lose the ad click along the way. Here's how to keep one session and one source from click to call.


Cross-domain tracking is the quiet reason a lot of funnels show “Direct” or “Unknown” for leads that obviously came from a paid ad. The visitor clicks a Meta ad and lands on www.yourbrand.com, opts in on go.yourbrand.com, watches a VSL on a page builder’s domain, books on a scheduling tool, and lands on a thank-you page back on your main site. Five hops. If the tracking loses the visitor at any one of them, the lead arrives in your CRM with no campaign attached.

This post explains why sessions break between subdomains and domains, how to keep a single visitor identity through the whole funnel, and how to check that it’s actually working before you spend another dollar on traffic.

Why sessions break between domains

Browser tracking relies on cookies and local storage, and both are scoped to a domain. Three different situations cause trouble, and they need different fixes.

Subdomains of the same root domain

www.yourbrand.com and go.yourbrand.com share a root domain, so in principle a cookie set on .yourbrand.com is readable by both. In practice, plenty of scripts set cookies on the exact host they run on, or store the session in local storage, which never crosses subdomains. The visitor becomes two anonymous sessions: one with the ad click, one with the form fill.

Completely different domains

Your main site is yourbrand.com but your funnel pages live on yourbrand.myclickfunnels.com or a separate funnel domain like getyourbrandoffer.com. No cookie can cross that boundary. The only way to carry identity is to pass it explicitly, typically in the URL.

Third-party tools in the middle

Booking tools, form tools and checkout pages are hosted on someone else’s domain, often inside an iframe. You don’t control their cookies. You can only pass identifiers into them (as URL parameters, hidden fields or embed metadata) and get those identifiers back via webhook or integration.

Most funnels have all three problems at once.

Map the funnel before you fix it

Before changing anything, write down every hop a real visitor takes. A simple table works:

Step URL / host Who controls it How identity crosses
Ad landing www.yourbrand.com/apply You Ad click ID + UTMs in URL
Application go.yourbrand.com/form You (page builder) Shared root domain
Booking Calendly embed Third party Session ID passed into embed
Thank you www.yourbrand.com/booked You Same root domain
Payment Stripe checkout Third party Email / customer match

The last column is the one that matters. For each hop, you need a concrete answer to “how does the tracking know this is the same person?” If the answer is “it should just work,” test it.

Keeping one session across subdomains

For hops between subdomains you own, the goal is a single first-party session that survives the move. Options, roughly in order of robustness:

  1. Use a tracking script that sets its session on the root domain. This is the cleanest fix. A session cookie on .yourbrand.com is visible on www., go. and apply. alike.
  2. Server-side tracking with first-party identifiers. Events sent from your server don’t depend on what the browser kept, as long as the server knows who the visitor is. See server-side tracking explained.
  3. Pass the session ID in links between subdomains. A fallback when you can’t change cookie scope, but fragile: one hard-coded link without the parameter and the session breaks.

In Callix, the pixel keeps a visitor’s session when your funnel moves between subdomains, so an application on www. and a confirmation page on go. are the same visit, and the conversion keeps the ad and UTMs from the first page. You don’t need to pass anything in links between your own subdomains.

Carrying attribution across separate domains

When a funnel crosses to a domain with a different root, you have to carry identity explicitly. The common patterns:

  • Decorate outbound links. Append the UTMs and ad click IDs (fbclid, gclid) to every link from domain A to domain B, and install the same tracking on domain B so it picks them up on arrival. This is what most “cross-domain tracking” settings in analytics tools do under the hood.
  • Pass a session ID. Instead of re-sending every UTM, pass one identifier that the tracking on domain B can use to look up the original visit.
  • Read forwarded links. Some signup and checkout pages carry the page a visitor came from inside their own URL, for example as a redirect or return parameter. Tracking that reads UTMs and click IDs from that inner link can fill in what the outer page is missing. Callix’s pixel does this, which recovers clicks that would otherwise land as Direct.

Whichever pattern you use, keep the same UTM conventions on every domain. Cross-domain tracking can carry a messy UTM perfectly; it just won’t make it less messy. If yours have drifted, start with a practical UTM setup.

Booking tools and forms on third-party domains

The booking step is where call-driven funnels most often lose attribution, because the conversion you care about most (a booked call) happens on someone else’s page.

The general approach is always the same: put your visitor identifier into the third-party tool, and make sure it comes back attached to the booking or submission. How you do that varies by tool:

  • Calendly: pass identifiers as UTM parameters on the embed or link, which Calendly returns in its webhook payload. Callix’s pixel passes the visitor’s session to Calendly automatically when the calendar is embedded on or linked from a tracked page.
  • Cal.com: pass the session as embed metadata. Callix documents passing it as metadata[callix_sid].
  • Typeform: add a hidden field for the session ID and populate it from the page. In Callix, a hidden field named callix_sid is filled by the pixel on embedded forms and links.
  • Custom forms posting to a webhook: include the click ID or session ID as a field in the payload, then map it on the receiving end.

The payment step

Payments are usually the last hop and the one most often left out of cross-domain planning. Stripe Checkout, course platforms and payment-plan providers all run on their own domains, and you generally can’t install your tracking on them. The practical approach is to stop relying on the browser at this step: pull payments in through the processor’s integration or webhook and match them to the lead by email, phone or customer ID. Pre-filling the checkout email from the lead record removes most of the matching failures before they happen.

Even with all of this, some leads will come through without an identifier, usually because they booked from a link in an email days later on another device. That’s normal. Your job is to make the unattributed share small and stable, not zero.

Reporting by funnel when you run several domains

Once identity carries through properly, the next problem is reporting. If you run three funnels on three domains (a webinar funnel, an application funnel and a low-ticket offer), you want each one’s performance separately, even when the same ad sends traffic to more than one.

Define each funnel by where traffic lands: a hostname, a path, or a combination. Then report leads, booked calls, show rate and revenue per funnel. In Callix, Funnels split reporting by the site your traffic landed on, and you can filter any widget, ad table or CRM tab by funnel. A table of campaigns filtered to one funnel lists only the ads that brought someone into it, so you can see which creative works for the webinar funnel versus the application funnel.

Funnel-level reporting also helps with conversion events. If each funnel has its own qualified-call definition, you can send a separate event per funnel to Meta rather than mixing them into one signal.

How to test that it actually works

Don’t trust a setup you haven’t walked through yourself. A good test:

  1. Open a private window and visit your landing page with fake UTMs and a test click ID, like ?utm_source=test&utm_campaign=xdomain-check&fbclid=test123.
  2. Walk every hop exactly as a prospect would, including the booking tool and thank-you page.
  3. Use a unique test email so you can find the record.
  4. Check the lead record in your CRM or attribution tool. Does it show the test campaign and the original landing page? Does the booking carry the same source?
  5. Repeat on mobile, ideally from inside the Instagram or Facebook in-app browser, which handles cookies differently.
  6. Repeat for every funnel and every booking tool. Each one is its own failure point.

Write down the result for each hop. If a step fails, you’ll usually see it as the source switching from your test campaign to Direct or blank at a specific step. That’s where to look.

Common mistakes to avoid

  • Assuming subdomains share sessions by default. Many scripts don’t. Test it.
  • Redirects that strip parameters. A link shortener or a “clean URL” redirect can silently drop UTMs and click IDs.
  • Hard-coded links in page builders. One button to the next step without parameter passing breaks the chain for everyone who clicks it.
  • Different tracking setups per domain. If domain B has a different pixel version or none at all, nothing carries.
  • Forgetting the thank-you page. If your conversion fires on a page without tracking, the conversion never ties back.

Get the funnel map right, carry one identifier from the first click to the booked call, and test it end to end every time a page builder or booking tool changes. That’s most of cross-domain tracking. The rest is checking it again after someone “just updates the form.” If you want the bigger picture of what breaks attribution, this audit guide covers it.

Book a demo