Skip to main content
The Restoo widget emits custom browser events for the main steps of the booking funnel. Listen for them with standard event listeners to measure the funnel in your own analytics, or in any other system that consumes browser events.
If you use GA4, Google Ads, Meta Pixel, TikTok Pixel, OpenAI Pixel, or Google Tag Manager, see Restoo Connect. It forwards these events without requiring a custom listener for each one.

Listen for events

Each event is a standard browser CustomEvent. Its name starts with restoo:, and its payload is available in event.detail. For example, to receive a confirmed booking:
Register your listeners on the page that embeds the widget.
These events always arrive, with or without consent. The widget emits them on your page so you can measure with your own tools; what consent controls is what Restoo Connect delivers to each platform. If you forward them to a third party, the consent is yours to apply. The exception is the customer’s identity: the hashed email and phone are only emitted with advertising permission granted (customer identity).

Event reference

Widget and navigation

Booking funnel

Some events depend on the booking configuration. For example, conditions and cancellation-policy events only appear when those steps are presented.
These two events are mutually exclusive and fire once each time a booking is saved, at the moment the backend confirms it — not when the confirmation page renders, so reloading that page does not emit them again. Editing a booking emits booking_updated, never booking_created. Both carry is_update_flow set accordingly.

Item list events

Customer

customer_identified carries personal data, so it is emitted only when the visitor has granted ad_user_data — see Consent. It is not lost if permission arrives later: the widget holds the identification and emits it as soon as the visitor grants it, which is what happens when someone is recognized from remembered details before answering the cookie notice.

Actions

Fields common to every event

Every event has the same top-level structure in event.detail:
Fields
string
required
Unique identifier for this emission, not for the kind of event. Modern browsers generate an RFC 4122 UUID, but treat it as an opaque string because the fallback used by older browsers has a different format.Every dispatch gets a new one: three taps on the contact button produce three action_taken events with three different id values.
string
required
Identifier shared by events from the same widget session. It follows the same format rules as id.
string
required
Event name without the restoo: prefix.
string | null
required
Payload model. It determines the shape of data; both type and data are null for events without a payload.
string
required
Event time as an ISO 8601 UTC timestamp. Example: "2026-07-22T10:15:00.000Z".
object
required
Widget context.
object
required
Marketing attribution associated with the visit.
boolean
required
true when the event belongs to an update flow; otherwise false.
object | null
required
Event-specific payload. See Event data for more information.

Event data

The examples below show the value of event.detail.data, not the whole event. Definitions: WidgetEvent, PageViewed, BookingFunnel, NoAvailability, BookingViewItemList, BookingSelectItem, BookingViewItemDetail, ActionTaken, and CustomerIdentified.
Looking for a field that isn’t here — a catalogue name, or more customer details? Some are deliberately omitted; see What Restoo deliberately omits.

WidgetEvent

Used by widget_mounted.
Fields
string
required
URL of the internal document Restoo loads inside the iframe.It is not your page’s URL, and it is not an address you can open: on its own it stays blank, because the widget draws nothing until Restoo.js sends it the settings on mount.The path is always the same and only its parameters change, so this field identifies the starting view, not where the visitor was. For that, read window.location.href on your own page.

PageViewed

Used by page_viewed.
Fields
string
required
Internal view path — mirrors the widget’s own routes, one per screen (there are 50+). A few representative examples: "reservation" (calendar), "reservation/details" (guest details form), "reservation/confirmed", "experiences", "store", "store/checkout", "booking/cancel", and "my-account".

BookingFunnel

Used by the booking funnel events whose type is booking. The payload is a snapshot of the booking at the moment the event is emitted, so fields that have not been selected or assigned yet can be null.
Fields
object
required
Booking state when the event was emitted.

Resource IDs

Experience, add-on, area, and time-slot IDs use the following format:
Each segment is lowercase. Non-alphanumeric characters are normalized to underscores.
A time-slot ID identifies the account and local time of day. Use the item’s date and floor_plan_area_id fields when you need the complete booking context.

NoAvailability

Used by booking_no_availability_viewed.
Fields
object
required
Result shown when no availability is found.
object
required
Booking snapshot documented in BookingFunnel.

BookingViewItemList

Used by booking_item_list_viewed. It follows the e-commerce view_item_list pattern and is emitted once when the list view is shown. Fields
string
required
Type of list shown.
object[]
required
Items shown in the list. Their fields depend on list_type.

BookingSelectItem

Used by booking_item_selected. It follows the e-commerce select_item pattern. The item shapes match BookingViewItemList; selected experiences also include tickets, and selected add-ons include quantity. Fields
string
required
Type of item selected.
object[]
required
Selected items. Their fields depend on list_type.

BookingViewItemDetail

Used by booking_item_detail_viewed. It follows the e-commerce view_item pattern.
Fields
string
required
Kind of item opened.
string
required
List from which the detail was opened: booking_experiences, booking_time_slots, or booking_add_ons. See the definitions in BookingViewItemList.
object
required
Item whose detail was opened.

ActionTaken

Used by action_taken.
Fields
string
required
Group to which the action belongs.
string
required
Specific choice made within the category.
A contact through the menu emits two events, not one. Opening the contact menu sends option: "open", and picking the channel sends the channel — "whatsapp", "phone", or "email" — both with category: "contact". Where the channels are shown directly, with no menu, only the second one arrives.So to count contacts, filter on option and not just on category. Conversions are unaffected: "open" and "click" never fire them (Event Mapping).

CustomerIdentified

Used by customer_identified.
Fields
string
required
How the customer was identified.
object
required
Identified customer. Personal text values are normalized by trimming leading and trailing whitespace and converting them to lowercase before hashing.

Send selected events to your data layer

You can forward only the events that matter to your site:
For automatic mappings to supported analytics platforms, use Restoo Connect.

Next steps

Event Mapping

What each of these events becomes in GA4, Google Ads, Meta, TikTok, ChatGPT Ads, and GTM.

Consent

What needs permission and what does not, and why customer identity is handled separately.