How Kismet sends events
View .mdHow Kismet sends events
Section titled “How Kismet sends events”Every guest action Kismet records follows one path. Your page never calls the network for these events: components fire in-page events, and the browser tracker turns them into stored events.
The path
Section titled “The path”Kismet component or your page │ a guest action: quick view, Book, checkout step ▼In-page event · window CustomEvent kismet:visitor:<object>:<verb> │ picked up by k.js — never a direct network call from the component ▼Pinned k.js · consent check, visitor session, payload fields │ one beacon per event ▼POST /api/track · client-plane ingest │ ▼Stored event · one row per event, keyed by its stored value- The component fires an in-page event. A Kismet component dispatches a
kismet:visitor:<object>:<verb>CustomEvent onwindow. Nothing here touches the network. - The pinned k.js tag listens. k.js checks consent, resolves the visitor session on your domain, and assembles the payload. Serve a pinned release so the browser code you reviewed is the code that runs — see the pinned browser tracker.
- One beacon per event. k.js posts the event to the tracking relay,
/api/trackby default. The only server-side job is the adapter’s session seed, so k.js adopts the resolved id — see the tracking contract. - The stored event. Kismet stores one row per event, keyed by the stored value in the table below. Funnels, reports and the go-live check all read that stored value.
Every event carries the visitor session and page context — beaconId, clientSessionId, collectionSlug, servingDomain, pageUrl, productType, productId, productSlug, emitter, surface, schemaVersion — and, wherever a stay is known, stayCheckIn, stayCheckOut, guestCount, stayNights, stayTotalCents and currency.
The funnel events
Section titled “The funnel events”The stored values below are never renamed, and they cover every bookable product type. Values marked (legacy) predate the current naming and stay as they are; new names say product.
| Event | Visitor event | Stored value | GA4 / Meta | Fires when | Sent automatically | Status |
|---|---|---|---|---|---|---|
| Search Submitted | kismet:visitor:search:submit |
search_submit |
GA4 search |
A guest commits a place or date change; debounced, never per keystroke | Yes | Planned |
| Filter Applied | kismet:visitor:search:filter |
filter_apply |
— | A guest applies or changes a results filter; filter details, never money | Yes | Planned |
| Content Viewed (list) | kismet:visitor:search:view |
view (legacy) |
GA4 view_item_list / Meta Search |
A results list shows with prices loaded; once per mount and once per new query; carries result counts | Yes | Live (Fixtures publish it per query, kismet-elements #1078; k.js maps it) |
| Product Selected | kismet:visitor:product:select |
product_select |
GA4 select_item |
A card tap opens the quick view; every tap; carries list size and the price shown | Yes | Planned |
| Product Viewed (quick view) | kismet:visitor:property-detail:view |
property_view (legacy) |
GA4 view_item / Meta ViewContent |
The quick-view sheet opens; once per open per product; carries the stay and price shown | Yes | Live (Fixtures and WordPress, kismet-elements #1076) |
| Quick View Closed | kismet:visitor:product:close |
quickview_close |
— | The sheet closes; carries time open and how it was closed | Yes | Planned |
| Content Clicked (view full listing) | kismet:visitor:property:cta |
click (legacy) |
— | “View full listing” tapped in the quick-view sheet | Yes | Live (Fixtures and WordPress, kismet-elements #1076) |
| Product Viewed (full page) | kismet:visitor:property-detail:view |
property_view (legacy) |
GA4 view_item / Meta ViewContent |
The product page shows; once per page; carries the stay and price | Yes | Live (server plane, and the browser page event in kismet-elements #1078) |
| Availability Missed | kismet:visitor:product:availability-miss |
availability_miss (legacy) |
— | The booking rail or quick view checks dates and they are not available | Yes | Planned |
| Product Saved | kismet:visitor:property:save |
add_to_wishlist (legacy) |
GA4 add_to_wishlist / Meta AddToWishlist |
The heart is tapped | Yes | Live (Fixtures and WordPress, kismet-elements #1076) |
| Checkout Intent Clicked | kismet:visitor:property-detail:book |
cta_click (legacy) |
GA4 begin_checkout / Meta InitiateCheckout |
Book or Reserve tapped in the quick view, booking rail or mobile drawer; every tap; carries the stay and price shown | Yes | Live (Fixtures and WordPress, kismet-elements #1076) |
| Quote Requested | kismet:visitor:product:quote |
quote_request |
— | Server-side, on every price check; outcome and quoted total recorded; a quoted total is intent, never revenue | Yes, server-side | Planned |
| Checkout Opened | kismet:visitor:checkout:open |
checkout_open |
— | The checkout panel reports form-ready; once per checkout | Yes | Planned; the in-page event fires today |
| Promo Applied / Rejected | kismet:visitor:checkout:promo |
promo_apply or promo_reject |
GA4 coupon parameter (no separate standard event) |
Server-side, when a code is tried at quote; valid codes stored as typed, rejected text stored hashed only, never raw | Yes, server-side | Planned |
| Guest Info Added | kismet:visitor:checkout:guest-info |
guest_info_add |
GA4 add_shipping_info |
A guest completes the details step; once per checkout | Yes | Planned; the in-page event fires today |
| Payment Info Added | kismet:visitor:checkout:payment-info |
payment_info_add |
GA4 add_payment_info / Meta AddPaymentInfo |
A guest completes the payment step; once per checkout | Yes | Planned; the in-page event fires today |
| Payment Submitted | kismet:visitor:checkout:pay |
payment_submit |
— | Pay tapped; every attempt | Yes | Planned; the in-page event fires today |
| Payment Failed | kismet:visitor:checkout:pay-failed |
payment_fail |
— | Server-side, when a reservation create fails — card declined, authentication, expired quote or unknown; reason recorded | Yes, server-side | Planned |
| Booking Completed | kismet:visitor:checkout:purchase (GA4 path only) |
booking_completed (legacy) |
GA4 purchase / Meta Purchase, server-side only |
The reservation is confirmed; the server is the source of truth, one purchase per booking | Yes, server-side | Live (server plane) |
“Sent automatically” means the page sends the event with no site code when it uses Kismet components or Kismet-served pages as designed. Server-side rows are recorded by Kismet’s booking and pricing APIs, not the browser; a custom checkout instead calls the booking bridge from the code that knows the reservation succeeded.
What ships today
Section titled “What ships today”- Every Live browser event is stored today on any site that runs the Kismet browser bundle — Fixtures pages and WordPress + Elements pages. Fixtures mount the analytics adapter themselves, so a site that uses the Fixtures as designed sends the quick view, Book and save events with zero site code (kismet-elements #1076).
- Content Viewed (list) is stored from the Fixtures results view once per query after prices settle, with result counts and booking window (kismet-elements #1078), and from k.js’s own search mapping elsewhere. Product Viewed (full page) is stored twice over: as the server-plane page event of the tracking contract and as the browser page event (
exposureDepth: 'full', stay dates but no total — a from-price is not a quote; #1078). - Events emitted before k.js starts are held on the page in
window.__kismetVisitorBuffer(FIFO, capped at 50, one unique event id each) and k.js replays them once it starts, deduplicating by event id (kismet-elements #1080, kismet.travel #3921). - Checkout Opened, Guest Info Added, Payment Info Added and Payment Submitted already fire in the page today: their components dispatch the visitor events, but k.js does not deliver them to Kismet yet.
Events by site type
Section titled “Events by site type”What each kind of site does to send the Live browser events:
| Site type | What you do | What you get |
|---|---|---|
| Kismet Fixtures (the SDK starter pages) | Nothing | Automatic. Fixtures mount the analytics adapter themselves (kismet-elements #1076) and publish the results and detail views (#1078). |
| WordPress + Kismet Elements | Install the plugin | Automatic. The pageshell and dispatcher bundles mount the same adapter. |
| SDK-only custom UI (your own components on the SDK) | Wire the interim path below, until the SDK bridge (KIS-21846) ships | The events your components dispatch are stored; nothing mounts one for you |
The interim path for SDK-only custom UI
Section titled “The interim path for SDK-only custom UI”The in-page event names are the contract the pinned k.js tag already listens for. Wire them before the staging review, not after launch — events a site never dispatches are never recovered:
-
Pin k.js on every page (pinned browser tracker). It owns consent, the visitor session and delivery; your components never call the network.
-
Dispatch the in-page event from the code that owns the action. Each action maps to one window
CustomEvent, dispatched once per occurrence:Guest action Event to dispatch Stored value Carries Quick view opens kismet:visitor:property-detail:viewwithexposureDepth: 'quickview'property_viewstay dates, guests, the price shown Full property page shows kismet:visitor:property-detail:viewwithexposureDepth: 'full'property_viewstay dates; no total (a from-price is not a quote) Book or Reserve tapped kismet:visitor:property-detail:bookcta_clickstay dates, guests, the price shown “View full listing” tapped kismet:visitor:property:ctaclickthe product Home saved kismet:visitor:property:saveadd_to_wishlistthe product Results list shows with prices settled kismet:visitor:search:viewviewresult count, once per query The detail object carries the funnel context k.js reads:
vrSlug(orslug),exposureDepthwhere marked,checkIn,checkOut,guests,nightCount,stayTotalCents,currency, and a uniqueeventId(a UUID) so k.js can deduplicate. k.js adds the session (kidSid) and the collection and serving domain; an action with no session — a consent-denied visitor — is skipped, never queued. -
Buffer events emitted before k.js starts. If your page can emit before the tag loads, append the same
{ name, detail, eventId }record towindow.__kismetVisitorBuffer(FIFO, capped at 50,namewithout thekismet:visitor:prefix). k.js drains the buffer when it starts, deduplicates by event id, and clears it (kismet-elements #1080, kismet.travel #3921).
This path is interim: the SDK bridge (KIS-21846) replaces it with one supported funnel view and one GA4 path. Two surfaces are also planned and ship with it:
- SDK recipe hooks. Recipes that include a Kismet search bar or booking confirmation publish their events automatically, and the recipe runner checks the real events — a recipe that stops emitting fails visibly.
emitKismetVisitorEvent. A public helper for your own components, named for the in-page event it dispatches.
Consent and the pre-consent buffer
Section titled “Consent and the pre-consent buffer”k.js owns consent for browser events — there is no second gate in your page. Wire your consent manager once for the server adapters and the browser tracker as described in the consent guide; without a permitted session, browser events are not sent.
One piece shipped with the funnel work. While the page runs before k.js starts, the browser bundle holds each emitted visitor event on the page in window.__kismetVisitorBuffer — a FIFO capped at 50 entries, one unique event id each (kismet-elements #1080). When k.js starts it drains the buffer, skips every event it cannot stitch to a session, deduplicates the rest by event id, and clears the buffer (kismet.travel #3921). The buffer never leaves the page: an event reaches Kismet only when k.js can deliver it under the consent rules above, so for a visitor in the EU/EEA/UK/CH without consent — or anyone sending a Global Privacy Control or opt-out signal — nothing is sent and nothing is stored. The buffer lives for one page load; leaving the page discards it. This is not legal advice; confirm regional handling with counsel before relying on buffer timing for EU traffic.
Check a site
Section titled “Check a site”After you integrate — or after any release that touches the funnel — confirm each event arrives:
- Walk the funnel on staging: search, open a quick view, choose View full listing, save a property, tap Book, and complete a checkout.
- Check the stored events with one query grouped by stored value, over the window your walk covered. Every Live event you triggered should show a count above zero. Planned rows stay absent until they ship.
- The Developer MCP’s
inspect_telemetrytool reads aggregate stored-event evidence for your collection — a server API key with thetelemetry.readgrant, no guest records or visitor identifiers returned. See the Developer MCP.
A count above zero per event is the go-live bar: per event, not per session, because checkout events only fire when a guest reaches checkout.