Analytics & tags

Google Tag Manager for Microsoft Bookings

The standard Microsoft Bookings page runs on Microsoft's domain, so the Google Tag Manager container on your site never sees a booking happen. The BookingsXP widget runs inside your page and pushes each step of the booking to your page's dataLayer, so GTM can fire any tag you like on a real, confirmed booking.

Plan
Plan: FreeWorks on every plan, including Free ($0, no card).
In short
Ten bookingsxp.* dataLayer events for Custom Event triggers, with service, slot and booking reference.
Microsoft Bookings
Stays your system of record. Bookings land in Outlook and Teams and Microsoft sends the invites and reminders.

How it works

What happens with Google Tag Manager

  • The widget is an iframe served by BookingsXP. The small loader script on your page listens to it over postMessage, accepting messages only from the BookingsXP origin.
  • For every step, the loader runs window.dataLayer.push({ event: "bookingsxp.<step>", bookingsxp: { … } }) on your page. It creates window.dataLayer if your page has none.
  • The payload under bookingsxp carries the widget ID, business name, service (id, name, duration, price and currency when Bookings has a price), staff, slot (ISO start and end plus the IANA time zone) and, on completion, the booking reference (BXP-XXXXXX).
  • bookingsxp.booking_completed fires only after Microsoft Bookings has confirmed the appointment, so it is safe to use as your conversion trigger.
  • The push works in link-only mode too (no account, just your public Bookings link), because it happens on your page, not on ours.

Setup

Set up Google Tag Manager

5 steps. Names of menus and buttons are as they appear today; vendors rename things, so look for the closest match.
  1. Step 1: Embed the widget with the script

    Paste the script and the custom element on the page where people book. The script embed is what talks to your dataLayer; a plain iframe cannot. If you use a saved widget, the Tracking tab's "Push events to dataLayer" switch is on by default.

    HTML
    <script src="https://bookingsxp.com/embed/v1.js" async></script>
    <bookingsxp-widget widget="w_8fk2m1qz"></bookingsxp-widget>
  2. Step 2: Create Data Layer Variables

    In GTM go to Variables → User-Defined Variables → New → Data Layer Variable (version 2). Dots in the name read nested keys, so create one variable per field you need.

    Data Layer Variable names
    bookingsxp.service.name
    bookingsxp.service.price
    bookingsxp.service.currency
    bookingsxp.staff.name
    bookingsxp.slot.start
    bookingsxp.booking.id
  3. Step 3: Add a Custom Event trigger

    Triggers → New → Custom Event. For the conversion, set Event name to bookingsxp.booking_completed. To catch the whole funnel in one trigger, use ^bookingsxp\. and tick "Use regex matching".

    Trigger event names
    bookingsxp.booking_completed      (conversion)
    ^bookingsxp\.                     (every step, regex)
  4. Step 4: Attach your tags

    Fire a Google Analytics: GA4 Event tag, a Google Ads Conversion Tracking tag, or any Custom HTML tag from that trigger. For de-duplication, map {{DLV - bookingsxp.booking.id}} to the tag's transaction or order ID field.

  5. Step 5: Test in Preview mode

    Open GTM Preview (Tag Assistant), load your booking page and step through the widget. You should see bookingsxp.widget_viewed, then date, slot and form events. A test booking is a real appointment in Microsoft Bookings, so cancel it afterwards.

Outcomes and caveats

What you get

The result

  • Ten events: widget_viewed, service_selected, staff_selected, date_selected, slot_selected, form_started, booking_submitted, booking_completed, booking_failed and no_availability.
  • A conversion event that fires on Microsoft's confirmation, not on a button click.
  • The BXP booking reference to use as a transaction ID, so one booking counts once.
  • Funnel drop-off you can analyse in any tool GTM feeds, including no_availability (people who found no open time).

Good to know

Limits and caveats

  • Only the script embed, the framework components and the WordPress plugin push to your dataLayer. A plain iframe cannot reach your page's JavaScript.
  • Names, emails and phone numbers are never pushed to the dataLayer. The only customer-derived value is a SHA-256 email hash, and only when a Pro widget has enhanced conversions switched on.
  • If you also set a GA4 measurement ID on the widget, GA4 receives the direct events as well as whatever your GTM tags send. Pick one route per event to avoid double counting.
  • booking_completed fires in the visitor's browser. Ad blockers and closed tabs can stop a tag from firing; the booking itself is unaffected.

FAQ

Google Tag Manager questions

Something not covered? Email hello@bookingsxp.com.

Start free, no card

One widget, three templates, GTM and GA4 events and attribution in every booking. No card, no time limit.