Booking Experts data layer events
Full reference of GA4 and custom events, parameters, and sample payloads.
Pre-release notice: These docs reflect the schema that becomes active on 2 Mar 2026. Events marked active are part of that upcoming schema. Events marked deprecated are legacy payloads still emitted today and will stop after 2 Mar 2026.
Looking for setup guidance? See Booking Experts data layer overview.
Deprecated events: See Deprecated data layer events for legacy payloads and removals.
GA4 events
add_to_cart
A user adds items to the cart.
| Status | active |
|---|---|
| Type | event |
| Available on | Booking site |
| Portals | Checkout portal |
| Flow | Booking site cart + checkout portal upgrades add |
Triggered when a user adds one or more items to the cart on a booking site or adds extras/upgrades in the checkout portal.
If the add-to-cart action comes from availability search, a search snapshot is included (same shape as search_results_loaded.search).
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
search | {...} (see below) | if available | object | Availability search snapshot for the add_to_cart action. Source: Website availability search state (dates, guests, amenities) when adding to cart. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
currency | EUR | always | ga4 | Currency of the items associated with the event, in 3-letter ISO 4217 format. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
value | 350.0 | always | ga4 | Total value of the event. Source: Total order/booking value or sum of item prices. |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | always | ga4 | The ID of the rentable type. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | if available | ga4 | The name of the rentable type. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
item_brand | Administration Name | if available | ga4 | The localized name of the site. Source: Checkout portal: administration name. Website search: site/brand name shown on the website (can differ from the administration name). |
item_category | Accommodation | if available | ga4 | Top-level item type.
Source: Checkout portal: |
item_category2 | house | if available | ga4 | Semantic segment for accommodations or sub-bucket for extras. Accommodation: house pitch room berth apartment other Extras: Amenity Upgrade PackageSource: Checkout portal: accommodation semantic segment or extras bucket. Website search: accommodation semantic segment. |
item_category3 | if available | ga4 | PMS extra type for extras only.
Source: Checkout portal extras only: cost extra_type. Not set for accommodations, packages, or website search. | |
item_variant | single_night | if available | ga4 | Stay duration category for the accommodation.
Source: Checkout portal accommodations and CMS availability items; derived from arrival/departure. |
item_list_id | cart | if available | ga4 | ID of the list where the item is shown. Source: Website search list id (availability_search/property_search). Cart/checkout events may supply list id like Cart or Checkout. |
item_list_name | Cart | if available | ga4 | Name of the list where the item is shown. Source: Website search list name (Availability search/Property search). Cart/checkout events may supply list name like Cart or Checkout. |
item_country | Netherlands | if available | custom | The country where the administration is located. Source: Administration country from BEX (shared across checkout portal and website search). |
item_region | Twente | if available | custom | The region where the administration is located. Source: Administration region from BEX (shared across checkout portal and website search). |
item_city | Enschede | if available | custom | The city where the administration is located. Source: Administration city from BEX (shared across checkout portal and website search). |
administration_id | 321321 | if available | custom | The ID of the administration in BEX PMS. Source: Checkout portal: BEX administration id. Website search: the same BEX administration id (Booking Experts administration mapping). |
administration_name | Administration Name | if available | custom | The name of the administration in BEX PMS. Source: Checkout portal: BEX administration name. Website search: the same BEX administration name (Booking Experts administration mapping). |
coupon | SUMMER10 | if available | ga4 | Coupon applied to the item. Source: Coupon code applied to the reservation or order item (first code, if any). |
discount | 25.0 | if available | ga4 | Discount applied to the item. Source: Discount amount for the order item. |
price | 350.0 | if available | ga4 | Price for the item line (stay total for accommodation). Source: Website search: availability/property price for the stay. Checkout portal: order item unit price; accommodation uses stay total derived from booking total minus upgrades. |
quantity | 1 | if available | ga4 | Quantity of the item. Source: Order item quantity; otherwise 1. |
index | 1 | if available | ga4 | Position of the item in the list. Source: Position in the result list (website search only). |
start_date | 2026-02-20 | if available | custom | The date of arrival for availability. Source: Stay arrival date or availability start date. |
end_date | 2026-02-22 | if available | custom | The date of departure for availability. Source: Stay departure date or availability end date. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
search
Availability search snapshot for the add_to_cart action. Source: Website availability search state (dates, guests, amenities) when adding to cart.
Fields below apply only when search is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
start_date | 2026-02-20 | if available | custom | Arrival date for the availability search (YYYY-MM-DD, null when missing). Source: Website availability search arrival date. |
end_date | 2026-02-22 | if available | custom | Departure date for the availability search (YYYY-MM-DD, null when missing). Source: Website availability search departure date. |
nights | 2 | if available | custom | Length of stay in nights (null when dates are missing). Source: Derived from search dates or nights selector. |
rentable_type | house | if available | custom | Accommodation semantic segment (house, pitch, room, berth, apartment, other). Source: Search rentable type segment. |
price_range_min | 100 | if available | custom | Minimum total price. Source: Search price range minimum. |
price_range_max | 500 | if available | custom | Maximum total price. Source: Search price range maximum. |
sorting_id | price_asc | if available | custom | Sorting option id. Source: Search sorting choice. |
amenities | {...} | if available | custom | Amenity facet id mapped to arrays of value ids. Source: Search amenity selections. |
amenities_count | 2 | if available | custom | Count of active amenity selections (includes price range). Source: Number of active amenity selections plus price range. |
has_results | true | if available | custom | True when results_count > 0. Source: Derived from availability search results. |
results_count | 42 | if available | custom | Total result count (null when unknown). Source: Availability search total results. |
special_period_id | 123 | if available | custom | Special period id when the search dates match a defined special period (selected or inferred). Source: Special period id. |
special_period_name | Summer Holiday | if available | custom | Localized special period name when the search dates match a defined special period (selected or inferred). Source: Special period name. |
guest_group | {...} (see below) | if available | object | Guest counts by group (see guest_group fields). Source: Guest group from search form. |
search.guest_group
Guest counts by group (see guest_group fields). Source: Guest group from search form.
Fields below apply only when search.guest_group is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
seniors | 0 | always | custom | Number of seniors. Source: Guest group seniors count. |
adults | 2 | always | custom | Number of adults. Source: Guest group adults count. |
adolescents | 0 | always | custom | Number of adolescents. Source: Guest group adolescents count. |
children | 1 | always | custom | Number of children. Source: Guest group children count. |
babies | 0 | always | custom | Number of babies. Source: Guest group babies count. |
pets | 0 | always | custom | Number of pets. Source: Guest group pets count. |
total | 3 | always | custom | Total guests (sum of guest group counts). Source: Guest group total. |
Sample data layer snippet
dataLayer.push({"event":"add_to_cart","ecommerce":{"currency":"EUR","value":350.0,"items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","item_brand":"Administration Name","item_category":"Accommodation","item_category2":"house","item_variant":"single_night","item_list_id":"cart","item_list_name":"Cart","item_country":"Netherlands","item_region":"Twente","item_city":"Enschede","administration_id":"321321","administration_name":"Administration Name","coupon":"SUMMER10","discount":25.0,"price":350.0,"quantity":1,"index":1,"start_date":"2026-02-20","end_date":"2026-02-22","google_business_vertical":"hotel_rental"}]},"search":{"start_date":"2026-02-20","end_date":"2026-02-22","nights":2,"rentable_type":"house","guest_group":{"seniors":0,"adults":2,"adolescents":0,"children":1,"babies":0,"pets":0,"total":3},"price_range_min":100,"price_range_max":500,"sorting_id":"price_asc","amenities":{"facility":["pool"]},"amenities_count":2,"has_results":true,"results_count":42,"special_period_id":123,"special_period_name":"Summer Holiday"}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
remove_from_cart
A user removes items from the cart.
| Status | active |
|---|---|
| Type | event |
| Available on | Booking site |
| Portals | Checkout portal |
| Flow | Booking site cart + checkout portal upgrades remove |
Triggered when a user removes one or more items from the cart on a booking site or removes extras/upgrades in the checkout portal.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
currency | EUR | always | ga4 | Currency of the items associated with the event, in 3-letter ISO 4217 format. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
value | 350.0 | always | ga4 | Total value of the event. Source: Total order/booking value or sum of item prices. |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | always | ga4 | The ID of the rentable type. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | if available | ga4 | The name of the rentable type. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
item_brand | Administration Name | if available | ga4 | The localized name of the site. Source: Checkout portal: administration name. Website search: site/brand name shown on the website (can differ from the administration name). |
item_category | Accommodation | if available | ga4 | Top-level item type.
Source: Checkout portal: |
item_category2 | house | if available | ga4 | Semantic segment for accommodations or sub-bucket for extras. Accommodation: house pitch room berth apartment other Extras: Amenity Upgrade PackageSource: Checkout portal: accommodation semantic segment or extras bucket. Website search: accommodation semantic segment. |
item_category3 | if available | ga4 | PMS extra type for extras only.
Source: Checkout portal extras only: cost extra_type. Not set for accommodations, packages, or website search. | |
item_variant | single_night | if available | ga4 | Stay duration category for the accommodation.
Source: Checkout portal accommodations and CMS availability items; derived from arrival/departure. |
item_list_id | cart | if available | ga4 | ID of the list where the item is shown. Source: Website search list id (availability_search/property_search). Cart/checkout events may supply list id like Cart or Checkout. |
item_list_name | Cart | if available | ga4 | Name of the list where the item is shown. Source: Website search list name (Availability search/Property search). Cart/checkout events may supply list name like Cart or Checkout. |
item_country | Netherlands | if available | custom | The country where the administration is located. Source: Administration country from BEX (shared across checkout portal and website search). |
item_region | Twente | if available | custom | The region where the administration is located. Source: Administration region from BEX (shared across checkout portal and website search). |
item_city | Enschede | if available | custom | The city where the administration is located. Source: Administration city from BEX (shared across checkout portal and website search). |
administration_id | 321321 | if available | custom | The ID of the administration in BEX PMS. Source: Checkout portal: BEX administration id. Website search: the same BEX administration id (Booking Experts administration mapping). |
administration_name | Administration Name | if available | custom | The name of the administration in BEX PMS. Source: Checkout portal: BEX administration name. Website search: the same BEX administration name (Booking Experts administration mapping). |
coupon | SUMMER10 | if available | ga4 | Coupon applied to the item. Source: Coupon code applied to the reservation or order item (first code, if any). |
discount | 25.0 | if available | ga4 | Discount applied to the item. Source: Discount amount for the order item. |
price | 350.0 | if available | ga4 | Price for the item line (stay total for accommodation). Source: Website search: availability/property price for the stay. Checkout portal: order item unit price; accommodation uses stay total derived from booking total minus upgrades. |
quantity | 1 | if available | ga4 | Quantity of the item. Source: Order item quantity; otherwise 1. |
index | 1 | if available | ga4 | Position of the item in the list. Source: Position in the result list (website search only). |
start_date | 2026-02-20 | if available | custom | The date of arrival for availability. Source: Stay arrival date or availability start date. |
end_date | 2026-02-22 | if available | custom | The date of departure for availability. Source: Stay departure date or availability end date. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
Sample data layer snippet
dataLayer.push({"event":"remove_from_cart","ecommerce":{"currency":"EUR","value":350.0,"items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","item_brand":"Administration Name","item_category":"Accommodation","item_category2":"house","item_variant":"single_night","item_list_id":"cart","item_list_name":"Cart","item_country":"Netherlands","item_region":"Twente","item_city":"Enschede","administration_id":"321321","administration_name":"Administration Name","coupon":"SUMMER10","discount":25.0,"price":350.0,"quantity":1,"index":1,"start_date":"2026-02-20","end_date":"2026-02-22","google_business_vertical":"hotel_rental"}]}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
view_cart
A user views their cart.
| Status | active |
|---|---|
| Type | event |
| Available on | Booking site |
| Portals | Checkout portal |
| Flow | Booking site cart + checkout portal upgrades view |
Triggered when a user views their cart on a booking site or reaches the upgrades step in the checkout portal.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
currency | EUR | always | ga4 | Currency of the items associated with the event, in 3-letter ISO 4217 format. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
value | 350.0 | always | ga4 | Total value of the cart. Source: Total order/booking value or sum of item prices. |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | always | ga4 | The ID of the rentable type. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | always | ga4 | The name of the rentable type. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
item_brand | Administration Name | if available | ga4 | The localized name of the site. Source: Checkout portal: administration name. Website search: site/brand name shown on the website (can differ from the administration name). |
item_category | Accommodation | always | ga4 | Top-level item type.
Source: Checkout portal: |
item_category2 | house | if available | ga4 | Semantic segment for accommodations or sub-bucket for extras. Accommodation: house pitch room berth apartment other Extras: Amenity Upgrade PackageSource: Checkout portal: accommodation semantic segment or extras bucket. Website search: accommodation semantic segment. |
item_category3 | if available | ga4 | PMS extra type for extras only.
Source: Checkout portal extras only: cost extra_type. Not set for accommodations, packages, or website search. | |
item_variant | single_night | if available | ga4 | Stay duration category for the accommodation.
Source: Checkout portal accommodations and CMS availability items; derived from arrival/departure. |
item_list_id | cart | if available | ga4 | ID of the list where the item is shown. Source: Website search list id (availability_search/property_search). Cart/checkout events may supply list id like Cart or Checkout. |
item_list_name | Cart | if available | ga4 | Name of the list where the item is shown. Source: Website search list name (Availability search/Property search). Cart/checkout events may supply list name like Cart or Checkout. |
coupon | SUMMER10 | if available | ga4 | Coupon applied to the item. Source: Coupon code applied to the reservation or order item (first code, if any). |
discount | 25.0 | if available | ga4 | Discount applied to the item. Source: Discount amount for the order item. |
price | 350.0 | if available | ga4 | Price for the item line (stay total for accommodation). Source: Website search: availability/property price for the stay. Checkout portal: order item unit price; accommodation uses stay total derived from booking total minus upgrades. |
quantity | 1 | if available | ga4 | Quantity of the item. Source: Order item quantity; otherwise 1. |
index | 1 | if available | ga4 | Position of the item in the list. Source: Position in the result list (website search only). |
item_country | Netherlands | if available | custom | The country where the administration is located. Source: Administration country from BEX (shared across checkout portal and website search). |
item_region | Twente | if available | custom | The region where the administration is located. Source: Administration region from BEX (shared across checkout portal and website search). |
item_city | Enschede | if available | custom | The city where the administration is located. Source: Administration city from BEX (shared across checkout portal and website search). |
administration_id | 321321 | if available | custom | The ID of the administration in BEX PMS. Source: Checkout portal: BEX administration id. Website search: the same BEX administration id (Booking Experts administration mapping). |
administration_name | Administration Name | if available | custom | The name of the administration in BEX PMS. Source: Checkout portal: BEX administration name. Website search: the same BEX administration name (Booking Experts administration mapping). |
start_date | 2026-02-20 | if available | custom | The date when the booking starts. Source: Stay arrival date or availability start date. |
end_date | 2026-02-22 | if available | custom | The date when the booking ends. Source: Stay departure date or availability end date. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
Sample data layer snippet
dataLayer.push({"event":"view_cart","ecommerce":{"currency":"EUR","value":350.0,"items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","item_brand":"Administration Name","item_category":"Accommodation","item_category2":"house","item_variant":"single_night","item_list_id":"cart","item_list_name":"Cart","coupon":"SUMMER10","discount":25.0,"price":350.0,"quantity":1,"index":1,"item_country":"Netherlands","item_region":"Twente","item_city":"Enschede","administration_id":"321321","administration_name":"Administration Name","start_date":"2026-02-20","end_date":"2026-02-22","google_business_vertical":"hotel_rental"}]}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
begin_checkout
A user begins checkout.
| Status | active |
|---|---|
| Type | event |
| Portals | Checkout portal |
| Flow | Checkout portal entry (stay step) |
Triggered when a user begins checkout.
Source: checkout portal flow (PMS). This is emitted when the Stay step is shown.
If a CMS search snapshot cookie is present, a top-level search object is included.
Checkout portal emits a booking snapshot with totals and guest group counts (status = concept).
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
search | {...} (see below) | if available | object | Availability search snapshot for the checkout action. Source: Availability search snapshot when checkout starts (shared from CMS via cookie). |
booking | {...} (see below) | if available | object | Booking snapshot with status concept and checkout totals. Source: Checkout portal booking summary. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
currency | EUR | always | ga4 | Currency of the items associated with the event, in 3-letter ISO 4217 format. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
value | 350.0 | always | ga4 | Total value of the checkout. Source: Total order/booking value or sum of item prices. |
coupon | SUMMER10 | if available | ga4 | Coupon code applied to the checkout. Source: Applied coupon codes for the booking/reservation, comma-separated when multiple. |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | always | ga4 | The ID of the rentable type. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | always | ga4 | The name of the rentable type. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
item_brand | Administration Name | if available | ga4 | The localized name of the site. Source: Checkout portal: administration name. Website search: site/brand name shown on the website (can differ from the administration name). |
item_category | Accommodation | always | ga4 | Top-level item type.
Source: Checkout portal: |
item_category2 | house | if available | ga4 | Semantic segment for accommodations or sub-bucket for extras. Accommodation: house pitch room berth apartment other Extras: Amenity Upgrade PackageSource: Checkout portal: accommodation semantic segment or extras bucket. Website search: accommodation semantic segment. |
item_category3 | if available | ga4 | PMS extra type for extras only.
Source: Checkout portal extras only: cost extra_type. Not set for accommodations, packages, or website search. | |
item_variant | single_night | if available | ga4 | Stay duration category for the accommodation.
Source: Checkout portal accommodations and CMS availability items; derived from arrival/departure. |
item_list_id | checkout | if available | ga4 | ID of the list where the item is shown. Source: Website search list id (availability_search/property_search). Cart/checkout events may supply list id like Cart or Checkout. |
item_list_name | Checkout | if available | ga4 | Name of the list where the item is shown. Source: Website search list name (Availability search/Property search). Cart/checkout events may supply list name like Cart or Checkout. |
coupon | SUMMER10 | if available | ga4 | Coupon applied to the item. Source: Coupon code applied to the reservation or order item (first code, if any). |
discount | 25.0 | if available | ga4 | Discount applied to the item. Source: Discount amount for the order item. |
price | 350.0 | if available | ga4 | Price for the item line (stay total for accommodation). Source: Website search: availability/property price for the stay. Checkout portal: order item unit price; accommodation uses stay total derived from booking total minus upgrades. |
quantity | 1 | if available | ga4 | Quantity of the item. Source: Order item quantity; otherwise 1. |
index | 1 | if available | ga4 | Position of the item in the list. Source: Position in the result list (website search only). |
item_country | Netherlands | if available | custom | The country where the administration is located. Source: Administration country from BEX (shared across checkout portal and website search). |
item_region | Twente | if available | custom | The region where the administration is located. Source: Administration region from BEX (shared across checkout portal and website search). |
item_city | Enschede | if available | custom | The city where the administration is located. Source: Administration city from BEX (shared across checkout portal and website search). |
administration_id | 321321 | if available | custom | The ID of the administration in BEX PMS. Source: Checkout portal: BEX administration id. Website search: the same BEX administration id (Booking Experts administration mapping). |
administration_name | Administration Name | if available | custom | The name of the administration in BEX PMS. Source: Checkout portal: BEX administration name. Website search: the same BEX administration name (Booking Experts administration mapping). |
start_date | 2026-02-20 | if available | custom | The date when the booking starts. Source: Stay arrival date or availability start date. |
end_date | 2026-02-22 | if available | custom | The date when the booking ends. Source: Stay departure date or availability end date. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
search
Availability search snapshot for the checkout action. Source: Availability search snapshot when checkout starts (shared from CMS via cookie).
Fields below apply only when search is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
start_date | 2026-02-20 | if available | custom | Arrival date for the availability search (YYYY-MM-DD, null when missing). Source: Website availability search arrival date. |
end_date | 2026-02-22 | if available | custom | Departure date for the availability search (YYYY-MM-DD, null when missing). Source: Website availability search departure date. |
nights | 2 | if available | custom | Length of stay in nights (null when dates are missing). Source: Derived from search dates or nights selector. |
rentable_type | house | if available | custom | Accommodation semantic segment (house, pitch, room, berth, apartment, other). Source: Search rentable type segment. |
price_range_min | 100 | if available | custom | Minimum total price. Source: Search price range minimum. |
price_range_max | 500 | if available | custom | Maximum total price. Source: Search price range maximum. |
sorting_id | price_asc | if available | custom | Sorting option id. Source: Search sorting choice. |
amenities | {...} | if available | custom | Amenity facet id mapped to arrays of value ids. Source: Search amenity selections. |
amenities_count | 2 | if available | custom | Count of active amenity selections (includes price range). Source: Number of active amenity selections plus price range. |
has_results | true | if available | custom | True when results_count > 0. Source: Derived from availability search results. |
results_count | 42 | if available | custom | Total result count (null when unknown). Source: Availability search total results. |
special_period_id | 123 | if available | custom | Special period id when the search dates match a defined special period (selected or inferred). Source: Special period id. |
special_period_name | Summer Holiday | if available | custom | Localized special period name when the search dates match a defined special period (selected or inferred). Source: Special period name. |
guest_group | {...} (see below) | if available | object | Guest counts by group (see guest_group fields). Source: Guest group from search form. |
search.guest_group
Guest counts by group (see guest_group fields). Source: Guest group from search form.
Fields below apply only when search.guest_group is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
seniors | 0 | always | custom | Number of seniors. Source: Guest group seniors count. |
adults | 2 | always | custom | Number of adults. Source: Guest group adults count. |
adolescents | 0 | always | custom | Number of adolescents. Source: Guest group adolescents count. |
children | 1 | always | custom | Number of children. Source: Guest group children count. |
babies | 0 | always | custom | Number of babies. Source: Guest group babies count. |
pets | 0 | always | custom | Number of pets. Source: Guest group pets count. |
total | 3 | always | custom | Total guests (sum of guest group counts). Source: Guest group total. |
booking
Booking snapshot with status concept and checkout totals. Source: Checkout portal booking summary.
Fields below apply only when booking is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
status | booked | if available | custom | Booking lifecycle status (concept/option/booked/cancelled). Source: Checkout portal status override or booking state from PMS. |
final | true | if available | custom | True when the booking is confirmed or imported. Source: Confirmed/imported flag from PMS. |
currency | EUR | if available | ga4 | Booking currency (ISO 4217). Source: Booking currency. |
total | 350 | if available | custom | Sum of all guest order items. Source: Total of guest debtor items. |
base_rent_total | 350 | if available | custom | Base rent (accommodation rent) order items. Source: Base rent total. |
upgrade_total | 0 | if available | custom | Upgrade order items (bundles/extras), excluding deposits. Source: Upgrade extras total. |
preference_total | 0 | if available | custom | Preference order items (amenities/preferences). Source: Preference items total. |
deposit_total | 0 | if available | custom | Reservation deposit order items (non-deferred). Source: Deposit total. |
deferred_deposit_total | 0 | if available | custom | Reservation deposit order items marked deferred. Source: Deferred deposit total. |
security_deposit_total | 0 | if available | custom | Security deposits (borg), from security deposit policies. Source: Security deposit total. |
tourist_taxes_total | 0 | if available | custom | Tourist tax order items. Source: Tourist taxes total. |
vat_total | 50 | if available | custom | VAT total for guest debtor items. Source: VAT total. |
guest_group | {...} (see below) | if available | object | Guest counts by group (see guest_group fields). Source: Aggregated guest group from reservations. |
booking.guest_group
Guest counts by group (see guest_group fields). Source: Aggregated guest group from reservations.
Fields below apply only when booking.guest_group is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
seniors | 0 | always | custom | Number of seniors. Source: Guest group seniors count. |
adults | 2 | always | custom | Number of adults. Source: Guest group adults count. |
adolescents | 0 | always | custom | Number of adolescents. Source: Guest group adolescents count. |
children | 1 | always | custom | Number of children. Source: Guest group children count. |
babies | 0 | always | custom | Number of babies. Source: Guest group babies count. |
pets | 0 | always | custom | Number of pets. Source: Guest group pets count. |
total | 3 | always | custom | Total guests (sum of guest group counts). Source: Guest group total. |
Sample data layer snippet
dataLayer.push({"event":"begin_checkout","ecommerce":{"currency":"EUR","value":350.0,"coupon":"SUMMER10","items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","item_brand":"Administration Name","item_category":"Accommodation","item_category2":"house","item_variant":"single_night","item_list_id":"checkout","item_list_name":"Checkout","coupon":"SUMMER10","discount":25.0,"price":350.0,"quantity":1,"index":1,"item_country":"Netherlands","item_region":"Twente","item_city":"Enschede","administration_id":"321321","administration_name":"Administration Name","start_date":"2026-02-20","end_date":"2026-02-22","google_business_vertical":"hotel_rental"}]},"search":{"start_date":"2026-02-20","end_date":"2026-02-22","nights":2,"rentable_type":"house","guest_group":{"seniors":0,"adults":2,"adolescents":0,"children":1,"babies":0,"pets":0,"total":3},"price_range_min":100,"price_range_max":500,"sorting_id":"price_asc","amenities":{"facility":["pool"]},"amenities_count":2,"has_results":true,"results_count":42,"special_period_id":123,"special_period_name":"Summer Holiday"},"booking":{"status":"concept","final":false,"guest_group":{"seniors":0,"adults":2,"adolescents":0,"children":1,"babies":0,"pets":0,"total":3},"currency":"EUR","total":350,"base_rent_total":350,"upgrade_total":0,"preference_total":0,"deposit_total":0,"deferred_deposit_total":0,"security_deposit_total":0,"tourist_taxes_total":0,"vat_total":50}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
We do not auto-clear booking. If you map booking outside booking events, clear it manually with dataLayer.push({ booking: null }).
add_shipping_info
A user submits guest details during checkout.
| Status | active |
|---|---|
| Type | event |
| Portals | Checkout portal |
| Flow | Checkout portal guest details step |
Triggered after a user successfully submits the details step during checkout.
Emitted when the confirmation step is loaded directly after the details form submit.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
currency | EUR | always | ga4 | Currency of the items associated with the event, in 3-letter ISO 4217 format. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
value | 350.0 | always | ga4 | Total value of the checkout. Source: Total order/booking value or sum of item prices. |
coupon | SUMMER10 | if available | ga4 | Coupon code applied to the checkout. Source: Applied coupon codes for the booking/reservation, comma-separated when multiple. |
shipping_tier | Standard | if available | ga4 | Shipping tier selected by the user. Source: Not used in our PMS flows. |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | always | ga4 | The ID of the rentable type. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | always | ga4 | The name of the rentable type. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
item_brand | Administration Name | if available | ga4 | The localized name of the site. Source: Checkout portal: administration name. Website search: site/brand name shown on the website (can differ from the administration name). |
item_category | Accommodation | always | ga4 | Top-level item type.
Source: Checkout portal: |
item_category2 | house | if available | ga4 | Semantic segment for accommodations or sub-bucket for extras. Accommodation: house pitch room berth apartment other Extras: Amenity Upgrade PackageSource: Checkout portal: accommodation semantic segment or extras bucket. Website search: accommodation semantic segment. |
item_category3 | if available | ga4 | PMS extra type for extras only.
Source: Checkout portal extras only: cost extra_type. Not set for accommodations, packages, or website search. | |
item_variant | single_night | if available | ga4 | Stay duration category for the accommodation.
Source: Checkout portal accommodations and CMS availability items; derived from arrival/departure. |
item_list_id | checkout | if available | ga4 | ID of the list where the item is shown. Source: Website search list id (availability_search/property_search). Cart/checkout events may supply list id like Cart or Checkout. |
item_list_name | Checkout | if available | ga4 | Name of the list where the item is shown. Source: Website search list name (Availability search/Property search). Cart/checkout events may supply list name like Cart or Checkout. |
coupon | SUMMER10 | if available | ga4 | Coupon applied to the item. Source: Coupon code applied to the reservation or order item (first code, if any). |
discount | 25.0 | if available | ga4 | Discount applied to the item. Source: Discount amount for the order item. |
price | 350.0 | if available | ga4 | Price for the item line (stay total for accommodation). Source: Website search: availability/property price for the stay. Checkout portal: order item unit price; accommodation uses stay total derived from booking total minus upgrades. |
quantity | 1 | if available | ga4 | Quantity of the item. Source: Order item quantity; otherwise 1. |
index | 1 | if available | ga4 | Position of the item in the list. Source: Position in the result list (website search only). |
item_country | Netherlands | if available | custom | The country where the administration is located. Source: Administration country from BEX (shared across checkout portal and website search). |
item_region | Twente | if available | custom | The region where the administration is located. Source: Administration region from BEX (shared across checkout portal and website search). |
item_city | Enschede | if available | custom | The city where the administration is located. Source: Administration city from BEX (shared across checkout portal and website search). |
administration_id | 321321 | if available | custom | The ID of the administration in BEX PMS. Source: Checkout portal: BEX administration id. Website search: the same BEX administration id (Booking Experts administration mapping). |
administration_name | Administration Name | if available | custom | The name of the administration in BEX PMS. Source: Checkout portal: BEX administration name. Website search: the same BEX administration name (Booking Experts administration mapping). |
start_date | 2026-02-20 | if available | custom | The date when the booking starts. Source: Stay arrival date or availability start date. |
end_date | 2026-02-22 | if available | custom | The date when the booking ends. Source: Stay departure date or availability end date. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
Sample data layer snippet
dataLayer.push({"event":"add_shipping_info","ecommerce":{"currency":"EUR","value":350.0,"coupon":"SUMMER10","shipping_tier":"Standard","items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","item_brand":"Administration Name","item_category":"Accommodation","item_category2":"house","item_variant":"single_night","item_list_id":"checkout","item_list_name":"Checkout","coupon":"SUMMER10","discount":25.0,"price":350.0,"quantity":1,"index":1,"item_country":"Netherlands","item_region":"Twente","item_city":"Enschede","administration_id":"321321","administration_name":"Administration Name","start_date":"2026-02-20","end_date":"2026-02-22","google_business_vertical":"hotel_rental"}]}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
add_payment_info
A user selects a payment method during checkout.
| Status | active |
|---|---|
| Type | event |
| Portals | Checkout portal |
| Flow | Checkout portal confirm step (payment selection) |
Triggered when a user selects a payment method during checkout.
Emitted when the user selects a payment method in the payment portal.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
currency | EUR | always | ga4 | Currency of the items associated with the event, in 3-letter ISO 4217 format. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
value | 350.0 | always | ga4 | Total value of the checkout. Source: Total order/booking value or sum of item prices. |
coupon | SUMMER10 | if available | ga4 | Coupon code applied to the checkout. Source: Applied coupon codes for the booking/reservation, comma-separated when multiple. |
payment_type | ideal | always | ga4 | Payment method selected by the user.
Source: Payment method kind from the payment portal. |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | always | ga4 | The ID of the rentable type. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | always | ga4 | The name of the rentable type. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
item_brand | Administration Name | if available | ga4 | The localized name of the site. Source: Checkout portal: administration name. Website search: site/brand name shown on the website (can differ from the administration name). |
item_category | Accommodation | always | ga4 | Top-level item type.
Source: Checkout portal: |
item_category2 | house | if available | ga4 | Semantic segment for accommodations or sub-bucket for extras. Accommodation: house pitch room berth apartment other Extras: Amenity Upgrade PackageSource: Checkout portal: accommodation semantic segment or extras bucket. Website search: accommodation semantic segment. |
item_category3 | if available | ga4 | PMS extra type for extras only.
Source: Checkout portal extras only: cost extra_type. Not set for accommodations, packages, or website search. | |
item_variant | single_night | if available | ga4 | Stay duration category for the accommodation.
Source: Checkout portal accommodations and CMS availability items; derived from arrival/departure. |
item_list_id | checkout | if available | ga4 | ID of the list where the item is shown. Source: Website search list id (availability_search/property_search). Cart/checkout events may supply list id like Cart or Checkout. |
item_list_name | Checkout | if available | ga4 | Name of the list where the item is shown. Source: Website search list name (Availability search/Property search). Cart/checkout events may supply list name like Cart or Checkout. |
coupon | SUMMER10 | if available | ga4 | Coupon applied to the item. Source: Coupon code applied to the reservation or order item (first code, if any). |
discount | 25.0 | if available | ga4 | Discount applied to the item. Source: Discount amount for the order item. |
price | 350.0 | if available | ga4 | Price for the item line (stay total for accommodation). Source: Website search: availability/property price for the stay. Checkout portal: order item unit price; accommodation uses stay total derived from booking total minus upgrades. |
quantity | 1 | if available | ga4 | Quantity of the item. Source: Order item quantity; otherwise 1. |
index | 1 | if available | ga4 | Position of the item in the list. Source: Position in the result list (website search only). |
item_country | Netherlands | if available | custom | The country where the administration is located. Source: Administration country from BEX (shared across checkout portal and website search). |
item_region | Twente | if available | custom | The region where the administration is located. Source: Administration region from BEX (shared across checkout portal and website search). |
item_city | Enschede | if available | custom | The city where the administration is located. Source: Administration city from BEX (shared across checkout portal and website search). |
administration_id | 321321 | if available | custom | The ID of the administration in BEX PMS. Source: Checkout portal: BEX administration id. Website search: the same BEX administration id (Booking Experts administration mapping). |
administration_name | Administration Name | if available | custom | The name of the administration in BEX PMS. Source: Checkout portal: BEX administration name. Website search: the same BEX administration name (Booking Experts administration mapping). |
start_date | 2026-02-20 | if available | custom | The date when the booking starts. Source: Stay arrival date or availability start date. |
end_date | 2026-02-22 | if available | custom | The date when the booking ends. Source: Stay departure date or availability end date. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
Sample data layer snippet
dataLayer.push({"event":"add_payment_info","ecommerce":{"currency":"EUR","value":350.0,"coupon":"SUMMER10","payment_type":"ideal","items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","item_brand":"Administration Name","item_category":"Accommodation","item_category2":"house","item_variant":"single_night","item_list_id":"checkout","item_list_name":"Checkout","coupon":"SUMMER10","discount":25.0,"price":350.0,"quantity":1,"index":1,"item_country":"Netherlands","item_region":"Twente","item_city":"Enschede","administration_id":"321321","administration_name":"Administration Name","start_date":"2026-02-20","end_date":"2026-02-22","google_business_vertical":"hotel_rental"}]}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
purchase
A user completes a purchase.
| Status | active |
|---|---|
| Type | event |
| Portals | Checkout portal |
| Flow | Checkout portal after payment success |
Triggered when a user completes a purchase.
Emitted on the checkout portal after returning from the payment portal with a success status.
transaction_iduses the booking number in PMS (non-PII).customer_typeis derived from prior bookings in the last 540 days when a contact is known.
Additional booking metadata can be included at the top level under booking (booking.status reflects the booking state).
Checkout portal includes portal_settings to analyze required fields impact on conversion.
Affiliate payouts should generally use booking.base_rent_total to exclude upgrades and deposits.
If marketing consent is granted, include user_data with hashed identifiers.
No address fields are sent.
If a CMS search snapshot cookie is present, a top-level search object is included.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
search | {...} (see below) | if available | object | Availability search snapshot for the purchase. Source: Availability search snapshot shared from CMS via cookie. |
booking | {...} (see below) | if available | object | Booking object. Source: Booking object. booking.status/final/guest_group plus booking totals fields are populated for checkout portal purchase/lead events. |
portal_settings | {...} (see below) | if available | object | Checkout portal settings snapshot (enabled/required fields and contact toggles). Source: Organization checkout portal settings. |
user_data | {...} (see below) | if available | object | Hashed user-provided data for Google tags. Source: Hashed email/phone from booking contact, sent only with marketing consent. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
transaction_id | ORDER-123 | always | ga4 | Unique transaction ID. Source: Booking reference/number. |
affiliation | Administration Name | if available | custom | Affiliation or brand for the purchase. Source: Administration/site name used for reporting. |
currency | EUR | always | ga4 | Currency of the items associated with the event, in 3-letter ISO 4217 format. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
value | 350.0 | always | ga4 | Total value of the purchase. Source: Total order/booking value or sum of item prices. |
customer_type | new | if available | custom | Whether the customer is new or returning ("new" or "returning"). PMS uses a 540-day lookback window. Source: New vs returning based on booking history within 540 days. |
payment_type | ideal | if available | ga4 | Payment method used for the booking. Source: Payment method kind from the payment portal. |
tax | 20.0 | if available | ga4 | Total tax amount. Source: Not sent separately; tax is included in totals. |
shipping | 0.0 | if available | ga4 | Shipping amount. Source: Not used in our PMS flows. |
coupon | SUMMER10 | if available | ga4 | Coupon code applied to the purchase. Source: Applied coupon codes for the booking/reservation, comma-separated when multiple. |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | always | ga4 | The ID of the rentable type. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | always | ga4 | The name of the rentable type. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
item_brand | Administration Name | if available | ga4 | The localized name of the site. Source: Checkout portal: administration name. Website search: site/brand name shown on the website (can differ from the administration name). |
item_category | Accommodation | always | ga4 | Top-level item type.
Source: Checkout portal: |
item_category2 | house | if available | ga4 | Semantic segment for accommodations or sub-bucket for extras. Accommodation: house pitch room berth apartment other Extras: Amenity Upgrade PackageSource: Checkout portal: accommodation semantic segment or extras bucket. Website search: accommodation semantic segment. |
item_category3 | if available | ga4 | PMS extra type for extras only.
Source: Checkout portal extras only: cost extra_type. Not set for accommodations, packages, or website search. | |
item_variant | single_night | if available | ga4 | Stay duration category for the accommodation.
Source: Checkout portal accommodations and CMS availability items; derived from arrival/departure. |
item_list_id | checkout | if available | ga4 | ID of the list where the item is shown. Source: Website search list id (availability_search/property_search). Cart/checkout events may supply list id like Cart or Checkout. |
item_list_name | Checkout | if available | ga4 | Name of the list where the item is shown. Source: Website search list name (Availability search/Property search). Cart/checkout events may supply list name like Cart or Checkout. |
item_country | Netherlands | if available | custom | The country where the administration is located. Source: Administration country from BEX (shared across checkout portal and website search). |
item_region | Twente | if available | custom | The region where the administration is located. Source: Administration region from BEX (shared across checkout portal and website search). |
item_city | Enschede | if available | custom | The city where the administration is located. Source: Administration city from BEX (shared across checkout portal and website search). |
administration_id | 321321 | if available | custom | The ID of the administration in BEX PMS. Source: Checkout portal: BEX administration id. Website search: the same BEX administration id (Booking Experts administration mapping). |
administration_name | Administration Name | if available | custom | The name of the administration in BEX PMS. Source: Checkout portal: BEX administration name. Website search: the same BEX administration name (Booking Experts administration mapping). |
price | 350.0 | if available | ga4 | Price for the item line (stay total for accommodation). Source: Website search: availability/property price for the stay. Checkout portal: order item unit price; accommodation uses stay total derived from booking total minus upgrades. |
quantity | 1 | if available | ga4 | Quantity of the item. Source: Order item quantity; otherwise 1. |
discount | 25.0 | if available | ga4 | Discount applied to the item. Source: Discount amount for the order item. |
coupon | SUMMER10 | if available | ga4 | Coupon applied to the item. Source: Coupon code applied to the reservation or order item (first code, if any). |
index | 1 | if available | ga4 | Position of the item in the list. Source: Position in the result list (website search only). |
start_date | 2026-02-20 | if available | custom | The date when the booking starts. Source: Stay arrival date or availability start date. |
end_date | 2026-02-22 | if available | custom | The date when the booking ends. Source: Stay departure date or availability end date. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
search
Availability search snapshot for the purchase. Source: Availability search snapshot shared from CMS via cookie.
Fields below apply only when search is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
start_date | 2026-02-20 | if available | custom | Arrival date for the availability search (YYYY-MM-DD, null when missing). Source: Website availability search arrival date. |
end_date | 2026-02-22 | if available | custom | Departure date for the availability search (YYYY-MM-DD, null when missing). Source: Website availability search departure date. |
nights | 2 | if available | custom | Length of stay in nights (null when dates are missing). Source: Derived from search dates or nights selector. |
rentable_type | house | if available | custom | Accommodation semantic segment (house, pitch, room, berth, apartment, other). Source: Search rentable type segment. |
price_range_min | 100 | if available | custom | Minimum total price. Source: Search price range minimum. |
price_range_max | 500 | if available | custom | Maximum total price. Source: Search price range maximum. |
sorting_id | price_asc | if available | custom | Sorting option id. Source: Search sorting choice. |
amenities | {...} | if available | custom | Amenity facet id mapped to arrays of value ids. Source: Search amenity selections. |
amenities_count | 2 | if available | custom | Count of active amenity selections (includes price range). Source: Number of active amenity selections plus price range. |
has_results | true | if available | custom | True when results_count > 0. Source: Derived from availability search results. |
results_count | 42 | if available | custom | Total result count (null when unknown). Source: Availability search total results. |
special_period_id | 123 | if available | custom | Special period id when the search dates match a defined special period (selected or inferred). Source: Special period id. |
special_period_name | Summer Holiday | if available | custom | Localized special period name when the search dates match a defined special period (selected or inferred). Source: Special period name. |
guest_group | {...} (see below) | if available | object | Guest counts by group (see guest_group fields). Source: Guest group from search form. |
search.guest_group
Guest counts by group (see guest_group fields). Source: Guest group from search form.
Fields below apply only when search.guest_group is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
seniors | 0 | always | custom | Number of seniors. Source: Guest group seniors count. |
adults | 2 | always | custom | Number of adults. Source: Guest group adults count. |
adolescents | 0 | always | custom | Number of adolescents. Source: Guest group adolescents count. |
children | 1 | always | custom | Number of children. Source: Guest group children count. |
babies | 0 | always | custom | Number of babies. Source: Guest group babies count. |
pets | 0 | always | custom | Number of pets. Source: Guest group pets count. |
total | 3 | always | custom | Total guests (sum of guest group counts). Source: Guest group total. |
booking
Booking object. Source: Booking object. booking.status/final/guest_group plus booking totals fields are populated for checkout portal purchase/lead events.
Fields below apply only when booking is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
status | booked | if available | custom | Booking lifecycle status (concept/option/booked/cancelled). Source: Checkout portal status override or booking state from PMS. |
final | true | if available | custom | True when the booking is confirmed or imported. Source: Confirmed/imported flag from PMS. |
currency | EUR | if available | ga4 | Booking currency (ISO 4217). Source: Booking currency. |
total | 350 | if available | custom | Sum of all guest order items. Source: Total of guest debtor items. |
base_rent_total | 350 | if available | custom | Base rent (accommodation rent) order items. Source: Base rent total. |
upgrade_total | 0 | if available | custom | Upgrade order items (bundles/extras), excluding deposits. Source: Upgrade extras total. |
preference_total | 0 | if available | custom | Preference order items (amenities/preferences). Source: Preference items total. |
deposit_total | 0 | if available | custom | Reservation deposit order items (non-deferred). Source: Deposit total. |
deferred_deposit_total | 0 | if available | custom | Reservation deposit order items marked deferred. Source: Deferred deposit total. |
security_deposit_total | 0 | if available | custom | Security deposits (borg), from security deposit policies. Source: Security deposit total. |
tourist_taxes_total | 0 | if available | custom | Tourist tax order items. Source: Tourist taxes total. |
vat_total | 50 | if available | custom | VAT total for guest debtor items. Source: VAT total. |
guest_group | {...} (see below) | if available | object | Guest counts by group (see guest_group fields). Source: Aggregated guest group from reservations. |
booking.guest_group
Guest counts by group (see guest_group fields). Source: Aggregated guest group from reservations.
Fields below apply only when booking.guest_group is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
seniors | 0 | always | custom | Number of seniors. Source: Guest group seniors count. |
adults | 2 | always | custom | Number of adults. Source: Guest group adults count. |
adolescents | 0 | always | custom | Number of adolescents. Source: Guest group adolescents count. |
children | 1 | always | custom | Number of children. Source: Guest group children count. |
babies | 0 | always | custom | Number of babies. Source: Guest group babies count. |
pets | 0 | always | custom | Number of pets. Source: Guest group pets count. |
total | 3 | always | custom | Total guests (sum of guest group counts). Source: Guest group total. |
portal_settings
Checkout portal settings snapshot (enabled/required fields and contact toggles). Source: Organization checkout portal settings.
Fields below apply only when portal_settings is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
fields | [...] | if available | custom | Enabled checkout portal fields. Source: Organization checkout portal field configuration. |
required_fields | [...] | if available | custom | Required checkout portal fields. Source: Organization required checkout portal fields. |
optional_fields | [...] | if available | custom | Optional checkout portal fields. Source: Organization optional checkout portal fields. |
fields_count | 5 | if available | custom | Count of enabled fields. Source: Derived from portal settings fields list. |
required_fields_count | 3 | if available | custom | Count of required fields. Source: Derived from portal settings required fields list. |
optional_fields_count | 2 | if available | custom | Count of optional fields. Source: Derived from portal settings optional fields list. |
override_default_fields | true | if available | custom | True when checkout portal field defaults are overridden. Source: Organization override flag. |
license_plates_enabled | true | if available | custom | True when the checkout portal license plates step is enabled. Source: Organization + park settings. |
phone_enabled | true | if available | custom | True when phone contact method is enabled. Source: Organization checkout portal settings. |
email_enabled | true | if available | custom | True when email contact method is enabled. Source: Organization checkout portal settings. |
whatsapp_enabled | false | if available | custom | True when WhatsApp contact method is enabled. Source: Organization checkout portal settings. |
user_data
Hashed user-provided data for Google tags. Source: Hashed email/phone from booking contact, sent only with marketing consent.
Fields below apply only when user_data is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
sha256_email_address | ... | if available | custom | Hex-encoded SHA-256 after normalization. Source: Hashed email (marketing consent required). |
sha256_phone_number | ... | if available | custom | Hex-encoded SHA-256 after normalization. Source: Hashed phone number (marketing consent required). |
Sample data layer snippet
dataLayer.push({"event":"purchase","ecommerce":{"transaction_id":"ORDER-123","affiliation":"Administration Name","currency":"EUR","value":350.0,"customer_type":"new","payment_type":"ideal","tax":20.0,"shipping":0.0,"coupon":"SUMMER10","items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","item_brand":"Administration Name","item_category":"Accommodation","item_category2":"house","item_variant":"single_night","item_list_id":"checkout","item_list_name":"Checkout","item_country":"Netherlands","item_region":"Twente","item_city":"Enschede","administration_id":"321321","administration_name":"Administration Name","price":350.0,"quantity":1,"discount":25.0,"coupon":"SUMMER10","index":1,"start_date":"2026-02-20","end_date":"2026-02-22","google_business_vertical":"hotel_rental"}]},"search":{"start_date":"2026-02-20","end_date":"2026-02-22","nights":2,"rentable_type":"house","guest_group":{"seniors":0,"adults":2,"adolescents":0,"children":1,"babies":0,"pets":0,"total":3},"price_range_min":100,"price_range_max":500,"sorting_id":"price_asc","amenities":{"facility":["pool"]},"amenities_count":2,"has_results":true,"results_count":42,"special_period_id":123,"special_period_name":"Summer Holiday"},"booking":{"status":"booked","final":true,"guest_group":{"seniors":0,"adults":2,"adolescents":0,"children":1,"babies":0,"pets":0,"total":3},"currency":"EUR","total":350,"base_rent_total":350,"upgrade_total":0,"preference_total":0,"deposit_total":0,"deferred_deposit_total":0,"security_deposit_total":0,"tourist_taxes_total":0,"vat_total":50},"portal_settings":{"fields":["first_name","last_name","email","phone","note"],"required_fields":["first_name","last_name","email"],"optional_fields":["phone","note"],"fields_count":5,"required_fields_count":3,"optional_fields_count":2,"override_default_fields":true,"license_plates_enabled":true,"phone_enabled":true,"email_enabled":true,"whatsapp_enabled":false},"user_data":{"sha256_email_address":"...","sha256_phone_number":"..."}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
We do not auto-clear booking. If you map booking outside booking events, clear it manually with dataLayer.push({ booking: null }).
generate_lead
A lead is generated.
| Status | active |
|---|---|
| Type | event |
| Available on | Sales site |
| Portals | Checkout portal |
| Flow | Sales inquiry or checkout portal booking option |
Triggered when a lead is generated (for example, a booking option or a sales form with a priced property).
Checkout portal booking options emit this after the option is created.
Additional booking metadata can be included under booking (booking.status = option).
CMS sales forms: we only emit generate_lead when a property price and site currency are available, so value and currency are always present.
If marketing consent is granted, include user_data with hashed identifiers.
No address fields are sent.
Top-level parameters
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
currency | EUR | always | ga4 | Currency of the lead value, in 3-letter ISO 4217 format. Source: Checkout portal: booking currency. CMS sales forms: site default currency. |
value | 350.0 | always | ga4 | Monetary value of the lead. Source: Checkout portal: total order/booking value. CMS sales forms: selected property price. |
lead_source | Website | if available | custom | Source of the lead. Source: Checkout portal: booking traffic source name. CMS sales forms: form name. |
lead_id | lead-123 | if available | custom | Stable lead identifier for deduplication and marketing event_id. Source: Checkout portal booking number or CMS lead identifier. |
booking | {...} (see below) | if available | object | Booking object. Source: Booking object. booking.status/final/guest_group plus booking totals fields are populated for checkout portal purchase/lead events. |
user_data | {...} (see below) | if available | object | Hashed user-provided data for Google tags. Source: Hashed email/phone from booking contact, sent only with marketing consent. |
booking
Booking object. Source: Booking object. booking.status/final/guest_group plus booking totals fields are populated for checkout portal purchase/lead events.
Fields below apply only when booking is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
status | booked | if available | custom | Booking lifecycle status (concept/option/booked/cancelled). Source: Checkout portal status override or booking state from PMS. |
final | true | if available | custom | True when the booking is confirmed or imported. Source: Confirmed/imported flag from PMS. |
currency | EUR | if available | ga4 | Booking currency (ISO 4217). Source: Booking currency. |
total | 350 | if available | custom | Sum of all guest order items. Source: Total of guest debtor items. |
base_rent_total | 350 | if available | custom | Base rent (accommodation rent) order items. Source: Base rent total. |
upgrade_total | 0 | if available | custom | Upgrade order items (bundles/extras), excluding deposits. Source: Upgrade extras total. |
preference_total | 0 | if available | custom | Preference order items (amenities/preferences). Source: Preference items total. |
deposit_total | 0 | if available | custom | Reservation deposit order items (non-deferred). Source: Deposit total. |
deferred_deposit_total | 0 | if available | custom | Reservation deposit order items marked deferred. Source: Deferred deposit total. |
security_deposit_total | 0 | if available | custom | Security deposits (borg), from security deposit policies. Source: Security deposit total. |
tourist_taxes_total | 0 | if available | custom | Tourist tax order items. Source: Tourist taxes total. |
vat_total | 50 | if available | custom | VAT total for guest debtor items. Source: VAT total. |
guest_group | {...} (see below) | if available | object | Guest counts by group (see guest_group fields). Source: Aggregated guest group from reservations. |
booking.guest_group
Guest counts by group (see guest_group fields). Source: Aggregated guest group from reservations.
Fields below apply only when booking.guest_group is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
seniors | 0 | always | custom | Number of seniors. Source: Guest group seniors count. |
adults | 2 | always | custom | Number of adults. Source: Guest group adults count. |
adolescents | 0 | always | custom | Number of adolescents. Source: Guest group adolescents count. |
children | 1 | always | custom | Number of children. Source: Guest group children count. |
babies | 0 | always | custom | Number of babies. Source: Guest group babies count. |
pets | 0 | always | custom | Number of pets. Source: Guest group pets count. |
total | 3 | always | custom | Total guests (sum of guest group counts). Source: Guest group total. |
user_data
Hashed user-provided data for Google tags. Source: Hashed email/phone from booking contact, sent only with marketing consent.
Fields below apply only when user_data is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
sha256_email_address | ... | if available | custom | Hex-encoded SHA-256 after normalization. Source: Hashed email (marketing consent required). |
sha256_phone_number | ... | if available | custom | Hex-encoded SHA-256 after normalization. Source: Hashed phone number (marketing consent required). |
Sample data layer snippet
dataLayer.push({"event":"generate_lead","currency":"EUR","value":350.0,"lead_source":"Website","lead_id":"lead-123","booking":{"status":"option","final":false,"guest_group":{"seniors":0,"adults":2,"adolescents":0,"children":1,"babies":0,"pets":0,"total":3},"currency":"EUR","total":350,"base_rent_total":350,"upgrade_total":0,"preference_total":0,"deposit_total":0,"deferred_deposit_total":0,"security_deposit_total":0,"tourist_taxes_total":0,"vat_total":50},"user_data":{"sha256_email_address":"...","sha256_phone_number":"..."}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
We do not auto-clear booking. If you map booking outside booking events, clear it manually with dataLayer.push({ booking: null }).
close_convert_lead
A lead is converted and closed.
| Status | active |
|---|---|
| Type | event |
| Portals | Checkout portal |
| Flow | Checkout portal option confirmation |
Triggered when a lead is converted and closed (for example, an option confirmation).
Checkout portal option confirmations emit this after the option is finalized.
Additional booking metadata can be included under booking (booking.status reflects the booking state).
If marketing consent is granted, include user_data with hashed identifiers.
No address fields are sent.
Top-level parameters
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
currency | EUR | always | ga4 | Currency of the lead value, in 3-letter ISO 4217 format. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
value | 350.0 | always | ga4 | Monetary value of the lead conversion. Source: Total order/booking value or sum of item prices. |
lead_id | lead-123 | if available | custom | Stable lead identifier for deduplication and marketing event_id. Source: Checkout portal booking number or CMS lead identifier. |
booking | {...} (see below) | if available | object | Booking object. Source: Booking object. booking.status/final/guest_group plus booking totals fields are populated for checkout portal purchase/lead events. |
user_data | {...} (see below) | if available | object | Hashed user-provided data for Google tags. Source: Hashed email/phone from booking contact, sent only with marketing consent. |
booking
Booking object. Source: Booking object. booking.status/final/guest_group plus booking totals fields are populated for checkout portal purchase/lead events.
Fields below apply only when booking is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
status | booked | if available | custom | Booking lifecycle status (concept/option/booked/cancelled). Source: Checkout portal status override or booking state from PMS. |
final | true | if available | custom | True when the booking is confirmed or imported. Source: Confirmed/imported flag from PMS. |
currency | EUR | if available | ga4 | Booking currency (ISO 4217). Source: Booking currency. |
total | 350 | if available | custom | Sum of all guest order items. Source: Total of guest debtor items. |
base_rent_total | 350 | if available | custom | Base rent (accommodation rent) order items. Source: Base rent total. |
upgrade_total | 0 | if available | custom | Upgrade order items (bundles/extras), excluding deposits. Source: Upgrade extras total. |
preference_total | 0 | if available | custom | Preference order items (amenities/preferences). Source: Preference items total. |
deposit_total | 0 | if available | custom | Reservation deposit order items (non-deferred). Source: Deposit total. |
deferred_deposit_total | 0 | if available | custom | Reservation deposit order items marked deferred. Source: Deferred deposit total. |
security_deposit_total | 0 | if available | custom | Security deposits (borg), from security deposit policies. Source: Security deposit total. |
tourist_taxes_total | 0 | if available | custom | Tourist tax order items. Source: Tourist taxes total. |
vat_total | 50 | if available | custom | VAT total for guest debtor items. Source: VAT total. |
guest_group | {...} (see below) | if available | object | Guest counts by group (see guest_group fields). Source: Aggregated guest group from reservations. |
booking.guest_group
Guest counts by group (see guest_group fields). Source: Aggregated guest group from reservations.
Fields below apply only when booking.guest_group is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
seniors | 0 | always | custom | Number of seniors. Source: Guest group seniors count. |
adults | 2 | always | custom | Number of adults. Source: Guest group adults count. |
adolescents | 0 | always | custom | Number of adolescents. Source: Guest group adolescents count. |
children | 1 | always | custom | Number of children. Source: Guest group children count. |
babies | 0 | always | custom | Number of babies. Source: Guest group babies count. |
pets | 0 | always | custom | Number of pets. Source: Guest group pets count. |
total | 3 | always | custom | Total guests (sum of guest group counts). Source: Guest group total. |
user_data
Hashed user-provided data for Google tags. Source: Hashed email/phone from booking contact, sent only with marketing consent.
Fields below apply only when user_data is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
sha256_email_address | ... | if available | custom | Hex-encoded SHA-256 after normalization. Source: Hashed email (marketing consent required). |
sha256_phone_number | ... | if available | custom | Hex-encoded SHA-256 after normalization. Source: Hashed phone number (marketing consent required). |
Sample data layer snippet
dataLayer.push({"event":"close_convert_lead","currency":"EUR","value":350.0,"lead_id":"lead-123","booking":{"status":"booked","final":true,"guest_group":{"seniors":0,"adults":2,"adolescents":0,"children":1,"babies":0,"pets":0,"total":3},"currency":"EUR","total":350,"base_rent_total":350,"upgrade_total":0,"preference_total":0,"deposit_total":0,"deferred_deposit_total":0,"security_deposit_total":0,"tourist_taxes_total":0,"vat_total":50},"user_data":{"sha256_email_address":"...","sha256_phone_number":"..."}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
We do not auto-clear booking. If you map booking outside booking events, clear it manually with dataLayer.push({ booking: null }).
view_item_list
A user is presented with a list of items.
| Status | active |
|---|---|
| Type | event |
| Available on | Sales site, Booking site |
| Flow | Listings or availability results |
We measure rentable types (items) being presented to the user for certain dates and a certain price (availability) by sending a view_item_list event with the relevant rentable types in an items array. This event is triggered when a website visitor searches for availabilities by entering information like arrival date, departure date guest group, required amenities, etc.
The same event can be used for sales module listings (properties) by supplying the property items as the list items.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_list_id | availability_search | always | ga4 | The list ID for the results. Source: Website search list id (availability_search or property_search). |
item_list_name | Availability Search | always | ga4 | The list name for the results. Source: Website search list name (Availability search or Property search). |
currency | EUR | always | ga4 | Currency of the items associated with the event, in 3-letter ISO 4217 format. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | always | ga4 | The ID of the rentable type. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | always | ga4 | The name of the rentable type. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
item_brand | Administration Name | if available | ga4 | The localized name of the site. Source: Checkout portal: administration name. Website search: site/brand name shown on the website (can differ from the administration name). |
item_category | Accommodation | always | ga4 | Top-level item type.
Source: Checkout portal: |
item_category2 | house | if available | ga4 | Semantic segment for accommodations or sub-bucket for extras. Accommodation: house pitch room berth apartment other Extras: Amenity Upgrade PackageSource: Checkout portal: accommodation semantic segment or extras bucket. Website search: accommodation semantic segment. |
item_category3 | if available | ga4 | PMS extra type for extras only.
Source: Checkout portal extras only: cost extra_type. Not set for accommodations, packages, or website search. | |
item_variant | single_night | if available | ga4 | Stay duration category for the accommodation.
Source: Checkout portal accommodations and CMS availability items; derived from arrival/departure. |
item_country | Netherlands | if available | custom | The country where the administration is located. Source: Administration country from BEX (shared across checkout portal and website search). |
item_region | Twente | if available | custom | The region where the administration is located. Source: Administration region from BEX (shared across checkout portal and website search). |
item_city | Enschede | if available | custom | The city where the administration is located. Source: Administration city from BEX (shared across checkout portal and website search). |
administration_id | 321321 | if available | custom | The ID of the administration in BEX PMS. Source: Checkout portal: BEX administration id. Website search: the same BEX administration id (Booking Experts administration mapping). |
administration_name | Administration Name | if available | custom | The name of the administration in BEX PMS. Source: Checkout portal: BEX administration name. Website search: the same BEX administration name (Booking Experts administration mapping). |
coupon | SUMMER10 | if available | ga4 | Coupon applied to the item. Source: Coupon code applied to the reservation or order item (first code, if any). |
discount | 25.0 | if available | ga4 | Discount applied to the item. Source: Discount amount for the order item. |
price | 350.0 | if available | ga4 | Price for the item line (stay total for accommodation). Source: Website search: availability/property price for the stay. Checkout portal: order item unit price; accommodation uses stay total derived from booking total minus upgrades. |
quantity | 1 | if available | ga4 | Quantity of the item. Source: Order item quantity; otherwise 1. |
start_date | 2026-02-20 | if available | custom | The date of arrival for availability. Source: Stay arrival date or availability start date. |
end_date | 2026-02-22 | if available | custom | The date of departure for availability. Source: Stay departure date or availability end date. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
index | 1 | if available | ga4 | The position of the item in the list. Source: Position in the result list (website search only). |
Sample data layer snippet
dataLayer.push({"event":"view_item_list","ecommerce":{"item_list_id":"availability_search","item_list_name":"Availability Search","currency":"EUR","items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","item_brand":"Administration Name","item_category":"Accommodation","item_category2":"house","item_variant":"single_night","item_country":"Netherlands","item_region":"Twente","item_city":"Enschede","administration_id":"321321","administration_name":"Administration Name","coupon":"SUMMER10","discount":25.0,"price":350.0,"quantity":1,"start_date":"2026-02-20","end_date":"2026-02-22","google_business_vertical":"hotel_rental","index":1}]}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
select_item
A user selects an item from a list.
| Status | active |
|---|---|
| Type | event |
| Available on | Sales site, Booking site |
| Flow | Listing click to detail |
Triggered when a user selects an item from a list (for example, clicking an accommodation card on the listing page).
This is the list click; the detail page view is tracked with view_item.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_list_id | availability_search | always | ga4 | The list ID for the results. Source: Website search list id (availability_search or property_search). |
item_list_name | Availability Search | always | ga4 | The list name for the results. Source: Website search list name (Availability search or Property search). |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | always | ga4 | The ID of the rentable type. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | always | ga4 | The name of the rentable type. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
item_brand | Administration Name | if available | ga4 | The localized name of the site. Source: Checkout portal: administration name. Website search: site/brand name shown on the website (can differ from the administration name). |
item_category | Accommodation | always | ga4 | Top-level item type.
Source: Checkout portal: |
item_category2 | house | if available | ga4 | Semantic segment for accommodations or sub-bucket for extras. Accommodation: house pitch room berth apartment other Extras: Amenity Upgrade PackageSource: Checkout portal: accommodation semantic segment or extras bucket. Website search: accommodation semantic segment. |
item_category3 | if available | ga4 | PMS extra type for extras only.
Source: Checkout portal extras only: cost extra_type. Not set for accommodations, packages, or website search. | |
item_variant | single_night | if available | ga4 | Stay duration category for the accommodation.
Source: Checkout portal accommodations and CMS availability items; derived from arrival/departure. |
item_country | Netherlands | if available | custom | The country where the administration is located. Source: Administration country from BEX (shared across checkout portal and website search). |
item_region | Twente | if available | custom | The region where the administration is located. Source: Administration region from BEX (shared across checkout portal and website search). |
item_city | Enschede | if available | custom | The city where the administration is located. Source: Administration city from BEX (shared across checkout portal and website search). |
administration_id | 321321 | if available | custom | The ID of the administration in BEX PMS. Source: Checkout portal: BEX administration id. Website search: the same BEX administration id (Booking Experts administration mapping). |
administration_name | Administration Name | if available | custom | The name of the administration in BEX PMS. Source: Checkout portal: BEX administration name. Website search: the same BEX administration name (Booking Experts administration mapping). |
coupon | SUMMER10 | if available | ga4 | Coupon applied to the item. Source: Coupon code applied to the reservation or order item (first code, if any). |
discount | 25.0 | if available | ga4 | Discount applied to the item. Source: Discount amount for the order item. |
price | 350.0 | if available | ga4 | Price for the item line (stay total for accommodation). Source: Website search: availability/property price for the stay. Checkout portal: order item unit price; accommodation uses stay total derived from booking total minus upgrades. |
quantity | 1 | if available | ga4 | Quantity of the item. Source: Order item quantity; otherwise 1. |
start_date | 2026-02-20 | if available | custom | The date of arrival for availability. Source: Stay arrival date or availability start date. |
end_date | 2026-02-22 | if available | custom | The date of departure for availability. Source: Stay departure date or availability end date. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
index | 1 | if available | ga4 | The position of the item in the list. Source: Position in the result list (website search only). |
item_list_id | availability_search | always | ga4 | The list ID for the item. Source: Website search list id (availability_search/property_search). Cart/checkout events may supply list id like Cart or Checkout. |
item_list_name | Availability Search | always | ga4 | The list name for the item. Source: Website search list name (Availability search/Property search). Cart/checkout events may supply list name like Cart or Checkout. |
Sample data layer snippet
dataLayer.push({"event":"select_item","ecommerce":{"item_list_id":"availability_search","item_list_name":"Availability Search","items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","item_brand":"Administration Name","item_category":"Accommodation","item_category2":"house","item_variant":"single_night","item_country":"Netherlands","item_region":"Twente","item_city":"Enschede","administration_id":"321321","administration_name":"Administration Name","coupon":"SUMMER10","discount":25.0,"price":350.0,"quantity":1,"start_date":"2026-02-20","end_date":"2026-02-22","google_business_vertical":"hotel_rental","index":1,"item_list_id":"availability_search","item_list_name":"Availability Search"}]}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
view_item
A user views an item detail.
| Status | active |
|---|---|
| Type | event |
| Available on | Sales site, Booking site |
| Flow | Property/rentable detail page |
Triggered when a user views an item detail page.
Used for rentable detail pages and sales module property detail pages.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
currency | EUR | if available | ga4 | Currency of the items associated with the event, in 3-letter ISO 4217 format. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
value | 350.0 | if available | ga4 | Total value of the event. Source: Total order/booking value or sum of item prices. |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | always | ga4 | The ID of the rentable type. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | always | ga4 | The name of the rentable type. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
item_brand | Administration Name | if available | ga4 | The localized name of the site. Source: Checkout portal: administration name. Website search: site/brand name shown on the website (can differ from the administration name). |
item_category | Accommodation | always | ga4 | Top-level item type.
Source: Checkout portal: |
item_category2 | house | if available | ga4 | Semantic segment for accommodations or sub-bucket for extras. Accommodation: house pitch room berth apartment other Extras: Amenity Upgrade PackageSource: Checkout portal: accommodation semantic segment or extras bucket. Website search: accommodation semantic segment. |
item_category3 | if available | ga4 | PMS extra type for extras only.
Source: Checkout portal extras only: cost extra_type. Not set for accommodations, packages, or website search. | |
item_variant | single_night | if available | ga4 | Stay duration category for the accommodation.
Source: Checkout portal accommodations and CMS availability items; derived from arrival/departure. |
item_country | Netherlands | if available | custom | The country where the administration is located. Source: Administration country from BEX (shared across checkout portal and website search). |
item_region | Twente | if available | custom | The region where the administration is located. Source: Administration region from BEX (shared across checkout portal and website search). |
item_city | Enschede | if available | custom | The city where the administration is located. Source: Administration city from BEX (shared across checkout portal and website search). |
administration_id | 321321 | if available | custom | The ID of the administration in BEX PMS. Source: Checkout portal: BEX administration id. Website search: the same BEX administration id (Booking Experts administration mapping). |
administration_name | Administration Name | if available | custom | The name of the administration in BEX PMS. Source: Checkout portal: BEX administration name. Website search: the same BEX administration name (Booking Experts administration mapping). |
coupon | SUMMER10 | if available | ga4 | Coupon applied to the item. Source: Coupon code applied to the reservation or order item (first code, if any). |
discount | 25.0 | if available | ga4 | Discount applied to the item. Source: Discount amount for the order item. |
price | 350.0 | if available | ga4 | Price for the item line (stay total for accommodation). Source: Website search: availability/property price for the stay. Checkout portal: order item unit price; accommodation uses stay total derived from booking total minus upgrades. |
quantity | 1 | if available | ga4 | Quantity of the item. Source: Order item quantity; otherwise 1. |
index | 1 | if available | ga4 | Position of the item in the list. Source: Position in the result list (website search only). |
start_date | 2026-02-20 | if available | custom | The date of arrival for availability. Source: Stay arrival date or availability start date. |
end_date | 2026-02-22 | if available | custom | The date of departure for availability. Source: Stay departure date or availability end date. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
item_list_id | availability_search | if available | ga4 | The list ID for the item. Source: Website search list id (availability_search/property_search). Cart/checkout events may supply list id like Cart or Checkout. |
item_list_name | Availability Search | if available | ga4 | The list name for the item. Source: Website search list name (Availability search/Property search). Cart/checkout events may supply list name like Cart or Checkout. |
Sample data layer snippet
dataLayer.push({"event":"view_item","ecommerce":{"currency":"EUR","value":350.0,"items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","item_brand":"Administration Name","item_category":"Accommodation","item_category2":"house","item_variant":"single_night","item_country":"Netherlands","item_region":"Twente","item_city":"Enschede","administration_id":"321321","administration_name":"Administration Name","coupon":"SUMMER10","discount":25.0,"price":350.0,"quantity":1,"index":1,"start_date":"2026-02-20","end_date":"2026-02-22","google_business_vertical":"hotel_rental","item_list_id":"availability_search","item_list_name":"Availability Search"}]}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
view_promotion
A user views a promotion.
| Status | active |
|---|---|
| Type | event |
| Available on | Booking site |
| Portals | Checkout portal |
| Flow | Checkout portal promotion impression |
Triggered when a promotion is viewed or impressed.
Emitted in the checkout portal for discount card impressions.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
promotion_id | promo_123 | always | ga4 | Promotion ID. Source: Promotion id (discount, package, or discount card). |
promotion_name | Summer Sale | always | ga4 | Promotion name. Source: Promotion name (discount, package, or discount card). |
creative_name | Hero Banner | if available | ga4 | Creative name for the promotion. Source: Promotion creative name (banner/asset name) when provided. |
creative_slot | homepage_hero | if available | ga4 | Creative slot or placement. Source: Promotion placement/slot identifier when provided. |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | if available | ga4 | The ID of the promoted item. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | if available | ga4 | The name of the promoted item. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
Sample data layer snippet
dataLayer.push({"event":"view_promotion","ecommerce":{"promotion_id":"promo_123","promotion_name":"Summer Sale","creative_name":"Hero Banner","creative_slot":"homepage_hero","items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","google_business_vertical":"hotel_rental"}]}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
select_promotion
A user selects a promotion.
| Status | active |
|---|---|
| Type | event |
| Available on | Booking site |
| Portals | Checkout portal |
| Flow | Booking site promotions (availability or checkout portal) |
Triggered when a promotion is selected (clicked).
Emitted for availability-search promotions and checkout portal discounts.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
ecommerce | {...} (see below) | always | object | Ecommerce payload wrapper for GA4 events. |
ecommerce
Ecommerce payload wrapper for GA4 events.
Fields below apply only when ecommerce is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
promotion_id | promo_123 | always | ga4 | Promotion ID. Source: Promotion id (discount, package, or discount card). |
promotion_name | Summer Sale | always | ga4 | Promotion name. Source: Promotion name (discount, package, or discount card). |
creative_name | Hero Banner | if available | ga4 | Creative name for the promotion. Source: Promotion creative name (banner/asset name) when provided. |
creative_slot | homepage_hero | if available | ga4 | Creative slot or placement. Source: Promotion placement/slot identifier when provided. |
items[] | [...] (see below) | always | object[] | Items array for the ecommerce payload. |
ecommerce.items[]
Items array for the ecommerce payload.
Fields below apply only when ecommerce.items[] is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
item_id | 123123 | if available | ga4 | The ID of the promoted item. Source: Checkout portal: accommodation type id, extra cost id, bundle id, or amenity id. Website search: category id or property id. Promotions: discount/package id (different entities). |
item_name | 4-Person Luxury Villa | if available | ga4 | The name of the promoted item. Source: Checkout portal: accommodation type name, extra name, bundle name, or amenity name. Website search: localized category/property name. Promotions: promotion name. |
google_business_vertical | hotel_rental | if available | custom | Google Ads business vertical for dynamic remarketing (examples: "hotel_rental", "retail"). Source: Remarketing business vertical configured globally; not from booking data. |
Sample data layer snippet
dataLayer.push({"event":"select_promotion","ecommerce":{"promotion_id":"promo_123","promotion_name":"Summer Sale","creative_name":"Hero Banner","creative_slot":"homepage_hero","items":[{"item_id":"123123","item_name":"4-Person Luxury Villa","google_business_vertical":"hotel_rental"}]}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
Clear ecommerce before every ecommerce event to avoid reusing items: dataLayer.push({ ecommerce: null });
view_search_results
A user views search results.
| Status | active |
|---|---|
| Type | event |
| Available on | Sales site, Booking site |
| Flow | Site search results |
Triggered when a user views search results.
Emitted by the CMS site search page after a query is submitted.
Top-level parameters
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
search_term | summer holiday | always | ga4 | The search term entered by the user. Source: Search query entered by the guest. |
Sample data layer snippet
dataLayer.push({"event":"view_search_results","search_term":"summer holiday"});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
search
A user performs a search.
| Status | active |
|---|---|
| Type | event |
| Available on | Sales site, Booking site |
| Flow | Site search query |
Triggered when a user performs a search.
Emitted by the CMS site search page when a query is present.
Current search event payload
window.dataLayer = window.dataLayer || [];window.dataLayer.push({ "event": "search", "search_term": "summer holiday"});Legacy search payload (deprecated)
window.dataLayer = window.dataLayer || [];window.dataLayer.push({ "event": "search", "search_term": "summer holiday", "result_count": 42});Top-level parameters
| Parameter | Sample | Presence | Type | Status | Description |
|---|---|---|---|---|---|
search_term | summer holiday | always | ga4 | The term that was searched for. Source: Search query entered by the guest. | |
result_count | 42 | if available | custom | deprecated (removal 2 Mar 2026) | Legacy search result count. Source: CMS search result size. |
Custom events
search_results_loaded
Availability search results are rendered.
| Status | active |
|---|---|
| Type | event |
| Available on | Booking site |
| Flow | Availability search results loaded |
Custom event for the availability Search + Booking flow.
Emitted by CMS availability search results on booking sites.
Emitted when results are rendered or an availability API response is accepted for the current search.
All events include a full search snapshot including the results summary (has_results/results_count). Unknown values are null.
Dates are YYYY-MM-DD; currency is ISO 4217; numeric values are numbers.
This is the primary availability search tracking event; it captures both the search inputs and whether results were found.
We emit it on initial availability search loads and on subsequent amenity updates (search intent tracking).
Use it together with cart/checkout events in GA4 to understand which searches led to bookings (session/user attribution).
Only fire when results match the current search (use a request id if multiple calls are in-flight).
Payload: event + search.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
search | {...} (see below) | always | object | Full search snapshot including results summary. Source: Website search snapshot (dates, guests, amenities, sorting, price range, results). |
search
Full search snapshot including results summary. Source: Website search snapshot (dates, guests, amenities, sorting, price range, results).
Fields below apply only when search is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
start_date | 2026-02-20 | if available | custom | Arrival date for the availability search (YYYY-MM-DD, null when missing). Source: Website availability search arrival date. |
end_date | 2026-02-22 | if available | custom | Departure date for the availability search (YYYY-MM-DD, null when missing). Source: Website availability search departure date. |
nights | 2 | if available | custom | Length of stay in nights (null when dates are missing). Source: Derived from search dates or nights selector. |
rentable_type | house | if available | custom | Accommodation semantic segment (house, pitch, room, berth, apartment, other). Source: Search rentable type segment. |
price_range_min | 100 | if available | custom | Minimum total price. Source: Search price range minimum. |
price_range_max | 500 | if available | custom | Maximum total price. Source: Search price range maximum. |
sorting_id | price_asc | if available | custom | Sorting option id. Source: Search sorting choice. |
amenities | {...} | if available | custom | Amenity facet id mapped to arrays of value ids. Source: Search amenity selections. |
amenities_count | 2 | if available | custom | Count of active amenity selections (includes price range). Source: Number of active amenity selections plus price range. |
has_results | true | if available | custom | True when results_count > 0. Source: Derived from availability search results. |
results_count | 42 | if available | custom | Total result count (null when unknown). Source: Availability search total results. |
special_period_id | 123 | if available | custom | Special period id when the search dates match a defined special period (selected or inferred). Source: Special period id. |
special_period_name | Summer Holiday | if available | custom | Localized special period name when the search dates match a defined special period (selected or inferred). Source: Special period name. |
guest_group | {...} (see below) | if available | object | Guest counts by group (see guest_group fields). Source: Guest group from search form. |
search.guest_group
Guest counts by group (see guest_group fields). Source: Guest group from search form.
Fields below apply only when search.guest_group is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
seniors | 0 | always | custom | Number of seniors. Source: Guest group seniors count. |
adults | 2 | always | custom | Number of adults. Source: Guest group adults count. |
adolescents | 0 | always | custom | Number of adolescents. Source: Guest group adolescents count. |
children | 1 | always | custom | Number of children. Source: Guest group children count. |
babies | 0 | always | custom | Number of babies. Source: Guest group babies count. |
pets | 0 | always | custom | Number of pets. Source: Guest group pets count. |
total | 3 | always | custom | Total guests (sum of guest group counts). Source: Guest group total. |
Sample data layer snippet
dataLayer.push({"event":"search_results_loaded","search":{"start_date":"2026-02-20","end_date":"2026-02-22","nights":2,"rentable_type":"house","guest_group":{"seniors":0,"adults":2,"adolescents":0,"children":1,"babies":0,"pets":0,"total":3},"price_range_min":100,"price_range_max":500,"sorting_id":"price_asc","amenities":{"facility":["pool"]},"amenities_count":2,"has_results":true,"results_count":42,"special_period_id":123,"special_period_name":"Summer Holiday"}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
checkout_progress
Checkout portal progress update.
| Status | active |
|---|---|
| Type | event |
| Portals | Checkout portal |
| Flow | Checkout portal progress updates (step load + guest group/license plates) |
Custom checkout portal event emitted on each checkout step and when guests update checkout details.
Emitted when the guest group or license plate details change, and when a step is loaded.
Payload: event + step + step_number + guest_group + license plate summary + portal_settings.
Top-level parameters
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
step | stay | always | custom | Normalized checkout step (stay/upgrades/details/confirm). Source: Checkout portal step context. |
step_number | 1 | always | custom | Checkout step number (1=stay, 2=upgrades, 3=details, 4=confirm). Source: Checkout portal step context. |
license_plates_count | 1 | if available | custom | Number of non-empty license plates entered. Source: Checkout portal reservation license plates. |
available_parking_spots | 2 | if available | custom | Number of parking spots available for the reservation. Source: Rentable type parking spots. |
guest_group | {...} (see below) | if available | object | Guest counts by group (see guest_group fields). Source: Checkout portal reservation guest group. |
portal_settings | {...} (see below) | if available | object | Checkout portal settings snapshot (fields and contact toggles). Source: Organization checkout portal settings. |
guest_group
Guest counts by group (see guest_group fields). Source: Checkout portal reservation guest group.
Fields below apply only when guest_group is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
seniors | 0 | always | custom | Number of seniors. Source: Guest group seniors count. |
adults | 2 | always | custom | Number of adults. Source: Guest group adults count. |
adolescents | 0 | always | custom | Number of adolescents. Source: Guest group adolescents count. |
children | 1 | always | custom | Number of children. Source: Guest group children count. |
babies | 0 | always | custom | Number of babies. Source: Guest group babies count. |
pets | 0 | always | custom | Number of pets. Source: Guest group pets count. |
total | 3 | always | custom | Total guests (sum of guest group counts). Source: Guest group total. |
portal_settings
Checkout portal settings snapshot (fields and contact toggles). Source: Organization checkout portal settings.
Fields below apply only when portal_settings is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
fields | [...] | if available | custom | Enabled checkout portal fields. Source: Organization checkout portal field configuration. |
required_fields | [...] | if available | custom | Required checkout portal fields. Source: Organization required checkout portal fields. |
optional_fields | [...] | if available | custom | Optional checkout portal fields. Source: Organization optional checkout portal fields. |
fields_count | 5 | if available | custom | Count of enabled fields. Source: Derived from portal settings fields list. |
required_fields_count | 3 | if available | custom | Count of required fields. Source: Derived from portal settings required fields list. |
optional_fields_count | 2 | if available | custom | Count of optional fields. Source: Derived from portal settings optional fields list. |
override_default_fields | true | if available | custom | True when checkout portal field defaults are overridden. Source: Organization override flag. |
license_plates_enabled | true | if available | custom | True when the checkout portal license plates step is enabled. Source: Organization + park settings. |
phone_enabled | true | if available | custom | True when phone contact method is enabled. Source: Organization checkout portal settings. |
email_enabled | true | if available | custom | True when email contact method is enabled. Source: Organization checkout portal settings. |
whatsapp_enabled | false | if available | custom | True when WhatsApp contact method is enabled. Source: Organization checkout portal settings. |
Sample data layer snippet
dataLayer.push({"event":"checkout_progress","step":"stay","step_number":1,"license_plates_count":1,"available_parking_spots":2,"guest_group":{"seniors":0,"adults":2,"adolescents":0,"children":1,"babies":0,"pets":0,"total":3},"portal_settings":{"fields":["first_name","last_name","email","phone","note"],"required_fields":["first_name","last_name","email"],"optional_fields":["phone","note"],"fields_count":5,"required_fields_count":3,"optional_fields_count":2,"override_default_fields":true,"license_plates_enabled":true,"phone_enabled":true,"email_enabled":true,"whatsapp_enabled":false}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
form_start
A user starts interacting with a form.
| Status | active |
|---|---|
| Type | event |
| Available on | Sales site, Booking site |
| Flow | Site form start (sales or booking) |
Triggered the first time a user interacts with a form in a session.
Emitted by CMS forms on the website (sales or booking sites).
GA4 docs: https://support.google.com/analytics/answer/9216061
Note: To use form parameters in GA4 reports, configure custom dimensions.
Top-level parameters
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
form_id | 42 | always | custom | CMS form id. Source: Website form model id. |
form_name | Contact Form | always | custom | HTML name attribute of the <form> element. Source: Website form name. |
form_destination | /forms/responses | always | custom | URL the form submits to. Source: Website form submit URL. |
Sample data layer snippet
dataLayer.push({"event":"form_start","form_id":"42","form_name":"Contact Form","form_destination":"/forms/responses"});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
form_submit
A user submits a form.
| Status | active |
|---|---|
| Type | event |
| Available on | Sales site, Booking site |
| Flow | Site form submit (sales or booking) |
Triggered when a user submits a form.
Emitted by CMS forms on the website (sales or booking sites).
GA4 docs: https://support.google.com/analytics/answer/9216061
Note: To use form parameters in GA4 reports, configure custom dimensions.
If marketing consent is granted and the form includes email or phone fields, include user_data with hashed identifiers.
GA4 Tag Manager user-provided data guidance: https://support.google.com/analytics/answer/14171268
CMS sales forms with a selected property price also emit generate_lead (with value and currency).
No address fields are sent.
Top-level parameters
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
form_id | 42 | if available | custom | CMS form id. Source: Website form model id. |
form_name | Contact Form | always | custom | HTML name attribute of the <form> element. Source: Website form name. |
form_destination | /forms/responses | always | custom | URL the form submits to. Source: Website form submit URL. |
form_submit_text | Send message | if available | custom | Text of the submit button, if present. Source: Website submit button label. |
form_response_id | 12345 | always | custom | Internal form response id (custom parameter). Source: Website saved form response id. |
user_data | {...} (see below) | if available | object | Hashed user-provided data for Google tags. Source: Hashed email/phone from form response, sent only with marketing consent. |
user_data
Hashed user-provided data for Google tags. Source: Hashed email/phone from form response, sent only with marketing consent.
Fields below apply only when user_data is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
sha256_email_address | ... | if available | custom | Hex-encoded SHA-256 after normalization. Source: Hashed email (marketing consent required). |
sha256_phone_number | ... | if available | custom | Hex-encoded SHA-256 after normalization. Source: Hashed phone number (marketing consent required). |
Sample data layer snippet
dataLayer.push({"event":"form_submit","form_id":"42","form_name":"Contact Form","form_destination":"/forms/responses","form_submit_text":"Send message","form_response_id":"12345","user_data":{"sha256_email_address":"...","sha256_phone_number":"..."}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
failed_payment
A payment attempt fails during checkout.
| Status | active |
|---|---|
| Type | event |
| Portals | Checkout portal |
| Flow | Checkout portal after payment failure |
Triggered when a payment attempt fails.
Emitted on the checkout portal after returning from the payment portal with a failure status.
If marketing consent is granted, include user_data with hashed identifiers.
No address fields are sent.
Top-level parameters
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
transaction_id | ORDER-123 | always | custom | Unique transaction ID. Source: Booking reference/number. |
currency | EUR | always | custom | Currency of the payment. Source: Currency used for totals/items (booking/order/reservation currency; website search uses the active site currency). |
value | 350.0 | always | custom | Amount associated with the failed payment. Source: Total order/booking value or sum of item prices. |
reason_failed | failure | always | custom | Failure reason reported by the payment provider. Source: Payment provider failure reason. |
user_data | {...} (see below) | if available | object | Hashed user-provided data for Google tags. Source: Hashed email/phone from booking contact, sent only with marketing consent. |
user_data
Hashed user-provided data for Google tags. Source: Hashed email/phone from booking contact, sent only with marketing consent.
Fields below apply only when user_data is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
sha256_email_address | ... | if available | custom | Hex-encoded SHA-256 after normalization. Source: Hashed email (marketing consent required). |
sha256_phone_number | ... | if available | custom | Hex-encoded SHA-256 after normalization. Source: Hashed phone number (marketing consent required). |
Sample data layer snippet
dataLayer.push({"event":"failed_payment","transaction_id":"ORDER-123","currency":"EUR","value":350.0,"reason_failed":"failure","user_data":{"sha256_email_address":"...","sha256_phone_number":"..."}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];
user_identity_update
Associates a pseudonymous user id with the current session.
| Status | active |
|---|---|
| Type | event |
| Portals | Checkout portal |
| Flow | Checkout portal identity capture |
Triggered when a pseudonymous user id becomes available for analytics.
Emitted in the checkout portal when a booking contact is known and consent allows analytics.
No PII should be included in this event.
Top-level objects
| Parameter | Sample | Presence | Type | Description |
|---|---|---|---|---|
user | {...} (see below) | always | object | Pseudonymous user identifier and optional returning customer flag. Source: Pseudonymous user id and returning_customer flag derived from booking contact. |
user
Pseudonymous user identifier and optional returning customer flag. Source: Pseudonymous user id and returning_customer flag derived from booking contact.
Fields below apply only when user is present in the payload. Presence values are scoped to this group.
| Field | Sample | Presence | Type | Description |
|---|---|---|---|---|
user_id | u_hmac_... | always | custom | HMAC-SHA256 of the contact id using the configured secret key. Source: Pseudonymous user id derived from booking contact. |
returning_customer | true | if available | custom | True when the contact has a booking within the last 540 days. Source: Returning customer flag from booking history. |
Sample data layer snippet
dataLayer.push({"event":"user_identity_update","user":{"user_id":"u_hmac_...","returning_customer":true}});Initialize the data layer once on every page: window.dataLayer = window.dataLayer || [];