Auto-Properties
Auto-properties are $-prefixed key-value pairs that Pug attaches to every event automatically. The SDK adds them on the client before the event leaves the device; the server adds a second layer during ingestion.
The $ prefix is reserved. Custom event properties you send must not start with $ — the API rejects any event whose custom property keys begin with $. See Events API for validation details.
You do not need to set auto-properties yourself. Sending them manually has no effect for server-set properties (they are overwritten) and creates duplicates for SDK-set ones.
SDK-set properties — Web
Set by @pug-sh/browser inside autoProperties on every event, before the batch is sent to the API.
| Property | Type | Description | Example |
|---|---|---|---|
$projectId | string | Project identifier | proj_abc123 |
$platform | string | SDK platform — always web | web |
$url | string | Full URL of the current page (window.location.href) | https://app.example.com/pricing |
$referrer | string | Document referrer (document.referrer); empty string when none | https://google.com |
$pageTitle | string | Page title (document.title) | Pricing — Acme |
$locale | string | Browser locale (navigator.language) | en-US |
$screenWidth | string | Screen width in CSS pixels (window.screen.width) | 1920 |
$screenHeight | string | Screen height in CSS pixels (window.screen.height) | 1080 |
$sdkVersion | string | Web SDK version string | 0.0.1 |
$browser | string | Browser name, from navigator.userAgentData brands (Chromium) | Google Chrome |
$browserVersion | string | Browser major version string | 124 |
$os | string | Operating system / platform | macOS |
$osVersion | string | OS version (high-entropy, Chromium only) | 14.4.1 |
$device | string | Device model (high-entropy, Chromium only) | Pixel 8 |
$mobile | string | "true" or "false" — whether the UA reports a mobile device | "false" |
$utmSource | string | utm_source query parameter | google |
$utmMedium | string | utm_medium query parameter | cpc |
$utmCampaign | string | utm_campaign query parameter | spring_sale |
$utmContent | string | utm_content query parameter | banner_a |
$utmTerm | string | utm_term query parameter | analytics+software |
UTM parameters are parsed from window.location.search on every event call. $browser, $browserVersion, $os, $osVersion, $device, and $mobile are read from the User-Agent Client Hints API (navigator.userAgentData) and are only populated in Chromium-based browsers. Firefox and Safari do not expose this API; those browsers get UA properties set by the server-side fallback (see Server-set properties below). $platform has no such fallback — it comes only from the SDK. Other Pug SDKs set the same key with their own value, so you can filter and break down by platform across them; see Casing differences between SDKs for exactly what each one reports.
See Auto-tracking for which events trigger automatically.
SDK-set properties — Flutter
Set by pug_flutter inside autoProperties on every event. All keys are camelCase.
Core
| Property | Type | Description | Example |
|---|---|---|---|
$projectId | string | Project identifier | proj_abc123 |
$sdkVersion | string | Flutter SDK version string | 0.0.2 |
$platform | string | Flutter target platform name (defaultTargetPlatform.name) | android, iOS, macOS |
$os | string | Operating system (Platform.operatingSystem) | android |
$osVersion | string | OS version string | 14 |
$locale | string | Device locale as a BCP 47 language tag | en-US |
$timezone | string | IANA timezone identifier (from flutter_timezone; falls back to DateTime.now().timeZoneName’s abbreviation) | America/New_York |
$url | string | Current route name — set when a PugRouteObserver is wired | /checkout |
$referrer | string | Previous route name — set alongside $url on navigation | /cart |
Screen
| Property | Type | Description | Example |
|---|---|---|---|
$screenWidth | integer | Logical screen width in dp | 390 |
$screenHeight | integer | Logical screen height in dp | 844 |
$screenScale | number | Device pixel ratio | 3.0 |
App
| Property | Type | Description | Example |
|---|---|---|---|
$appName | string | App name from PackageInfo | Acme App |
$appPackage | string | Bundle / package identifier | com.example.acme |
$appVersion | string | App version string | 1.4.2 |
$appBuild | string | App build number | 42 |
Device (populated per platform)
| Property | Platform | Description | Example |
|---|---|---|---|
$deviceManufacturer | Android, iOS, macOS, Linux, Windows | Device manufacturer or OEM | Apple, Samsung |
$deviceModel | Android, iOS, macOS, Linux, Windows | Device model name | iPhone 15 Pro, Pixel 8 |
The user-assigned device name is deliberately not collected — it’s PII.
Network
| Property | Type | Description | Example |
|---|---|---|---|
$networkType | string | Active connectivity type | wifi, mobile, ethernet, vpn, bluetooth, other, none, unknown |
Campaign and click-ids
Captured from deep-link URIs when autoCaptureCampaigns is enabled. Persisted until the next campaign URL is opened.
| Property | Description | Example |
|---|---|---|
$utmSource | utm_source query parameter | google |
$utmMedium | utm_medium query parameter | cpc |
$utmCampaign | utm_campaign query parameter | spring_sale |
$utmTerm | utm_term query parameter | analytics+software |
$utmContent | utm_content query parameter | banner_a |
$gclid | Google Click ID | Cj0KCQjw... |
$fbclid | Meta (Facebook) Click ID | IwAR3x... |
$msclkid | Microsoft Advertising Click ID | abc123 |
$ttclid | TikTok Click ID | Cg8IEAA... |
See Auto-tracking for the navigation events (screen_view on mobile, page_view on web) emitted when a PugRouteObserver is wired.
SDK-set properties — Node
Set by @pug-sh/node inside autoProperties on every event, before the batch is sent to the API.
| Property | Type | Description | Example |
|---|---|---|---|
$lib | string | Library identifier — always pug-node | pug-node |
$sdkVersion | string | Node SDK version string | 0.0.5 |
$platform | string | SDK platform — always server | server |
That is the complete set. The server SDK has no browser, device, or ambient user, so it sets none of the page, screen, locale, or campaign properties the client SDKs collect — pass anything you need as a custom property on track() instead. It also omits $projectId: the private key (prv_…) it authenticates with is already project-scoped, so there is no project ID to supply at init.
Server-set properties are still added during ingestion, but they describe your backend rather than your end user — the request reaches the API from your server, so $ip and every geo property derived from it resolve to your server’s address. Filter on $platform = "server" to keep server events out of geo and browser breakdowns.
Casing differences between SDKs
Every Pug SDK sets $platform, which makes it the one key common to all of them — filter or break down on it to separate traffic by SDK.
| SDK | $platform value | Example |
|---|---|---|
@pug-sh/browser | always web | web |
pug_flutter | Flutter target platform name (defaultTargetPlatform.name) | android, iOS, macOS |
@pug-sh/node | always server | server |
Beyond that key, the Web SDK and Flutter SDK share several property names with identical casing. The table below calls out any divergence so you can write cross-platform queries correctly. “not set” = the SDK could supply this but doesn’t (a real gap on that platform); “not applicable” = the concept doesn’t exist on that platform. The Node SDK is left out: it sets only the three properties listed in its section above.
| Concept | Web SDK property | Flutter SDK property |
|---|---|---|
| URL / screen name | $url (full URL) | $url (current route name; set when PugRouteObserver is wired) |
| Page / screen title | $pageTitle | not set |
| Referrer | $referrer | $referrer (previous route name) |
| Platform | $platform (always web) + $os (platform string) | $platform (Flutter enum name) + $os |
| OS version | $osVersion | $osVersion |
| Browser | $browser | not set |
| Browser version | $browserVersion | not set |
| Device model | $device | $deviceModel |
| Mobile flag | $mobile (string "true"/"false") | not set |
| Screen width | $screenWidth | $screenWidth |
| Screen height | $screenHeight | $screenHeight |
| Locale | $locale | $locale |
| Timezone | not set client-side | $timezone |
| UTM source | $utmSource | $utmSource |
| UTM medium | $utmMedium | $utmMedium |
| UTM campaign | $utmCampaign | $utmCampaign |
| UTM term | $utmTerm | $utmTerm |
| UTM content | $utmContent | $utmContent |
| Click-ids | not set | $gclid, $fbclid, $msclkid, $ttclid |
| App info | not applicable | $appName, $appPackage, $appVersion, $appBuild |
| Network type | not set | $networkType |
Server-set properties
Added by the ingestion server during BatchCreate, after the SDK payload arrives. These properties are never present in the SDK payload — values sent by clients are ignored or actively stripped.
Geo enrichment (Cloudflare)
Geo properties come from Cloudflare CDN headers injected at the edge. They are populated only when the API is fronted by Cloudflare with the “Add visitor location headers” Managed Transform enabled. Behind other proxies or in self-hosted setups without Cloudflare, these properties will be absent.
| Property | Description | Example |
|---|---|---|
$ip | Client IP address (from CF-Connecting-IP, then True-Client-IP, then X-Forwarded-For) | 203.0.113.1 |
$continent | Continent code | NA |
$country | ISO 3166-1 alpha-2 country code | US |
$region | Region or state name | California |
$city | City name | San Francisco |
$postalCode | Postal / ZIP code | 94107 |
$metroCode | Metro code (US DMA) | 807 |
$latitude | Latitude (float64) | 37.7749 |
$longitude | Longitude (float64) | -122.4194 |
$timezone | IANA timezone name from Cloudflare | America/Los_Angeles |
User-agent enrichment (server-side fallback)
For browsers that do not expose the User-Agent Client Hints API (Firefox, Safari, all iOS browsers), the server parses the User-Agent request header and sets these properties. For Chromium browsers the SDK supplies these values directly and they take precedence.
| Property | Description | Example |
|---|---|---|
$browser | Browser family name | Firefox |
$browserVersion | Browser version string | 126.0 |
$os | Operating system name | Mac OS X |
$osVersion | OS version string | 10.15.7 |
$device | Device family | iPhone |
$mobile | "true" or "false" | "false" |
Bot signals (Cloudflare)
$bot_score and $verified_bot are server-only properties. Any values sent by the client are stripped before enrichment begins; the server then sets them from Cloudflare’s CF-Bot-Score and CF-Verified-Bot headers.
| Property | Type | Description | Example |
|---|---|---|---|
$bot_score | integer | Cloudflare bot score (0–99; lower = more likely bot) | 2 |
$verified_bot | boolean | true if Cloudflare identified a known good bot | false |
These properties are only populated when Cloudflare is in the request path. In self-hosted deployments without Cloudflare, they will be absent.
Using auto-properties in queries
Reference any auto-property in Insights filters and breakdowns exactly like custom properties, using the exact key string including the $ prefix.
Breakdown by country:
Filter to Chrome users only:
UTM campaign performance:
Exclude bots:
Related
- Events API — event validation rules including the
$-prefix restriction on custom properties - Auto-tracking — what each SDK captures automatically (Web interactions; Flutter navigation + app lifecycle)