# Events from embeds

An embedded booking page or routing form runs in a frame on your website, and 42min loads no Google or Meta code
inside it. Instead, the page sends each step of the booking to your website as a message. Your own tags receive
them there, and your website's own cookie consent decides what they record.

This page is the reference. For a setup in Google Tag Manager, step by step, see the
[Google Tag Manager recipe](/help/booking-pages/embed-google-tag-manager).

## Receiving the events

**Let the embed code push them into a tag.** In the embed panel (see
[Embedding on your website](/help/booking-pages/embedding)), choose a tag under **Send events to**: Google Tag
Manager, Google Analytics or Meta Pixel. The code then carries `data-x42min-push` (with the value `gtm`, `gtag`
or `meta`), and each event goes into that tag if the tag is already on your page. What each choice sends is
[described below](#what-send-events-to-does).

**Listen on your page.** With the embed code on your page, each event also arrives as an `x42min:event` event on
`window`. Its `detail` holds `version`, `name`, `params`, `identifiers` (or `null`) and `element`, the embed it
came from (for a popup, the link that opened it), so several embeds on one page stay apart:

```js
window.addEventListener('x42min:event', function (e) {
  console.log(e.detail.name, e.detail.params, e.detail.element);
});
```

**Listen to the messages yourself.** A plain `<iframe>` code from before, or a site builder that puts your code
in a frame of its own (Wix and Framer do), still receives the messages. Accept them only from `https://42min.us`:

```js
window.addEventListener('message', function (e) {
  if (e.origin !== 'https://42min.us') return;
  var data = e.data;
  if (!data || data.type !== 'x42min:event' || data.version !== 1) return;
  console.log(data.name, data.params);
});
```

## The message

```json
{
  "type": "x42min:event",
  "version": 1,
  "name": "x42min_booking_confirmed",
  "params": {
    "event_type_name": "Intro call",
    "event_type_slug": "intro-call",
    "duration_minutes": 30,
    "booking_id": "8f0c2a8e-1d4b-4b8e-9a51-0e6f3c1a2b7d",
    "language": "en",
    "meta_event": "Schedule"
  }
}
```

`identifiers` is added only in the case [described below](#hashed-email-and-phone).

## Events

| Event | Sent when |
|---|---|
| `x42min_landing_viewed` | your landing page or a team page opens |
| `x42min_booking_page_viewed` | a booking page opens |
| `x42min_date_selected` | the invitee picks a date |
| `x42min_time_selected` | the invitee picks a time |
| `x42min_booking_form_started` | the invitee starts the booking form |
| `x42min_booking_submitted` | the booking form is sent |
| `x42min_booking_confirmed` | the booking is confirmed, with no approval or payment pending |
| `x42min_booking_requested` | a booking that needs your approval is requested |
| `x42min_booking_disqualified` | qualification screens the invitee out |
| `x42min_checkout_started` | a paid booking leaves for the payment page |
| `x42min_routing_form_viewed` | a routing form opens |
| `x42min_routing_form_started` | the visitor gives a first answer |
| `x42min_routing_form_submitted` | the routing form is sent |
| `x42min_routing_form_routed` | the form decides where the visitor goes |

## Parameters

| Parameter | Carried by | Value |
|---|---|---|
| `event_type_name`, `event_type_slug`, `duration_minutes` | events of a booking page | the event type |
| `team_name` | events of a team booking page | the team |
| `routing_form_name` | events of a routing form | the form |
| `destination_type` | `x42min_routing_form_routed` | `event_type`, `external_url`, `custom_message` or `routing_form` |
| `page_kind` | `x42min_landing_viewed` | `user` or `team` |
| `language` | every event | the page's language |
| `occurrences` | events of a recurring series | the number of meetings |
| `booking_id` | `x42min_booking_confirmed`, `x42min_booking_requested` | the booking's ID |
| `value`, `currency` | `x42min_checkout_started` | the price |
| `meta_event` | events that map to a Meta standard event | the standard event |

`meta_event` is your Meta standard event for a confirmed booking (Schedule by default) on
`x42min_booking_confirmed`, the one for a submitted routing form (Lead by default) on
`x42min_routing_form_submitted`, `InitiateCheckout` on `x42min_checkout_started` and `ViewContent` on
`x42min_booking_page_viewed`.

Values are cut at 100 characters. No event carries the invitee's name, email address, phone number, answers,
notes or guests, the host's email address, a private link or token, or the routing response ID.

## Hashed email and phone

A message carries `identifiers` only when all of these hold:

- your website's address is listed under **Websites that may receive hashed identifiers from embeds**, on the
  [Google Ads](/help/integrations/google-ads) or [Meta Pixel](/help/integrations/meta-pixel) page;
- the embed code (`embed.js`) is on that page: it tells the frame your website's address when the frame loads,
  and the frame checks it against the list;
- the event is `x42min_booking_confirmed`, `x42min_booking_requested` or `x42min_routing_form_submitted`;
- **Enhanced conversions** is on (the `google` key) or **Advanced matching** is on (the `meta` key).

```json
"identifiers": {
  "google": { "sha256_email_address": "...", "sha256_phone_number": "..." },
  "meta": { "em": "...", "ph": "..." }
}
```

Each value is a SHA-256 hash in hex, computed in the visitor's browser after each platform's own normalization.
For Google, the email address is trimmed and lowercased, with the dots removed from the name part of Gmail
addresses, and the phone number is in international format with its `+`. For Meta, the email address is trimmed
and lowercased, and the phone number keeps its digits only, country code included.

On your page, the identifiers reach the `x42min:event` event, your own message listener and the Google Tag
Manager push (`x42min_identifiers`). The **Google Analytics** and **Meta Pixel** choices under **Send events to**
never pass them on: map `x42min_identifiers.google` and `x42min_identifiers.meta` in Google Tag Manager instead,
as the [recipe](/help/booking-pages/embed-google-tag-manager) shows.

A message to any other window never carries `identifiers`: not one to a website that isn't on the list, and not
the copy sent to the top window of a site builder. No message waits for 42min's cookie notice, which never
appears inside an embed: consent for the tags on your website is yours to collect.

## What "Send events to" does

Each push happens only when its tag is already on your page. The push itself doesn't check consent: your tags
do, so give each one a consent condition, as [step 7 of the recipe](/help/booking-pages/embed-google-tag-manager#7-consent-for-your-tags)
shows.

- **Google Tag Manager** gets two pushes per event. The first, `{ x42min: null, x42min_identifiers: null }`,
  clears the previous event's values. The second is `{ event: name, x42min: params, x42min_identifiers }`. No
  event inherits another's parameters or identifiers, even from another embed.
- **Google Analytics** gets `gtag('event', name, params)`, never with identifiers, because an event without
  `send_to` reaches every Google destination on your page. For enhanced conversions from embeds, use Google Tag
  Manager.
- **Meta Pixel** gets `fbq('track', ...)` with the standard event where `meta_event` names one, or
  `fbq('trackCustom', ...)` with the `x42min_` name otherwise, and the booking's ID as the event ID, never with
  identifiers: Meta's advanced matching needs your pixel's ID, which the embed code can't know. For advanced
  matching from embeds, use Google Tag Manager. It never gets a PageView: page views on your website are your own
  pixel's job.

## When nothing is sent

- The event type, routing form or team has its analytics set to **Off**.
- The page was opened through a single-use link.
- The steps that happen on cancel, reschedule and payment pages: payments completed, reschedules, cancellations
  and Roundtable votes.

## Versions

Messages carry `"version": 1`. Within version 1, changes only add things: new events or new parameters. Removing
or renaming anything means a version 2, sent alongside version 1 for a while. Check `version`, and ignore events
and parameters you don't know.
