Browser events (POST /ct)
Browser events are sent automatically by the SDK or manually via scanova('track', ...). They represent actions that happen in the user’s browser.
Fields you can send
| Field | Type | Required | Description |
|---|---|---|---|
event_id | UUID string | No | Unique identifier for this event. Auto-generated by the SDK if omitted. Send a stable ID from your code if you want safe retries. |
site_id | string | Yes | Your tracking site ID from the dashboard. |
event_type | string | Yes | The type of event. Use snake_case (e.g. page_view, cta_click, signup_completed). |
scan_session_id | UUID string | No | Set automatically by the SDK from the scnv URL parameter. Required for QR attribution. |
web_session_id | UUID string | No | Set automatically by the SDK per browser session (30-minute timeout). |
visitor_id | UUID string | No | Set automatically by the SDK. Persists for 1 year via cookie. |
page_url | string | No | Full URL of the current page including query string. |
page_title | string | No | Page title. Not sent by the Browser SDK; only useful for custom direct API integrations. |
referrer | string | No | The referring URL. |
event_time | ISO 8601 string | No | Event time in UTC. Defaults to server receive time if omitted. Note: the Browser SDK sends a timestamp key which is a separate, internal field — when calling the API directly, use event_time. |
device | object | No | Browser/device context — see below. |
metadata | object | No | Custom key-value data. Max 10 KB, max depth 5. No raw email addresses. |
device object fields:
| Field | Description |
|---|---|
user_agent | Browser user-agent string |
screen_width | Screen width in pixels |
screen_height | Screen height in pixels |
language | Browser language (e.g. en-US) |
Example browser event payload
Server events (POST /server-events)
Server events are sent from your backend using an API key. They represent actions that happen on your server, such as completed purchases, confirmed sign-ups, or leads created in your CRM.
Fields you can send
| Field | Type | Required | Description |
|---|---|---|---|
event_id | UUID string | Recommended | Unique event ID for safe retries. Generate once, persist, reuse on retry. |
site_id | string | Yes | Your tracking site ID. Must match the API key’s authorized site. |
event_name | string | Yes | Semantic event name (e.g. purchase, signup, lead). |
scan_session_id | UUID string | Yes | Links this server event to the originating QR scan. Pass from browser to your server. |
web_session_id | UUID string | No | The browser’s web session ID — pass from the browser if available, for richer session linking. |
visitor_id | UUID string | No | The browser’s persistent visitor ID — pass from the browser if available. |
event_time | ISO 8601 string | No | When the event occurred. Defaults to time of receipt. |
conversion_value | object | No | { "amount": 99.99, "currency": "USD" }. Currency must be a 3-letter ISO 4217 code. |
user_identifiers | object | No | Hashed user identifiers — see below. Never send raw email or phone. |
properties | object | No | Custom key-value metadata. Max 10 KB. No raw emails. |
consent | string | No | granted, denied, or pending. |
user_identifiers object fields (all hashed):
| Field | Description |
|---|---|
email_hash | SHA-256 hash of the user’s lowercase email address |
phone_hash | SHA-256 hash of the user’s E.164-format phone number |
external_id | Your internal user/customer ID |
Example server event payload
Event naming conventions
Use consistent, descriptive names insnake_case. A clear naming scheme makes reports easier to read.
| Good | Avoid |
|---|---|
page_view | pageView, PageView, pv |
cta_click | click1, btnClick |
signup_completed | signup, reg |
purchase | buy, order_placed_final |
Idempotency
Both browser and server events support anevent_id field for deduplication:
- If the same
event_idarrives more than once, the duplicate is stored but markedis_duplicate = 1 - Duplicates are excluded from analytics views automatically
- Always reuse the same
event_idwhen retrying a failed server event
Privacy and GDPR
- Never send raw email addresses in
metadataorproperties. Useuser_identifierswith hashed values. - The
consentfield controls PII handling in the pipeline:granted— all fields are stored normallydeniedorpending—page_url,referrer,city, andmetadataare stripped before storage- The
consentvalue itself is always stored as an audit trail
Sending consent from the browser
The Browser SDK does not have a built-in consent API. The recommended approach is to conditionally load the SDK based on your consent management platform’s decision:Sending consent from the server
For server events, pass theconsent value directly in every request payload alongside your other fields.