Tracker — Tracked events
The tracker fires events automatically with no configuration. Each event is wrapped in a standard envelope on the wire and lands in your tenant’s events collection ready for GET /v1/events.
Event envelope
Section titled “Event envelope”Every event arrives at the backend with this shape (the tracker batches up to 10 events per request):
{ "event": "page_view", "data": { /* event-specific payload */ }, "timestamp": "2026-04-29T11:23:45.000Z", "url": "https://example.com/pricing", "domain": "example.com", "visitorId": "vis_abc", "sessionId": "sess_xyz", "external_contact_id": null, "ga_user_id": "GA1.1.1234.5678", "userAgent": "Mozilla/5.0 …", "referrer": "https://google.com/", "screenResolution": "1920x1080"}Server-added fields
Section titled “Server-added fields”The backend derives extra fields from the userAgent and referrer every event already carries — no extra snippet config. They’re returned alongside each event by GET /v1/events and the agent event tools (query_events, get_contact_details, batch_get_activity):
browser,browser_version,os,device_type(Desktop/Mobile/Tablet) — derived fromuserAgent.referring_domain— the host ofreferrer, or"direct"when there’s no referrer.is_bot— present (andtrue) only when theuserAgentmatches a known bot/crawler. Bot events are flagged, not dropped, so you can include or exclude them at read time (filteris_bot == trueto find them, oris_bot != trueto exclude). Absent on human traffic.
device_type, browser, os, referring_domain, and is_bot are also available as group_by dimensions in aggregate_data (e.g. event counts by device type or referring domain).
The first referrer / referring domain / landing page / UTMs seen for a visitor are also persisted to their contact as first-touch attribution — creation_referrer, creation_referring_domain, creation_landing_page, creation_utms (surfaced grouped under first_touch by get_contact_details). They are written once and never overwritten by later visits.
The fields below describe the data payload for each event.
Page lifecycle
Section titled “Page lifecycle”page_view
Section titled “page_view”Fires on the initial document load and on every client-side route change. For single-page apps the tracker patches history.pushState/replaceState and listens for popstate/hashchange; a route counts as a new view when pathname + search + hash changes (an identical repeated URL is ignored).
navigationTypeis"load"on the first paint and"spa"for in-app navigations.previousPathis present on"spa"views and holds the path the visitor came from.urlis the full URL of the page the view is for, query string included.utmParamsalso captures ad-click IDs when present in the URL:gclid,fbclid,msclkid,li_fat_id,ttclid,gbraid,wbraid. The first set seen for a visitor is persisted to their contact as first-touch attribution.
{ "title": "Pricing — Example", "path": "/pricing", "url": "https://example.com/pricing?plan=team", "navigationType": "spa", "previousPath": "/", "utmParams": { "utm_source": "google", "utm_medium": "cpc", "utm_campaign": "spring-2026" }, "userAgent": "…", "referrer": "…", "screenResolution": "1920x1080", "pageLoadTime": 412}On the very first load this event carries
navigationType: "load"and nopreviousPath.
page_leave
Section titled “page_leave”Fires for the page a visitor is leaving — on each SPA route change (for the page being navigated away from) and once on exit (pagehide / beforeunload). timeOnPage is the dwell time on that page in milliseconds. url and path always describe the page being left, never the next one.
{ "title": "Pricing — Example", "path": "/pricing", "url": "https://example.com/pricing?plan=team", "timeOnPage": 8423}first_visit
Section titled “first_visit”Fires once per browser, the first time the tracker assigns a fresh pathbound_visitor_id (i.e. no recoverable visitor existed for the device fingerprint).
{ "landingPage": "https://example.com/pricing", "landingPath": "/pricing", "initialReferrer": "https://google.com/", "utmParams": { /* same as page_view */ }, "title": "Pricing — Example", "userAgent": "…", "screenResolution": "1920x1080", "pageLoadTime": 410}User interactions
Section titled “User interactions”button_click
Section titled “button_click”Fires when a click resolves to a <button>, <input type="submit|button">, or any element with role="button" (including <a role="button"> — an explicit role wins over the tag) — including clicks that land on a child element (an icon or <span> inside the button). The captured text/class/id are the actionable element’s, not the child’s.
{ "text": "Get a demo", "class": "btn btn-primary", "id": "demo-cta", "elementType": "button"}link_click
Section titled “link_click”Fires when a click resolves to an <a> (without role="button") or any element with role="link", including clicks on a child element inside the link. isExternal is true if the link has an href whose hostname differs from the current page’s hostname.
{ "text": "Read the docs", "href": "https://pathbound.ai/docs", "class": "footer-link", "id": "", "elementType": "link", "isExternal": true}form_submit
Section titled “form_submit”Fires on every native <form> submit. Form field values are not captured here — submit them to the public form-submission endpoint for that.
{ "formId": "demo-form", "formClass": "contact-form", "action": "/submit", "method": "post"}Auto-detected when a <wistia-player> embed is on the page (or added later via DOM mutation).
video_play
Section titled “video_play”Fires when playback begins or resumes.
{ "provider": "wistia", "mediaId": "abc123def", "videoName": "Product overview", "duration": 187, "currentTime": 0, "pageTitle": "Home — Example", "pagePath": "/", "wistiaVisitorKey": "v1-…"}video_pause
Section titled “video_pause”Fires on pause, including when the user navigates away.
{ "provider": "wistia", "mediaId": "abc123def", "videoName": "Product overview", "duration": 187, "currentTime": 64, "secondsWatched": 58, "pageTitle": "Home — Example", "pagePath": "/"}video_complete
Section titled “video_complete”Fires when the video reaches its natural end.
{ "provider": "wistia", "mediaId": "abc123def", "videoName": "Product overview", "duration": 187, "secondsWatched": 187, "pageTitle": "Home — Example", "pagePath": "/"}video_milestone
Section titled “video_milestone”Fires once each at 25%, 50%, 75%, and 100% of duration. The 100% milestone may fire alongside video_complete.
{ "provider": "wistia", "mediaId": "abc123def", "videoName": "Product overview", "milestone": 50, "currentTime": 94, "duration": 187, "pageTitle": "Home — Example", "pagePath": "/"}video_conversion
Section titled “video_conversion”Fires when an in-video email-capture form is submitted.
{ "provider": "wistia", "mediaId": "abc123def", "videoName": "Product overview", "duration": 187, "currentTime": 32, "pageTitle": "Home — Example", "pagePath": "/", "conversionType": "email_only", "firstName": "Ada", "lastName": "Lovelace"}The submitted email is the most reliable identifier the tracker captures from in-page interactions. If the visitor isn’t already linked to a contact, video_conversion is what flips them from anonymous to identified.
System events
Section titled “System events”_fingerprint_update
Section titled “_fingerprint_update”Internal — fired when the tracker computes a fresh device fingerprint. Used by the server to maintain the fingerprint → visitor ID mapping. Most consumers can ignore this event type when reading /v1/events.