Guide · Tracking & analytics

Google Ads conversion tracking for Microsoft Bookings

Last updated 9 min read7 sources

This guide shows how to make Google Ads count booked Microsoft Bookings appointments, not just clicks on a Book button, so Smart Bidding optimises toward meetings that actually happen. It's for PPC managers and agencies whose clients take bookings through a shared Microsoft Bookings page. A click conversion takes about 30 minutes. The gclid offline import takes an afternoon to build, plus a few minutes a week to upload.

For a quick yes or no on whether native tracking exists, see Google Ads conversions from Microsoft Bookings. This page is the build.

Before you start#

  • Auto-tagging must be on in Google Ads. Google lists it as a requirement for importing offline conversions.
  • You need the Google tag or GTM on your site, with a Conversion Linker tag firing on all pages if you use GTM.
  • You need admin access in Google Ads to create conversion actions.
  • For the offline import only: the Administrator role on the Bookings calendar, Power Automate, and an Excel workbook in OneDrive or SharePoint.

Choose what you can measure#

Microsoft's page doesn't allow a conversion tag and doesn't redirect after booking. That rules out the two usual methods, which are a tag on the confirmation step and a thank-you-page URL. What's left:

OptionWhat Google Ads countsGood for bidding?
Book-link click on your sitePeople who went to bookNo. Use it as a secondary action
GA4 key event imported into AdsBookings sent from a flow (see the GA4 guide)Partly. Attribution depends on GA4 linking the event to the ad click
gclid offline importBookings matched to the exact ad clickYes, with a delay
Conversion tag on your own booking pageBookings as they happen, in the browserYes

Google Ads lets you set a conversion action as primary (used for bidding) or secondary (reported, not used for bidding). Keep click-level signals secondary once you have real bookings.

Level 1: a click conversion as a secondary signal#

  1. In Google Ads, create a new website conversion action, set it up manually, and pick the category Book appointment. Copy the conversion ID and conversion label.
  2. In GTM, add a Google Ads Conversion Tracking tag with that ID and label.
  3. Fire it on the "Bookings link click" trigger from level 1 of the GA4 guide. That trigger matches clicks to outlook.office.com/book/ links.
  4. Once real booking data is flowing, set this action to secondary.

This takes minutes. It overcounts, because abandoned forms look the same as finished bookings. Treat it as a stopgap.

Level 2: import completed bookings with the gclid#

This follows Google's standard offline flow: capture the gclid, keep it with the lead, and upload it when the lead converts. Here the "lead record" is the Bookings appointment itself, and RefID carries the gclid into it.

Caveats#

  • RefID is the only way in. Microsoft allows only letters, digits, underscores and hyphens, and says to test your URL. Users have reported Bad Request pages (2023) and a blank Tracking data column (2024 and 2025). Test before you rely on it. See RefID not working.
  • The gclid must stay exact. Google says to keep its case when you upload. Google doesn't publish the gclid character set. The ones we've seen use letters, digits, hyphens and underscores, which RefID accepts. The script below skips a gclid rather than changing it.
  • Length. Microsoft doesn't document a maximum RefID length, and gclids are long. Make a test booking with a real gclid before you launch.
  • The connector. The Bookings connector is in Preview, is admin-only and allows 5 flows per mailbox.
  • Timing. After you create the conversion action, Google says to wait 4 to 6 hours before your first upload. Most sources can import conversions for clicks up to 90 days old.
  • iOS traffic. Google's import accepts GBRAIDs as well as GCLIDs, so the script falls back to gbraid when there's no gclid.

Step 1: Create the import conversion action#

In Google Ads, create a new conversion action, choose Import, and pick the option for conversions from clicks uploaded as a file. Name it exactly Booked appointment - Bookings. The name in every upload has to match it character for character. Set a default value if you want one: the Bookings trigger doesn't include the service price, so you'd have to add values per service yourself.

This runs on every page. It saves the most recent ad click for 90 days and adds it to Bookings links as gc- or gb- followed by the ID.

