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 JS SDK) |
session_id | string | Session identifier (auto-generated by JS SDK, 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) |
System 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 |
_ip | string | Client IP (may be anonymized per policy) | |
_library | string | wirelog-js/1.0, … | SDK identifier |
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 | countEvent 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 |
user "<id>" | Yes | Joins user_profiles for the specified user |
users | Yes | Queries user_profiles directly |
funnel, retention, paths, sessions | No | Not supported; use event queries with where user.* instead |
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 10Identity
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.
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.