Connect Cal.com

Track booked meetings, cancellations, and no-showsfrom Cal.com and fire them server-side to your ad platforms. Bookings stitch to the visitor's ad session through two hidden booking questions — ft_sid and ft_uid — that the FunnelTrack injector fills on your booking page.

1

Connect the source in FunnelTrack

In FunnelTrack go to Integrations → Cal.comand connect it. Copy your workspace's webhook URL shown there — it looks like:

https://app.funneltrack.com/api/webhook/calcom/<your-workspace-id>
2

Add the webhook in Cal.com

In Cal.com you can add the webhook at two levels — pick whichever fits:

  • All event types — Settings → Developer → Webhooks (account or organization level). One webhook covers every booking page.
  • Specific event types — open an event type → Advanced → Webhooks. Add the webhook only on the booking pages you want tracked.
Cal.com account-level webhook settings under Settings → Developer → Webhooks
All event types — Settings → Developer → Webhooks (account or organization level).
Adding a webhook on a single Cal.com event type under Advanced → Webhooks
Specific event types — open the event type → Advanced → Webhooks.

Paste your FunnelTrack webhook URL as the Subscriber URL and enable these three triggers:

  • Booking Created → Meeting Booked
  • Booking Cancelled → Meeting Canceled
  • Booking No-Show Updated → No-Show
Cal.com webhook configuration with the FunnelTrack subscriber URL and the three booking triggers enabled
Paste the Subscriber URL and enable Booking Created, Cancelled, and No-Show Updated. Save.

Coming soon: one-click connect

OAuth "Continue with Cal.com" will create these webhooks automatically — account, organization, or per event type — so you won't need to paste a URL. Until then, add the webhook manually as above.
3

Add the hidden ft_sid & ft_uid booking questions

On each event type you track, open Advanced → Booking questions and add two hidden questions with these exact identifiers:

  • Identifier ft_sid — the session id (the label can be anything).
  • Identifier ft_uid — the visitor id.

Set both to Short Text, mark them Hidden, and make them not required so they never block a booking.

Cal.com booking questions showing the hidden ft_sid and ft_uid fields added to the event type
Advanced → Booking questions — add ft_sid and ft_uid as hidden Short Text questions.

Here's the field configuration for each one — match the identifier exactly:

Configuring the hidden ft_sid booking question in Cal.com
ft_sid — Short Text, hidden, not required.
Configuring the hidden ft_uid booking question in Cal.com
ft_uid — Short Text, hidden, not required.

Booking questions are per event type

Cal.com stores booking questions on each event type separately. If the ft_sid question is missing (or its identifier isn't spelled exactly ft_sid) on an event type, that page's bookings will arrive without a session id and lose web attribution. Add both questions to every event type you embed.
4

Install the injector on your booking page

Cal.com's booking form is a cross-origin iframe, so the FunnelTrack pixel can't set its fields directly. This small script reads the visitor's session + visitor id from the pixel and prefills the ft_sid / ft_uidquestions through Cal's iframe URL. Load it after the FunnelTrack pixel, on the page hosting the embed:

<script>
(function () {
  "use strict";
  var CAL_HOST_RE = /(^|\.)cal\.com$/i;
  function getIds() {
    var ft = window.ft || window.tracker;
    if (!ft) return { sid: "", uid: "" };
    return {
      sid: typeof ft.getSessionId === "function" ? ft.getSessionId() || "" : "",
      uid: typeof ft.getUserId === "function" ? ft.getUserId() || "" : "",
    };
  }
  function inject(sid, uid) {
    var frames = document.querySelectorAll("iframe:not([data-ft-injected])");
    for (var i = 0; i < frames.length; i++) {
      var f = frames[i], src = f.getAttribute("src") || "";
      if (!src) continue;
      var u; try { u = new URL(src, window.location.href); } catch (e) { continue; }
      if (!CAL_HOST_RE.test(u.hostname)) continue;
      var changed = false;
      if (sid && u.searchParams.get("ft_sid") !== sid) { u.searchParams.set("ft_sid", sid); changed = true; }
      if (uid && u.searchParams.get("ft_uid") !== uid) { u.searchParams.set("ft_uid", uid); changed = true; }
      f.setAttribute("data-ft-injected", "1");
      if (changed) f.setAttribute("src", u.toString());
    }
  }
  function run() {
    var start = Date.now();
    (function poll() {
      var v = getIds();
      if (v.sid && v.uid) inject(v.sid, v.uid);
      if (Date.now() - start < 8000) setTimeout(poll, 150);
      else { var last = getIds(); inject(last.sid, last.uid); }
    })();
  }
  if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", run);
  else run();
})();
</script>
The FunnelTrack Cal.com injector script added to a scheduler page's custom code / footer, after the FunnelTrack pixel
Add the injector script to the page hosting your Cal.com embed, after the FunnelTrack pixel.

Works with the HTML inline embed, the popup/floating embed, and the React @calcom/embed-react component. For the native @calcom/atoms Booker, pass the ids through its prefill prop instead.

To confirm it's working, make a test booking on your live page — the two hidden fields should carry real values (not blank) on the Cal.com confirmation:

Cal.com booking confirmation showing the ft_sid and ft_uid values captured on the booking
Booking confirmation — ft_sid and ft_uid populated confirms the injector is passing the ids through.
5

Turn on events & route them

Open a destination (Meta, Google Ads, GA4, TikTok, …), pick Cal.com as the source, and enable the Meeting Bookedcard (and Canceled / No-Show if you want them). Map it to the destination event you want. Booking Created fires as a web conversion carrying the booker's click IDs; Canceled and No-Show fire as offline events.

Verify it's working

Make a test booking, then open the Event Delivery Log. You should see an inbound Meeting Booked (received) with ft_sid / ft_uid in the payload, plus matching outbound deliveries to each enabled destination.
FunnelTrack Event Delivery Log showing the inbound Meeting Booked and the outbound deliveries to each destination
Event Delivery Log — inbound Meeting Booked (received) followed by outbound deliveries.

Supported events

  • Meeting Booked — someone books a meeting (web conversion; carries booking price as value when set).
  • Meeting Canceled — a booked meeting is canceled by host or attendee (offline).
  • No-Show — the host marks an attendee as a no-show (offline).