About Tracking

Services

Google Ads Management Meta Ads Management Website Design & Build Local SEO Social Media Management Tracking & Conversions

Ad Platform Tracking

Meta Pixel + CAPI TikTok CAPI LinkedIn CAPI Snapchat CAPI Pinterest CAPI Quora Pixel Bing + UET Tag

Google Ecosystem

Google Ads Tracking GA4 Setup & Audit Google Tag Manager

Advanced Solutions

Server-Side Tracking Looker Studio Offline Conversion
Case Studies Blog Free Checklist Book Free Audit →
GA4 & GTMManufacturing SaaS · B2B CanadaCanada

Every booked demo looked like direct traffic — Calendly reset the session

91%Demo bookings now attributed to correct original traffic source
9%Genuine direct traffic — not artificially inflated
3xLinkedIn demo attribution restored — was showing as direct before

The situation

A Canadian B2B SaaS for manufacturing companies was using Calendly embedded on their pricing page for demo bookings. GA4 showed 80% of demo bookings as "direct" traffic. Their sales team knew demos were coming from Google Ads and LinkedIn but the data said otherwise.

The problem

Calendly embeds run in an iframe from calendly.com. When a user selects a time slot and submits their information inside the Calendly iframe, a new browser context is created. Any redirect that happens after booking goes through calendly.com, stripping all UTMs and resetting the GA4 session. The GA4 session_id, client_id, and attribution context were all lost at the moment of booking.

What we did

  1. Confirmed issue: GA4 session attribution in DebugView showed "direct" source immediately after Calendly interaction
  2. Implemented Calendly event listener via GTM — window.addEventListener("message") catching calendly.event_scheduled postMessage
  3. Pushed custom dataLayer event with stored UTM values (read from sessionStorage on page load) when Calendly booking confirmed
  4. Fired GA4 generate_lead event with traffic source parameters from stored UTMs — preserving original attribution

Why it worked

Calendly's iframe architecture breaks GA4 session continuity because the booking action happens on calendly.com, not your domain. The Calendly postMessage API is the only way to intercept the booking event from within your page context. Storing UTMs in sessionStorage on page load and reading them at booking time is the standard pattern for preserving attribution through iframe booking widgets.

“80% of our demo bookings showed as 'direct' in GA4 — we knew that was wrong. Saifur found that the Calendly embed iframe was breaking our session attribution. He set up a postMessage listener to capture the booking event and preserve the original UTM attribution. Now 91% of demos are correctly attributed.”
Sandra L.
Marketing Director · Manufacturing SaaS · Canada · May 2026