Fields
Fields are used in where clauses, aggregations, group by, and sort. The available fields depend on the query source.
Core fields
Present on every event. Usable in all event-based queries.
| Field | Type | Description |
|---|---|---|
event_type | string | Event name (e.g. signup, page_view) |
user_id | string | User identifier set by your code |
device_id | string | Anonymous device identifier (auto-generated by Script Tag and TypeScript client) |
session_id | string | Session identifier (auto-generated by Script Tag and TypeScript client, 30-min timeout) |
distinct_id | string | Stitched identity (see Identity below) |
time | datetime | Event timestamp (client-provided or server now()) |
insert_id | string | Deduplication key (auto-generated if not provided) |
Page and content fields
Promoted from event_properties during enrichment. Available as first-class fields for filtering and grouping.
| Field | Type | Description |
|---|---|---|
_url | string | Full page URL (from event_properties.url) |
_path | string | URL path component (extracted from _url) |
_path_clean | string | ID-normalized path — UUIDs, numeric IDs, hex strings, etc. replaced with {id} (e.g. /users/123/settings → /users/{id}/settings) |
_hostname | string | URL hostname (extracted from _url) |
_title | string | Page title (from event_properties.title) |
_referrer | string | Referrer URL (from event_properties.referrer) |
_referrer_domain | string | Referrer domain (from event_properties.referring_domain) |
Examples:
# Top pages by pathpage_view | last 30d | count by _path | top 20
# Top pages with IDs normalized (groups /users/123 and /users/456 together)page_view | last 30d | count by _path_clean | top 20
# Filter by specific pagepage_view | where _path = "/pricing" | last 7d | count by day
# Traffic by hostname* | last 30d | count by _hostnameDevice fields
Server-enriched from the User-Agent header and request metadata. Prefixed with _.
| Field | Type | Values | Description |
|---|---|---|---|
_browser | string | Chrome, Firefox, Safari, … | Browser name |
_browser_version | string | 120.0, 3.1, … | Browser version |
_os | string | Windows, Mac OS X, Linux, Android, iOS, … | Operating system |
_os_version | string | 14.2, 10, … | OS version |
_platform | string | web, android, ios | Platform (detected from UA) |
_device_type | string | desktop, mobile, bot | Device classification |
Examples:
# Events by platform* | last 7d | count by _platform
# Mobile-only events* | where _device_type = "mobile" | last 30d | count by event_type | top 10
# Filter by browserpage_view | where _browser = "Chrome" | last 7d | countGeo fields
Enriched from client IP or trusted headers.
| Field | Alias | Description |
|---|---|---|
_geo_country | _country | Country code |
_geo_region | _region | Region/state |
_geo_region_code | _region_code | Region code |
_geo_city | _city | City |
_geo_continent | _continent | Continent |
_geo_timezone | _timezone | Timezone |
_geo_metro_code | _metro_code | Metro code |
_geo_postal_code | _postal_code | Postal code |
_geo_latitude | _latitude | Latitude |
_geo_longitude | _longitude | Longitude |
_geo_source | Geo enrichment source (e.g. cf_header) |
Short aliases (e.g. _country) resolve to canonical field names (e.g. _geo_country) at compile time.
Examples:
# Events by country (using short alias)* | last 30d | count by _country | top 10
# Region filter* | where _country = "US" | last 30d | count by _region | top 10Other system fields
| Field | Type | Description |
|---|---|---|
_ip | string | Client IP (may be anonymized per policy) |
_ua | string | Raw User-Agent string |
_library | string | SDK identifier (e.g. wirelog-typescript/1.0) |
_ingest_origin | string | Ingestion origin: client, server, unknown |
Event properties
Access nested properties sent in the event_properties object on track calls.
Syntax: event_properties.<KEY>
| where event_properties.page = "/pricing"| sum event_properties.amount by day| where event_properties.button contains "signup"Property keys must match [a-zA-Z0-9_.\-]+ and be at most 256 characters.
Examples:
# Filter by a custom propertypurchase | where event_properties.plan = "pro" | last 30d | count
# Sum a numeric propertypurchase | last 30d | sum event_properties.amount by week
# P95 of a latency propertyapi_call | last 7d | p95 event_properties.duration_msUser properties (on event)
Access user properties sent alongside the event in the user_properties object.
Syntax: user_properties.<KEY>
| where user_properties.plan = "enterprise"| count by user_properties.roleThese are the user properties attached at track time, not the latest profile state. For latest profile state, use user.<KEY>.
Profile fields
Access the user_profiles table for the latest user state. Populated by identify() calls.
Syntax: user.<KEY>
Built-in profile fields
| Field | Type | Description |
|---|---|---|
user.email | string | Email address (set via identify) |
user.email_domain | string | Domain extracted from email (e.g. acme.org) |
user.first_seen | datetime | Timestamp of first event |
user.last_seen | datetime | Timestamp of most recent event |
Custom profile properties
Any key set via identify() user properties:
user.planuser.companyuser.roleuser.acquisition_channelThese resolve to user_properties['<key>'] on the user_profiles table.
Availability by source:
| Source | user.* fields | Notes |
|---|---|---|
Event queries (*, <event>) | Yes | Joins user_profiles via stitched identity |
funnel, retention, paths, sessions, lifecycle, stickiness | Yes | Identity-backed sources resolve user.* via profile join |
user "<id>" | Yes | Joins user_profiles for the specified user |
users | Yes | Queries user_profiles directly |
formula | No | Event-level metrics only |
Examples:
# Events from enterprise users* | where user.plan = "enterprise" | last 30d | count by event_type
# All events from a specific company* | where user.email_domain = "acme.org" | last 12w | count by week
# User directory: list enterprise usersusers | where user.plan = "enterprise" | list
# Count users by planusers | count by user.plan | top 10Session fields
Session fields are available in identity-backed/event-backed sources. They resolve from sessions_agg.
Syntax: session.<KEY>
Common fields:
session.start_time,session.end_timesession.duration,session.event_countsession.landing_url,session.landing_path,session.landing_path_clean,session.landing_hostname,session.referrer,session.referring_domainsession.utm_source,session.utm_medium,session.utm_campaign,session.utm_term,session.utm_contentsession.gclid,session.fbclidsession.language,session.timezonesession.ingest_origin,session.geo_sourcesession.country,session.region,session.region_code,session.city,session.continentsession.geo_timezone,session.metro_code,session.postal_code,session.latitude,session.longitudesession.first_event,session.last_event,session.exit_url,session.exit_path,session.exit_path_clean
# Sessions by campaignsessions | where session.utm_source = "google" | last 30d | count by day
# Region filter on raw events* | where session.region = "DE" | last 30d | countLatest stitched session fields
Use user_last_session.* when you want to filter events by each user’s latest stitched session context (not the event’s own session_id).
Syntax: user_last_session.<KEY>
user_last_session.* supports the same key space as session.*.
# Backend spend attributed to latest browser/session regionai_usage_charged | where user_last_session.region = "DE" | last 30d | sum event_properties.amount
# Campaign-attributed spendai_usage_charged | where user_last_session.utm_source = "google" | last 30d | sum event_properties.amountIdentity
distinct_id is the stitched identity field:
coalesce(user_id, mapped_user_id, device_id)Resolution order:
user_id— explicitly set user identifiermapped_user_id— looked up fromdevice_user_map(set byidentify()binding adevice_idto auser_id)device_id— anonymous device identifier (fallback)
Use unique distinct_id when you want unique user counts. This correctly deduplicates anonymous and identified events from the same user.
# Unique users per weeksignup | last 12w | unique distinct_id by week
# Unique users by platform* | last 30d | unique distinct_id by _platformPre-identify attribution: Events tracked before an identify() call are attributed retroactively. Once a device-to-user mapping exists in device_user_map, queries using distinct_id will include the anonymous events from that device.
Field introspection
Use the fields source to discover all available fields at runtime:
fields | last 7dReturns system/core fields plus dynamic event_properties.* and user_properties.* keys actually present in your data. Useful for LLMs and agents to discover what fields are available before writing queries.
Event inspection
Use the inspect source to discover event types and their properties:
inspect * | last 30dinspect signup | last 7dinspect * returns per-event-type overview: count, unique users, first/last seen, and top property keys. inspect <event> returns property-level detail: coverage %, inferred type (string/numeric/boolean), and top sample values.
This is the recommended first query for LLMs — it answers “what events exist and what data does each carry?” in a single request.
Property type handling
Properties are normalized on ingest into typed storage buckets:
| Type | Storage | Query behavior |
|---|---|---|
| String | event_properties / user_properties (canonical maps) | Direct string comparison |
| Number | *_num maps + canonical string map | Numeric aggregations (sum, avg, etc.) use numeric bucket first, fall back to toFloat64OrNull on string |
| Boolean | *_bool maps + canonical string map | Stored as 1/0 in bool bucket |
| Null | *_null arrays + excluded from other maps | Key recorded in null array |
| Object/Array | JSON-stringified in canonical string map | Stored as string; queryable via string operators |
Queries automatically check the correct typed bucket. You do not need to reference _num or _bool maps directly — the compiler handles this.
For numeric comparisons (>, <, >=, <=) with numeric literal values, the compiler uses the numeric bucket automatically. Non-numeric comparison values fall back to string semantics.
For exists/not exists on property fields, the compiler checks mapContains on the canonical map.