Events — Overview
Events is Pathbound’s built-in event capture. A small JavaScript snippet runs on your website and captures behavioral events — page views, clicks, form submissions, video plays — into the Pathbound platform. Once a visitor identifies (by submitting a form, clicking a tracked email link, or being matched via fingerprint), every event in their history is attached to their contact record.
Snippet URL
Section titled “Snippet URL”https://events.pathbound.ai/snippet.jsSites set up before October 2026 load https://tracker.pathbound.ai/tracker.js. That address keeps working unchanged, so there is nothing to update.
The script is served minified and gzipped/brotli-compressed, around 5 KB on the wire. There are no client-side dependencies; everything runs in vanilla browser JS.
What gets tracked
Section titled “What gets tracked”Out of the box, no configuration:
page_viewon every navigation, with title, path, UTM params, and load time.first_visitthe first time a browser is seen.button_clickon every<button>click — text, class, id.link_clickon every<a>click — text, href, internal vs external.form_submiton every native<form>submission — the form’s DOMid, class, action and method. Never the field values.- Video events when a
<wistia-player>embed is on the page —video_play,video_pause,video_complete,video_milestone(25/50/75/100%),video_conversion(in-video email capture).
Every event is enriched server-side with the visitor’s identity (cookie + fingerprint), session, referrer, screen resolution, user agent, and _ga user ID if Google Analytics is present.
How visitors get linked to contacts
Section titled “How visitors get linked to contacts”Four mechanisms, in order of reliability:
- Server-side identify — When a user logs in, call
POST /v1/identifyfrom your backend with their external ID + thepathbound_visitor_id. This is the authenticated path: it upserts the contact, merges traits, and back-fills their prior anonymous events immediately. - Client-side identify — Call
window.pathbound.identify(externalId, traits)at login (no backend or API key needed). It sets the external-contact cookie, records anidentifyevent, and creates or links the contact via the domain-gated public identify endpoint. - External contact ID cookie — If your app sets
pathbound_external_contact_iditself (the clientidentify()call does this for you), the snippet reads it on every event and the backend resolves it to a Pathbound contact. - Form submission — When your form posts to the public form endpoint with the visitor’s
visitor_id, the submission creates or updates a contact by email and ties that visitor to it. The snippet does not do this for you: see below.
Plus fingerprint recovery underneath them all — if the visitor’s pathbound_visitor_id cookie is missing (cleared, new device, incognito), the snippet computes a device fingerprint from Canvas + WebGL + AudioContext + system signals, hashes it (SHA-256), and asks the server for the canonical visitor ID. This recovers the timeline across cookie loss without depending on third-party identifiers.
Details: Identify logged-in users and Identity & fingerprinting.
form_submit and form_submission
Section titled “form_submit and form_submission”Two events have similar names and mean different things.
form_submitis the snippet noticing a submit on a page. It carries only the form’s DOMid, class,actionandmethod. It holds none of the field values, so it identifies nobody and creates no contact.form_submissionis written by the API when a form posts to the public form endpoint and the submission is stored. It is the one tied to a contact: the endpoint creates or updates the contact from the submitted email, and the event carries the ids of that contact and of the stored submission.
To capture what a visitor typed into a form, post the form to the public form endpoint. Loading the snippet on the page is not enough. Payloads: form_submit and form_submission.
Privacy
Section titled “Privacy”- Honors a Do-Not-Track cookie — set
pathbound_dnt=1on a domain and the snippet exits before doing anything. - Does not act on the browser’s Do Not Track or Global Privacy Control signals.
navigator.doNotTrackis read only as one of the fingerprint signals (so a DNT browser produces a different fingerprint than the same device without). - Stores cookies with
SameSite=Strict; Secureover HTTPS. - No third-party requests — events POST to Pathbound’s own ingest host:
events.pathbound.aifor the current snippet,tracker.pathbound.aifor installs from before October 2026. - Masks credentials and emails in captured URLs before anything is stored.
url,referrerand the landing-page fields keep their path and parameter names, but the values of OAuth callbackcode/state, tokens, passwords, API keys, signatures (including presigned S3/GCS links), email addresses, JWTs and 64+ character hex strings are replaced with[redacted], anywhere in the query, the fragment or a URL nested inside a parameter (returnTo=…). A token in the path is masked too: after a page named for a link sent by email (/reset_password/…,/verify/…,/confirm/…,/invite/…,/unsubscribe/…and the like), any later segment of six or more characters that does not read as words (a signedvalue:timestamp:signatureincluded), and on any page a segment with 32 or more generated characters. Record ids stay as they are (/map/<32 hex>, a UUID, a ULID), so a page keeps its identity. A URL with nothing to mask is stored exactly as captured, so URL filters and group-bys keep working. This applies to events, including their path fields (path,previousPath,landingPath,pagePath) and the campaign values inutmParams, and to a contact’s first-touch landing page and referrer.
Architecture
Section titled “Architecture”Event ingestion is a standalone Express service that:
- Serves the snippet (rate-limited, host-validated, brotli/gzip).
- Accepts batched events at
POST /track(up to 10 events per batch, 2-second timeout). - Provides fingerprint recovery at
POST /recover-visitor. - Writes directly to the same MongoDB as the REST API and MCP server, so events appear in
GET /v1/eventsimmediately.
This means event ingestion is not authenticated by API key — instead, the server validates the request’s Origin/Referer against the verified domains of each tenant. You verify domains in Settings → Domains in the dashboard.