JavaScript
(function () {
  var KEY = "bk_adclick";
  var params = new URLSearchParams(location.search);
  var id = params.get("gclid") || params.get("gbraid");
  var prefix = params.get("gclid") ? "gc-" : "gb-";

  if (id && /^[A-Za-z0-9_-]+$/.test(id)) {
    localStorage.setItem(KEY, JSON.stringify({ ref: prefix + id, ts: Date.now() }));
  }

  var saved = JSON.parse(localStorage.getItem(KEY) || "null");
  if (!saved || Date.now() - saved.ts > 90 * 864e5) return;

  document.querySelectorAll('a[href*="outlook.office"]').forEach(function (a) {
    var url = new URL(a.href);
    if (!/\/(book|owa\/calendar)\//.test(url.pathname)) return;
    url.search = "";
    url.searchParams.set("RefID", saved.ref);
    a.href = url.toString();
  });
})();

Only run it once the visitor has consented to advertising storage, using the same rule your consent tool applies to the Google Ads tag. Microsoft's page accepts only one RefID. If you also need a campaign code or the GA4 client_id, use the lookup-key approach in passing UTM parameters into Bookings.

Step 3: Write each booking to an Excel table#

Create a workbook in OneDrive or SharePoint with a table that has these columns, which match Google's import template:

Google Click IDConversion NameConversion TimeConversion ValueConversion Currency

Then build the flow:

  1. Trigger: When a appointment is Created (Microsoft Bookings), with your booking page's SMTP address.
  2. Condition: Tracking data starts with gc-. For gb- values, add a second branch, but check the column Google's current import template uses for GBRAIDs first.
  3. Action: Excel Online (Business) → Add a row into a table, with:
    • Google Click ID: substring(triggerBody()?['TrackingData'], 3, sub(length(triggerBody()?['TrackingData']), 3)), which drops the first three characters (gc-) and leaves the gclid untouched
    • Conversion Name: Booked appointment - Bookings
    • Conversion Time: formatDateTime(utcNow(), 'yyyy-MM-dd HH:mm:ss') followed by +00:00
    • Conversion Value and Currency: fixed values, or leave blank to use the default

Use the flow's run time as the conversion time, not the appointment's Start field. The conversion is the moment the booking was made, and the flow fires right after that. Check the time formats Google's template accepts before your first upload. An explicit offset avoids time-zone errors.

This flow only uses Standard connectors (Bookings and Excel Online (Business)), so you don't need the Premium HTTP action.

Step 4: Upload#

Download the table as a CSV and upload it under the Uploads page for conversions in Google Ads. Google also supports scheduled uploads from Google Sheets, HTTPS or SFTP, and the Google Ads API. If you want to schedule, you'll need to copy the rows somewhere Google can fetch them, because an Excel file in SharePoint isn't one of those sources. After each upload, clear or archive the rows you've sent.

Using a GA4 key event instead#

If you've built level 2 of the GA4 guide, you can import booking_completed into Google Ads from your linked GA4 property instead. It's less work each week. The trade-off is that Google Ads only gets credit when GA4 links the server-sent event to the session with the ad click, and those events arrive without a session. The gclid import matches the click directly, so it's the better input for bidding.

Testing#

  1. Tag Assistant. Connect Tag Assistant to your site, click a Book link, and check that the Google Ads conversion hit fires with your ID and label (level 1).
  2. The link. Visit your site with ?gclid=TeSt_123-abc, then hover a Book link. It should end in ?RefID=gc-TeSt_123-abc, with the case preserved.
  3. The flow. Make a test booking through that link and check that a row appeared with the right click ID and a UTC time.
  4. The upload. A test gclid won't match a real click, so Google will reject it. That's expected. Delete the test row. The first real check is an upload after a genuine ad click has turned into a booking.
  5. Upload history. Google Ads reports processed and rejected rows for each upload. Read the errors after every upload for the first few weeks.

Common problems#

"Conversion action not found." The Conversion Name doesn't exactly match the action, or you uploaded within 4 to 6 hours of creating it.

Clicks rejected as unrecognised. The gclid was changed on the way (lowercased, trimmed or URL-encoded), it came from a different Ads account, or the click is older than the import window.

No rows at all. RefID may be failing on your page (Bad Request, or blank Tracking data). The visitor may have booked from a link that wasn't tagged, such as the confirmation email or a bookmark. Or the flow may not be triggering. See Power Automate trigger not firing.

Bidding chases clicks. The level 1 click action is still set as primary. Change it to secondary once imported bookings are arriving.

Counts differ from the Bookings export. Only bookings that started from a paid click have a gclid, and staff-made bookings never do. The export's Tracking data column, described in UTM parameters and Bookings, shows how many bookings carried a code.

Doing this with BookingsXP#

With BookingsXP, the booking happens in a widget on your own page, so the conversion fires in the browser at the moment Microsoft Bookings confirms the appointment. You don't need to wait for uploads or depend on RefID. Add your conversion ID and label to the widget, and on booking_completed it sends:

JavaScript
gtag("event", "conversion", {
  send_to: "AW-123456789/AbCdEfGhIjKlMnOp",
  transaction_id: "BXP-7K3M9Q"
});

The transaction_id is the booking reference, so Google Ads de-duplicates a conversion reported twice. Optional enhanced conversions add a SHA-256 hash of the email, computed in the browser. If you'd rather use GTM, fire a Google Ads Conversion Tracking tag on the Custom Event bookingsxp.booking_completed with the reference as the transaction ID. The widget also records which ad click ID was present in the booking notes in Bookings. See analytics and pricing for which plan includes the Ads destination. BookingsXP is independent and not affiliated with or endorsed by Microsoft.

Questions people also ask

Sources

  1. Microsoft Learn: Customize booking page (opens in a new tab) · learn.microsoft.com
  2. Microsoft Learn (opens in a new tab) · learn.microsoft.com
  3. Microsoft Learn: Dlp connector classification (opens in a new tab) · learn.microsoft.com
  4. Microsoft Learn: Microsoft bookings appointment confirmation page g (opens in a new tab) · learn.microsoft.com
  5. Microsoft Tech Community: Track conversions for appointments booked through microsoft bookings on gt4 (opens in a new tab) · techcommunity.microsoft.com
  6. support.google.com: Google ads (opens in a new tab) · support.google.com
  7. support.google.com: Google ads (opens in a new tab) · support.google.com