Conversion tracking events
Exactly which event each platform receives, with payloads, so your conversion action matches.
When a booking completes, Booked fires a conversion event into whichever tracking tools are already on the page. You do not add any code for this — you add the pixel, switch on conversion reporting under Settings › Tracking & pixels (it is off until you do), and Booked fires into it. Your job is to build the conversion action on the right event name.
What fires, and where
These are the defaults. Every event name can be changed under Settings › Tracking & pixels, and you can add rules that fire events at earlier moments too — the form opening, a service chosen, a time chosen, details entered, the payment step — as well as at the booking itself.
| Platform | Event | Fired as |
|---|---|---|
| Meta (Facebook) | Purchase | fbq('track', 'Purchase', …) |
| Google Analytics 4 | purchase | gtag('event', 'purchase', …) |
| Google Ads | conversion | gtag('event', 'conversion', …) with send_to |
| Google Tag Manager | booking_completed | dataLayer.push(…) |
| TikTok | CompletePayment | ttq.track('CompletePayment', …) |
| X (Twitter) | your X event id, or the Meta names | twq('event', id, …), or twq('track', 'Purchase', …) when no id is set |
A Meta name that is not one of Meta's standard events is sent with trackCustom instead. Each call is guarded: if the pixel is not on the page, nothing is called and nothing errors. The GTM push is the exception — it always runs, and because GTM replays its queue, a container added later still receives events fired before it loaded.
The payloads
// Meta
fbq( 'track', 'Purchase', {
value, currency,
content_name: service,
content_type: 'booking'
} );
// GA4
gtag( 'event', 'purchase', {
value, currency,
transaction_id: reference,
items: [ { item_name: service, quantity } ]
} );
// Google Ads — only when an ID is configured
gtag( 'event', 'conversion', {
send_to: 'AW-123456789/AbC-D_efGh',
value, currency,
transaction_id: reference
} );
// GTM
dataLayer.push( {
event: 'booking_completed',
booking_value: value,
booking_currency: currency,
booking_reference: reference,
booking_service: service,
booking_quantity: quantity,
booking_step: 'booked',
booking_event: 'Purchase'
} );
// TikTok
ttq.track( 'CompletePayment', { value, currency } );
// X
twq( 'event', 'tw-abc12-def34', { value, currency } );The transaction_id is only sent for the booking itself. Earlier moments push booking_<step> into the data layer — booking_start, booking_service, booking_slot, booking_details, booking_checkout — whether or not a rule names them, and each is counted once per visit.
| Value | Is |
|---|---|
value | What was paid, or the booking's price if nothing was paid online. Worked out on the server, never negative. |
currency | The store currency, defaulting to GBP. |
reference | The booking reference, e.g. GB-00318. Use it as the transaction id to deduplicate. |
service | The service name, falling back to Booking. |
quantity | The number of people on the booking, at least 1. |
Google Ads needs two values
Unlike the others, the Ads conversion cannot fire without an explicit destination. Enter both the conversion ID and the label under Settings › Tracking & pixels; they are combined into send_to as ID/LABEL. With an ID and no label, only the ID is sent, and only for the booking itself — which will usually not match a conversion action.
Building the GTM trigger
- Create a Custom Event triggerEvent name exactly
booking_completed. - Create Data Layer variablesOne each for
booking_value,booking_currency,booking_referenceandbooking_service. - Point your tag at the triggerMap value and currency from the variables, and use the reference as the transaction id.
- Test in PreviewComplete a real booking. The event appears the moment the confirmation screen renders, or your own confirmation page loads.
When it fires
The event fires in the browser, but the server decides when. A booking converts once, ever: the first page to ask gets the payload and every later one gets nothing, so a refreshed confirmation or a second tab cannot double-count. A booking that owes money converts when the payment arrives, not when the form is submitted.
- Your own thank-you page can fire it. Send customers to a page with
?gb_booking=GB-00318in the address and, with conversion reporting on, Booked fires the conversion there. Choosing a page under Settings › Booking rules › After they book does this for you: the form sends every customer to that page with the reference (and a signed key) already in the address, and stops claiming the conversion itself. See Your own confirmation page. - A custom form can claim it.
POST /public/conversionwith the bookingreferencereturns the payload to exactly one caller. - Bookings your staff take by phone never fire it. These events belong to online bookings only, so ad platforms see online bookings, and Booked's own Insights sees everything. Expect the two to differ, and treat Booked as the source of truth.
The commonest cause of double-counted conversions is a hand-written listener alongside the built-in one. Add the pixel, configure the IDs, and let Booked fire. If you need to run something extra, use Run your own code when a booking converts on the same settings screen — it gets a booking object and runs once, after the events.
Attribution is separate
Booked's own where bookings come from reporting does not use these pixels. It records first-touch UTM values in the visitor's browser storage for 30 days, and never overwrites the original source on later visits. It is skipped entirely when storage is unavailable — private windows, or browsers blocking site data — so those bookings report as direct.