GoHighLevel tracking

GoHighLevel Conversion Tracking: Leads, Bookings & Closed Deals

This is for agencies and service businesses running ads into GoHighLevel funnels, forms and calendars. The usual problem: the ad platforms see form fills, but nobody can tell which campaign produced the booked call or the signed client. I connect GHL's front end and its pipeline to GA4, Google Ads and Meta so each lead can be followed through to revenue.

GoHighLevel · Lead generation
  • Form, survey and booking events tracked even when embedded in iframes
  • Pipeline stage changes sent back to Google Ads and Meta as offline conversions
  • Click IDs and UTMs stored on every contact record
  • One setup you can repeat across sub-accounts
Quick answer

Proper GoHighLevel tracking has two layers. On the front end, GTM on your funnels and sites captures form, survey and calendar conversions with the click ID. In the back end, workflows fire webhooks when an opportunity moves stage, sending qualified leads and won deals to Google Ads offline conversions and the Meta Conversions API.

Tracking flow

How tracking works on GoHighLevel

The events I set up on GoHighLevel, and where each one is sent.

Why it breaks

Why GoHighLevel tracking goes wrong

Embedded forms and calendars live in an iframe

When a GHL form or calendar is embedded on WordPress or another site, it loads from a different domain inside an iframe. The parent page's tags can't see the submission, so the conversion either goes missing or gets counted on the wrong page.

Tracking code pasted in the wrong place

GHL lets you add code at the funnel or website level, on individual pages and in custom code elements. I often find the same pixel loaded in two of those places, which double-counts leads, or missing from the thank-you step entirely.

Click IDs never reach the contact

Offline conversions only work if the gclid, gbraid or fbclid from the ad click is stored with the contact. If a redirect, a multi-step funnel or a form without hidden fields drops it, the deal can't be matched back to the ad.

Ads optimise on form fills, not real outcomes

Most accounts only send the first opt-in to Google Ads and Meta. Leads that never show up or never buy count the same as clients who pay, so bidding learns to chase cheap, low-quality leads.

Native integrations with limited control

GHL's built-in Google Ads and Meta connections are a reasonable start, but you get limited control over which fields are sent, how events are named and how they deduplicate against the browser pixel. Mixing them with a custom setup without a plan causes duplicates.

What I set up

My GoHighLevel tracking setup

Funnel, site & form tracking

  • GTM installed once at the funnel/website level, with old duplicate pixels removed
  • Form and survey submission events with form name and step
  • Calendar booking events from the booking confirmation
  • Iframe-embedded forms and calendars tracked on external sites
  • Hidden fields that save gclid, fbclid and UTMs to the contact

Pipeline & offline conversions

  • Workflows triggered by opportunity stage and status changes
  • Webhooks that send qualified, booked and won stages to server-side GTM
  • Google Ads offline conversion uploads matched on click ID
  • Enhanced conversions for leads using hashed email and phone
  • Deal value passed with won opportunities

Meta Pixel & Conversions API

  • Pixel Lead and Schedule events on funnel pages
  • Server-side CAPI events from workflows for later pipeline stages
  • Shared event IDs so browser and server events deduplicate
  • fbp/fbc and contact data sent for better event matching

Agency reporting

  • GA4 key events that match the conversions you bid on
  • Lead-to-sale view by campaign, ad set and keyword
  • A documented template you can roll out to new sub-accounts
  • Consent Mode v2 set up where your audience requires it
  • Handover notes for your team
Event map

Events I track on GoHighLevel

EventWhen it firesSent to
generate_leadFunnel or website form submittedGA4, Google Ads, Meta Pixel + CAPI
survey_completeMulti-step survey finishedGA4, Meta Pixel + CAPI
book_appointmentCalendar booking confirmedGA4, Google Ads, Meta (Schedule)
qualified_leadOpportunity moved to a qualified stage (workflow webhook)Google Ads offline, Meta CAPI
appointment_showedAppointment status set to showedGoogle Ads offline, Meta CAPI
closed_wonOpportunity marked won, with deal valueGoogle Ads offline, Meta CAPI (Purchase), GA4
phone_clickClick on a tel: link on a funnel pageGA4, Google Ads
Process

How the setup works

  1. 01

    Audit

    I review your funnels, sites, forms, calendars and existing integrations, and list what is double-counted, missing or unattributed.

  2. 02

    Map the pipeline

    We agree which pipeline stages count as a real conversion and what each one is worth, so the ad platforms learn from the outcomes you care about.

  3. 03

    Build front-end tracking

    I set up GTM, form, survey and booking events, and the hidden fields that save click IDs and UTMs to each contact.

  4. 04

    Connect workflows

    I build the workflows and webhooks that send stage changes through server-side GTM to Google Ads and the Meta Conversions API.

  5. 05

    Test and hand over

    I run test leads through the whole journey, check them in each platform's diagnostics, and document the setup so it can be copied to other sub-accounts.

Why GoHighLevel needs offline conversion tracking

In GoHighLevel the real value of a lead shows up later, in the pipeline: a booked call, a show, a signed contract. If Google Ads and Meta only ever hear about the opt-in, they treat a tyre-kicker and a paying client the same way.

GHL workflows can react to an opportunity changing stage or status and fire a webhook. I point those webhooks at a server-side GTM container (on Stape or Google Cloud), which formats the data and sends it to Google Ads as an offline conversion and to Meta as a Conversions API event. It's the same idea as my CRM and marketing automation work at /services/crm-marketing-automation/, applied to GHL's pipeline.

Lead-to-sale attribution for agencies

Agencies managing several sub-accounts need a setup they can repeat, not a one-off tangle of snippets. I build a standard container, naming convention and set of workflows that can be adapted per client, so every account reports leads, bookings and closed deals the same way.

The result is that you can show a client which campaigns brought in revenue, not just leads, and give the ad platforms better signals to optimise on.

FAQ

GoHighLevel tracking FAQ

Can GoHighLevel send offline conversions to Google Ads?

Yes. GHL has a native Google Ads connection, and you can also use workflow webhooks to send stage changes through server-side GTM or the Google Ads API. Either way, the contact needs a stored gclid (or gbraid/wbraid) or hashed contact details so Google can match the conversion to a click.

How do I track a GHL form embedded on my WordPress site?

The embedded form runs in an iframe on GHL's domain, so your site's GTM can't see the submit directly. Depending on the form type, I either listen for messages the iframe sends to the parent page (where GHL provides them), redirect to a thank-you page you control, or track the submission from GHL's side with a workflow. The right option depends on how the form is embedded.

Should I use GHL's built-in Meta Conversions API or a custom setup?

The built-in option is fine for basic lead events. A custom setup through server-side GTM gives you control over event names, deal values, matching data and deduplication with the browser pixel. What matters most is not running both for the same event without shared event IDs.

Can I track calendar bookings as conversions?

Yes. I track the booking on the confirmation step as a front-end event, and send later appointment statuses such as showed through a workflow. That way you can optimise for booked calls, or for calls that actually happened.

Will this work across multiple sub-accounts?

Yes. I build the tracking as a documented template, a GTM container plus a standard set of workflows, that can be adjusted for each sub-account. Each client still needs its own ad account IDs and conversion actions.

Do I need server-side tracking for GoHighLevel?

For pipeline events, effectively yes: stage changes happen in the CRM, not in the browser, so they have to be sent server to server. Server-side GTM also makes browser lead events more reliable when ad blockers or browser privacy limits block the pixel.

Guides

Read next

Want your GoHighLevel tracking fixed?

Get a free audit of your tracking and ad account. Usually replies within 1–2 hours.