TrueMetriks documentation: Calendly https://docs.truemetriks.com/form-integrations/calendly/ Generated from the TrueMetriks documentation. Paste the whole of this file into ChatGPT, Claude, Gemini, Cursor or any other AI. I use TrueMetriks, a server-side tracking and conversion attribution platform. It tracks my website visitors, ties every sale back to the ad that produced it, and sends those conversions back to my ad platforms. Help me with this specific task: Calendly. Connect Calendly over OAuth so every booking becomes a TrueMetriks Schedule or Lead event, stitched back to the ad that drove it. HOW TO GUIDE ME - This file has three parts: THE GUIDE is today's task, BACKGROUND is a prerequisite to confirm with me before you start THE GUIDE, not optional reading, and LINK MAP is the only place a real link comes from. - Ask me ONE thing at a time and wait for my answer before moving on. - At the start of every step, ask me: "do you want the written steps, or the video?" If I pick the video, give me the exact link from the LINK MAP at the bottom and wait until I tell you I have watched it. If I pick the written steps, give them to me from this file. - Only ever give me links that appear in the LINK MAP below. Never invent a URL, never guess an anchor, and if I ask for something that has no link here, say so and point me at https://docs.truemetriks.com/ instead. - Never ask me for my password, my API key, my MCP key, or any card details. You are reading me the steps; I am the one clicking in my own account. - Confirm each step worked before starting the next one. - Keep it short. I am doing this while looking at my screen, not reading an essay. - Everything you need is in this file. You do not need to browse the web. =============================================================================== THE GUIDE: Calendly https://docs.truemetriks.com/form-integrations/calendly/ =============================================================================== ## Video guide VIDEO: How to connect Calendly to TrueMetriks -> https://docs.truemetriks.com/form-integrations/calendly/#video-guide ## Connect Calendly to TrueMetriks ### Step 1 - Open Settings In TrueMetriks, pick the site you want from the selector at the top of the left sidebar, then click **Settings** at the bottom of the sidebar. ### Step 2 - Open the Calendly tile Click the **Integrations** tab, then click the highlighted **Calendly** tile. ### Step 3 - Click Connect Calendly Calendly webhooks require a **Standard, Teams, or Enterprise** plan. New Calendly accounts get a 14-day Teams trial, so webhooks work during the trial too. Click **Connect Calendly** to start the OAuth connection. ### Step 4 - Approve the connection in Calendly Calendly opens its approval screen asking to let TrueMetriks read your scheduled events and user info. Click **Approve** and you are redirected back to TrueMetriks, connected. ### Step 5 - Choose the event to fire Once connected, the page shows a green **Connected** status with the time of the last booking it received. Under **When someone books (invitee.created)**, pick the **Event to fire**. Two built-in events are available - **Schedule** is the default: - **Schedule** - the booking is an appointment (the default, and what most people want). - **Lead** - treat the booking as a lead. Whichever you pick fires on **every** booking. Want a uniquely-named Facebook event (for example `Schedule_Calendly`) to also fire on **every** booking? Add it under **Custom event mappings** in your [Facebook integration](https://docs.truemetriks.com/ad-integrations/facebook/) - it fires your custom name alongside the standard event on every booking, and restricted-category advertisers can uncheck the standard event so only the custom name fires. To fire a custom event only for **specific meeting types or answers**, use **Custom events for specific meeting types** below instead. ### Step 6 - Add the attribution helper script Copy the **attribution helper script** from the card: Paste it on **every** landing page that hosts a Calendly embed, **right below your existing TrueMetriks tracking snippet** in the page's `
`. For example, in a GoHighLevel funnel's Head tracking code it sits directly under the install snippet: The same applies to ClickFunnels, custom sites, and any other [platform install](https://docs.truemetriks.com/platform-installs/custom/) - paste the helper into the head, below your tracker. **On WordPress you do not touch any code.** In the TrueMetriks plugin settings, open the **Calendly & Typeform** card and tick **Load Calendly / Typeform attribution helper** - the plugin injects it for you on every page. See the [WordPress install guide](https://docs.truemetriks.com/platform-installs/wordpress/) for where the plugin settings live. ### Step 7 - Book a test call and watch it land Embed your Calendly on the page, then book a test appointment from a visit that came in through your site. Within a few seconds the booking appears in the visitor's timeline as your chosen event, with the appointment details attached: ## Custom events for specific meeting types (optional) Your **Schedule** (or **Lead**) event fires on every booking automatically. Add a **group** here to **also** fire a custom Facebook event when a booking comes from a specific meeting type and, optionally, answers an invitee question a certain way. This is how you send a distinct conversion for a high-intent call or answer without changing what fires for everyone else. VIDEO: How Calendly custom events for specific meeting types work -> https://docs.truemetriks.com/form-integrations/calendly/#custom-events-for-specific-meeting-types-optional ### How it works A group is made of a **Calendly event type** to target (by its exact name) and, optionally, one or more **invitee questions** whose answers must match: - A group **also fires its own custom event**. It does not change or gate the standard Schedule/Lead, which still fires on every booking. - Leave a group's event type empty to apply it to **any** booking. - A booking that matches **several groups fires them all**, so two groups can target the same event type with different answers and trigger two different custom events. - A group with **no custom event selected does nothing** - you must select or create one. - Answers match **case-insensitive** but otherwise **exactly** (not "contains") - the answer must be copied **verbatim**. This works best with **Checkboxes** or **Radio Buttons** invitee questions, where the answer options are fixed and you can copy them word for word. Free-text answers are unpredictable, so avoid them. ### Step A - Add a group On the Calendly page, scroll to **Custom events for specific meeting types (optional)** and click **+ Add group**. ### Step B - Create your invitee questions in Calendly The questions you match on are your Calendly **invitee questions**. In Calendly, open the event type under **Event types** and click **More options**: Then open **Invitee form** and add the questions you want to ask. Use **Checkboxes** or **Radio Buttons** so the answer options are fixed and can be copied verbatim (for example "Where do you live?"): ### Step C - Set the event type, conditions, and the custom event to fire Back in TrueMetriks, name the group and type the exact **Calendly event type** (leave it empty to apply to any type). Add a condition with the exact **Question** and one or more **Accepted answers** - one per line, click **+ Add answer** for each. The group matches when the invitee's answer is one of those values. Then, under **also fire**, pick the custom event this group fires. If you have already created one, select it from the dropdown. Otherwise click **Create new**: - **Standard event** is locked to the **Event to fire** you chose above (Schedule or Lead) - the custom event rides along with it. - **Custom event name** is the uniquely-named event Facebook records (for example `Calendly_DiscoveryCall`). - **Fire when** is **Always** by default, with **New customers only** and **Returning only** also available. Click **Create** and the custom event is created as a Facebook Custom Conversion, tagged **Calendly**. ### Step D - Add more conditions or groups, then save Click **+ Add condition** to require more than one answer. With two or more conditions a **Match mode** appears: **ALL conditions must match (AND)** or **ANY condition matches (OR)**. Add more **groups** to target other event types or answers. Click **Save changes** when you are done. Once a group is saved, its custom event **locks** - the event type, questions, and answers stay editable. To fire a different event, remove the group and add a new one. ### Where the custom event shows up, and how to remove it Each custom event you create appears in your [Facebook integration](https://docs.truemetriks.com/ad-integrations/facebook/) under **Tracking**, in the **Custom events** list, tagged with its standard event and its origin (for example **Schedule** and **Calendly**): Removing a group does **not** delete this event - it lives on your Facebook pixel as a Custom Conversion, so it stays available to select for other groups. To delete it entirely, remove it from the **Custom events** list in your Facebook integration. =============================================================================== BACKGROUND: Webhooks https://docs.truemetriks.com/integrations/webhooks/ =============================================================================== Webhooks move conversions in and out of TrueMetriks. Open **Settings > Integrations > Webhooks** and you get two tabs: **Receive webhooks** brings conversions in, **Send webhooks** pushes them back out with attribution attached. ## Receive webhooks Bring conversions in from any tool - Zapier, a WordPress form, GoHighLevel, or your own backend. Each webhook gets its own secret URL. Paste that URL into the tool and it sends Leads, booked calls, Purchases or custom events into this site's analytics. ### Step 1 - Create a receiving webhook On the **Receive webhooks** tab, click **Add receiving webhook**. Name it after the tool that will send to it, then pick the **event type**: - **Lead**, **Schedule**, or **Purchase** for a standard conversion. - **Custom event name** for your own event (for example `ApplicationSubmitted`). Custom events show in analytics and can trigger sending webhooks. You cannot change the event type later, because tools send to this URL expecting it. If you need a different type, create a second webhook. Click **Create webhook**. ### Step 2 - Copy the URL into your tool Copy the webhook URL and paste it into the tool that will send to it. That is the whole setup. The URL is the only credential, there are no API keys. ### Step 3 - Send a payload POST JSON to the URL (form-encoded works too). We read the common field names, and we find them inside nested payloads too, so most tools work with no setup at all: ```bash curl -X POST 'https://q.your-domain/api/webhooks/in/YOUR_TOKEN' \ -H 'Content-Type: application/json' \ -d '{"email":"jane@example.com","first_name":"Jane","value":49.99,"currency":"USD"}' ``` The fields we read are `email`, `phone`, `first_name`, `last_name`, `value`, `currency` and `order_id`. Anything else you send is kept as event properties. If it works you get **HTTP 200** back, with a summary of what we found. The event then shows in your analytics like any other integration. It only gets credited to an ad if we can tell which visitor it came from, and that part is worth getting right, so it has its own section next. ### Make sure the conversion lands on the right visitor When a conversion arrives by webhook, we have to work out which visitor it came from. If we cannot, the sale still counts and the money is still yours, but it lands on a person with no history, so no ad gets the credit. **Most of the time this takes care of itself.** Nearly every tool sends us an email, and nearly every buyer types their email somewhere on your site, so the two line up and the conversion joins the right journey. Nothing for you to do. Capturing the email as early as you have it makes this even more reliable - see [`window.tmIdentify`](https://docs.truemetriks.com/platform-installs/custom/#windowtmidentifyemail-traits) on the Custom install guide. #### When email is not enough Two things break the email match, and both are worth knowing about: - **They never typed their email on your site.** They browsed, then paid somewhere you do not control, so no visit of theirs carries that address. Nothing to match against. - **They typed it two different ways.** One spelling at a booking, another at checkout, and to us that is two different people. We do repair the obvious misspellings, but only so far. We fix a short, fixed list of provider typos, one way only: an email arriving as `gmial.com` is also tried as `gmail.com`. An email that arrives spelled **correctly** is never checked against misspellings, because that could merge two different people. And a typo before the `@` (`davd@` for `david@`) is not fixed at all. So if your conversions keep landing with no visit attached, email alone is not reaching those buyers, and the next section is how you fix it. #### The fix - send us the visitor id This is optional, and most sites never need it. But when email is not landing, it is the one thing that always works, because there is nothing to match and nothing to guess. Everything else is us working out who someone probably is. This is us being told. Every visitor we track carries a cookie on your own domain called `_evid`. Read it in the browser, drop it into a hidden field on your form or checkout, and send it in the payload alongside the email you already send. You can name the field any of these: `evid`, `_evid`, `tm_evid`, `visitor_id`, `tm_visitor_id`, `tm_id`. Add the hidden field to your form: ```html ``` Then fill it from the cookie at the moment the form is submitted: ```html ``` Your payload then carries one extra line: ```json { "email": "jane@example.com", "value": 49.99, "currency": "USD", "tm_evid": "ev_k3f9q2_a1b2c3d4" } ``` **Read the cookie in the browser. Never bake it into the page.** If a CDN caches the page holding your hidden field, one visitor's `_evid` gets saved into the HTML and handed to everybody who loads it after them, and all of their conversions pile onto that one person. We trust the visitor id above everything else, so nothing later catches the mistake. The snippet above is safe because it reads the cookie as the form is sent, in that visitor's own browser. #### Send the click id if you have it `fbclid` and `gclid` sit in the landing-page URL, so you can put them in a hidden field the same way, with no cookie to read. Another option when the visitor id is awkward to get at. You can name the field any of these: `fbclid`, `gclid`, `click_id`, `tm_click_id`. #### What we try, in order - **Visitor id** - exact, no guessing. - **Click id** - `fbclid` or `gclid`, matched against the click ids we stored for that visitor. - **Email** - matched against the email attached to their visits. We stop at the first one that finds a real visit. For most sites the email on its own gets there, which is why nothing above is required. Sending more than one is safe either way - they do not clash, the strongest one wins. #### Why a conversion shows no visit A conversion with no visit attached means nothing in that payload matched a visitor we had seen. It still counts and the money is still yours, but with no journey behind it there is no ad to credit. Adding the visitor id fixes it from then on. It cannot go back and fix conversions that already arrived, so the sooner it is in, the sooner your attribution fills in. ### Also fire to connected ad platforms Each receiving webhook has an **Also fire to connected ad platforms** toggle, off by default. Turn it on and the events also go to Facebook, TikTok, GA4 and Google Ads, just like a native integration. Your analytics get them either way. Custom events work too: `Call Booked` reaches your ad platforms under that same name. #### Send a custom event to Facebook as a Custom Conversion Once a custom-named receiving webhook exists, its event name shows up in Facebook's **Create custom event** dialog, under a **Custom webhook events** group. Pick it there and we create a Facebook Custom Conversion with that name, so Facebook can optimize and report on it. We store it as an `OTHER`-type conversion, so it is never mistaken for a Lead or a Purchase, and it fires once per event with no duplicates. Facebook only gets the event while that webhook's **Also fire to connected ad platforms** toggle is on. See the [Facebook integration guide](https://docs.truemetriks.com/ad-integrations/facebook/) for the dialog. ### Duplicate protection We count each conversion once, even when two tools report it: - **Leads, Schedules and custom events:** the same email and event type counts once per day, across every source. A webhook and a native integration (say [Typeform](https://docs.truemetriks.com/form-integrations/typeform/)) reporting the same lead will not double-count. - **Purchases** are checked on email, order and amount instead, so two genuinely different orders on the same day both count. If a native integration already reports the same event type for this site, the webhook shows an amber warning as a reminder. ### Recent deliveries Every receiving webhook keeps a **Recent deliveries** log: the last 25 receipts, 5 per page. Each one shows what happened (`accepted`, `deduped`, `parse error`, `oversized` or `ignored`) plus a preview of the payload, so you can see exactly what arrived. ### Rotating or removing a webhook There is no regenerate button, on purpose. To change a URL, delete the webhook and create a new one, which gets a new URL. Deleting one stops its URL working straight away. Payloads over 256 KB are rejected. ## Send webhooks Push conversions out of TrueMetriks to any URL - a CRM, GoHighLevel, or your own backend. Every Lead, Schedule and Purchase goes to your URL with the person's first and last touch, sessions and paid channel attached. Leads reach GoHighLevel with the whole journey on them. ### Step 1 - Create a sending webhook Switch to the **Send webhooks** tab and click **Add sending webhook**. Fill in the dialog: - **Name** - a label for you (for example "GoHighLevel contacts"). - **Webhook URL** - where we POST the payload. Must be `https`. - **Send this event** - pick ONE event from the dropdown: **Lead**, **Schedule**, **Purchase**, or one of **your custom events** (your Facebook Custom Conversions and custom-named receiving webhooks). One sending webhook sends one event. To send another event to the same place, create a second one. Click **Create webhook**. ### Step 2 - Copy the signing secret We show a **signing secret** once, right after you create the webhook. Copy it now, you will not see it again. Every delivery is signed so your receiver can check it came from us. The signature rides in an `X-TrueMetriks-Signature: t=