HubSpot Meetings Conversion Tracking for Google Ads and GA4

HubSpot tracks the booking perfectly well, for HubSpot. The contact gets a source, the meeting lands on the timeline, the deal is created. What HubSpot does not do is tell Google Ads that the click it paid for turned into a booked call, which is why so many HubSpot accounts run ads optimised for form fills or page views while the meetings pile up untracked.

The embed gives you what you need. When a meeting is booked, HubSpot’s scheduler sends a message to the page it is embedded on. Catch it, push it to Tag Manager, and the rest is the same path as Calendly and Cal.com.

Done for you, same day

Booking conversion tracking setup, $199

HubSpot, Calendly, Cal.com or Tally wired to GA4, Google Ads and Meta, tested with a live booking on a call with your accounts open.

Book the setup

If bookings are only part of the problem

Tracking audit across the stack

GA4, Google Ads, Meta, HubSpot attribution and Shopify if you sell, reconciled against what actually happened. Scoped on a call first.

Book a call to scope it

HubSpot meetings tracking path: the embed posts meetingBookSucceeded to the host page, a listener pushes hubspot_meeting to the dataLayer, Tag Manager sends it to GA4 as a key event and to the Meta pixel, Google Ads imports the GA4 key event, and HubSpot keeps its own contact attribution with the click ID stored for offline conversions later

What you need

The HubSpot meetings scheduler embedded on a page you control, not a bare meetings.hubspot.com link. Google Tag Manager on that page. A GA4 property linked to Google Ads. The Meta pixel ID if you run Meta.

Step 1: catch the booking message

HubSpot’s embed runs in an iframe and uses postMessage to tell the parent page what happened. On the page with the embed, add:

<script>
  window.addEventListener("message", function (e) {
    if (e.data && e.data.meetingBookSucceeded === true) {
      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({ event: "hubspot_meeting" });
    }
  });
</script>

Make a test booking and check the browser console for hubspot_meeting in dataLayer. If nothing arrives, the scheduler is probably opened in a new tab rather than embedded; switch to the inline embed.

One trigger and two tags in Tag Manager: a Custom Event trigger named after the dataLayer event, a GA4 Event tag with the same name and the form or event type as a parameter that becomes a key event, and a Meta Custom HTML tag firing Schedule or Lead with an eventID for Conversions API deduplication

Step 2: trigger and tags in Tag Manager

Custom Event trigger on hubspot_meeting. A GA4 Event tag sending hubspot_meeting. A Meta Custom HTML tag with fbq('track', 'Schedule', {}, { eventID: '<unique id>' }). Publish, then verify both fire in Preview with another test booking.

Step 3: key event in GA4, import to Google Ads

GA4, Admin, Events, toggle hubspot_meeting to a key event. Google Ads, Goals, New conversion action, Import, Google Analytics 4, select it. Set it as primary if booked meetings are the outcome the campaigns should learn from. Screenshots for both are in the Calendly post; the steps are identical from here.

Step 4: keep HubSpot and Google Ads telling the same story

This is the part specific to HubSpot. Two things.

Store the click ID on the contact. HubSpot captures gclid on forms when the tracking code is present, or you add a hidden field. Either way, make sure the Google click ID is on the contact record. When that contact closes three weeks later, you can upload the deal as an offline conversion to Google Ads against the original click, and bid on closed revenue rather than booked calls.

Decide which number is the number. HubSpot attributes across sessions and channels, including the email that reminded someone to book. Google Ads attributes inside its own window. They will disagree, and that is fine. Google Ads is the number for bidding. HubSpot is the number for the pipeline. A gap over 40 percent means bookings are not reaching Google Ads at all, which is the problem this post fixes.

Step 5: a server side copy for Meta

Pixels miss bookings on iPhones and behind ad blockers. HubSpot can cover it: a workflow triggered on meeting booked, with a webhook action that posts to Meta’s Conversions API, email hashed, the same event ID as the pixel so Meta deduplicates. If you do not want a workflow doing HTTP, Zapier’s HubSpot trigger does the same.

What this gives you

Booked meetings in Google Ads by campaign and keyword, in GA4 by source, in Meta by ad, and in HubSpot by contact with the click ID attached for the day the deal closes. One container, one trigger, and the ad platforms finally see the outcome the pipeline is built on. If the meeting is booked from a form first, the Tally version tracks that step the same way.

If you would rather have it done, the setup at the top of this post is the same work on a call, tested with a live booking before we hang up.

Frequently asked questions

How do I track HubSpot meeting bookings in Google Ads?
The HubSpot meetings embed posts a message to the host page when a meeting is booked, with meetingBookSucceeded set to true. A short listener pushes that to the dataLayer, Tag Manager sends it to GA4, GA4 marks it as a key event, and Google Ads imports it as a conversion action. No thank you page involved.
Does HubSpot's own tracking code send bookings to Google Ads?
No. HubSpot's tracking code reports to HubSpot, where it attributes the contact to a source. Google Ads only learns about the booking if something on the page sends it to GA4 or to Google Ads directly. The two systems can agree on source, but you have to wire the ad platform side yourself.
Why do my HubSpot and Google Ads numbers disagree?
They count different things. HubSpot counts contacts and attributes by first or last touch across sessions, including email. Google Ads counts conversions inside its own attribution window, usually 30 days click. Expect Google Ads to show fewer. A gap over 40 percent usually means bookings are not reaching Google Ads at all, which this setup fixes.
Can I pass the Google click ID into HubSpot?
Yes, and you should. Add a hidden field or use HubSpot's tracking of gclid on the contact record so that when a booked meeting later becomes a customer, you can upload that as an offline conversion to Google Ads. The booking event is the leading indicator; the closed deal is the one worth bidding on.
Does this work with the meetings link on a HubSpot landing page?
If the page is hosted by HubSpot and you can add Tag Manager to it, yes, the same listener works. If you are sending visitors to a meetings.hubspot.com link with no page of your own, you do not control the page and cannot run a listener; embed the scheduler on a page you own instead.
Can I send HubSpot bookings to Meta as well?
Yes. The same Tag Manager trigger fires a Meta pixel Schedule event. For a server side copy, a HubSpot workflow on meeting booked can call a webhook that posts to Meta's Conversions API with the contact's email hashed and the same event ID.
Nikhil Sharma

Nikhil Sharma

I run data and operations for a DTC brand on Shopify, consult on Meta and Google Ads, and build AI automations for ecommerce teams. I write about what I build and run.

Book a call More about me