Query Studio Schema Reference
Complete reference for all queryable tables available in Zenovay Query Studio. Use this guide to explore the database schema, understand column types, and write accurate SQL queries.
All queries must include WHERE website_id = 'your-website-id' to scope results to your website. Queries without this filter will be rejected.
Query Studio enforces a maximum of 1,000 rows per query and a 10-second timeout. Only SELECT statements are allowed — all write operations (INSERT, UPDATE, DELETE, DROP, etc.) are blocked.
Core Analytics
visitors
Individual visitor records with geolocation, device information, UTM tracking parameters, and behavioral engagement scores. This is the primary table for granular visitor-level analysis.
| Column | Type | Description |
|---|---|---|
id | uuid | Unique visitor record identifier |
website_id | uuid | Website this visitor belongs to |
visitor_id | text | Anonymized visitor identifier (hashed) |
page_url | text | Full URL of the page visited |
landing_page | text | First page the visitor landed on |
referrer | text | Referring URL that brought the visitor |
country_code | varchar | ISO 3166-1 alpha-2 country code (e.g., US, GB) |
country_name | varchar | Full country name (e.g., United States) |
city | varchar | City name from IP geolocation |
device_type | text | Device category: desktop, mobile, or tablet |
browser | varchar | Browser name (e.g., Chrome, Firefox, Safari) |
os | varchar | Operating system (e.g., Windows, macOS, iOS) |
utm_source | varchar | UTM source parameter (e.g., google, newsletter) |
utm_medium | varchar | UTM medium parameter (e.g., cpc, email, organic) |
utm_campaign | varchar | UTM campaign name |
channel | varchar | Attributed marketing channel (e.g., Organic Search, Direct, Social) |
had_interaction | boolean | Whether the visitor interacted with the page (clicks, scrolls, etc.) |
is_returning_visitor | boolean | true if the visitor has been seen before |
time_on_page | integer | Time spent on the page in seconds |
scroll_depth_percentage | integer | Maximum scroll depth reached (0-100) |
value_score | integer | Computed engagement score (0-100) based on behavior |
conversion_event | varchar | Name of the conversion event triggered, if any |
conversion_value | numeric | Monetary value associated with the conversion |
visited_at | timestamptz | Timestamp when the visit occurred |
analytics_daily
Pre-aggregated daily statistics for fast dashboard queries. Use this table instead of visitors when you need daily summaries — it is significantly faster for date-range reports.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
date | date | The calendar date for this aggregate |
visitors | integer | Total visitor count for the day |
page_views | integer | Total page views for the day |
unique_visitors | integer | Count of unique visitors |
sessions | integer | Number of distinct sessions |
avg_session_duration | integer | Average session duration in seconds |
bounce_rate | numeric | Bounce rate as a decimal (e.g., 0.45 = 45%) |
top_countries | jsonb | Top countries by visitor count |
top_devices | jsonb | Device type breakdown |
top_browsers | jsonb | Browser usage breakdown |
top_referrers | jsonb | Top referring sources |
top_pages | jsonb | Most visited pages |
JSONB columns like top_countries can be queried using the -> (returns JSON) and ->> (returns text) operators. Example: top_countries->0->>'country' returns the top country name.
page_views
Individual page view events with performance and engagement metrics. Each row represents a single page load by a visitor within a session.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
visitor_id | uuid | Reference to the visitor |
session_id | uuid | Session this page view belongs to |
page_url | text | Full URL of the page |
page_title | text | HTML title of the page |
page_path | text | URL path without domain (e.g., /pricing) |
load_time_ms | integer | Page load time in milliseconds |
time_on_page_seconds | integer | Time spent on this page in seconds |
scroll_depth_percentage | integer | Maximum scroll depth reached (0-100) |
clicks_count | integer | Number of clicks on this page |
had_interaction | boolean | Whether meaningful interaction occurred |
timestamp | timestamptz | When the page view occurred |
live_visitors
Currently active visitors on your website. This table is updated in real-time and reflects visitors who have been active within the last few minutes.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
visitor_id | uuid | Visitor identifier |
current_page_url | text | Page the visitor is currently viewing |
landing_page | text | First page of the current session |
pages_viewed | integer | Number of pages viewed in this session |
device_type | varchar | Device category |
browser | varchar | Browser name |
country_name | varchar | Country of the visitor |
channel | varchar | Traffic channel attribution |
is_active | boolean | Whether the visitor is still actively browsing |
is_new_visitor | boolean | true if this is the visitor's first session |
Revenue & Payments
payments
Payment transactions synced from connected payment providers (Stripe, LemonSqueezy, Polar). Each row represents a single transaction.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
amount | numeric | Transaction amount in the specified currency |
currency | varchar | ISO 4217 currency code (e.g., USD, EUR) |
status | varchar | Payment status: succeeded, pending, failed, refunded |
provider | varchar | Payment provider: stripe, lemonsqueezy, polar |
marketing_channel | varchar | Attributed marketing channel for this payment |
utm_source | varchar | UTM source tied to this transaction |
customer_email | varchar | Customer email address |
customer_name | varchar | Customer display name |
created_at | timestamptz | When the payment was created |
revenue_attribution
Revenue attributed to marketing channels over defined time periods. Use this table for channel ROI analysis and marketing performance reporting.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
period_start | date | Start date of the attribution period |
period_end | date | End date of the attribution period |
marketing_channel | varchar | Marketing channel name |
utm_source | varchar | UTM source for this attribution |
total_revenue | numeric | Total revenue attributed to this channel |
transaction_count | integer | Number of transactions |
unique_customers | integer | Count of unique paying customers |
conversion_rate | numeric | Conversion rate as a decimal |
identified_users
Known users who have been identified via the visitor identification API. Includes subscription status and lifetime revenue data.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
email | varchar | User email address |
name | varchar | User display name |
total_revenue | numeric | Lifetime revenue from this user |
subscription_status | varchar | Current status: active, canceled, past_due, trialing |
subscription_plan | varchar | Plan name (e.g., Pro, Enterprise) |
total_sessions | integer | Total number of sessions |
first_seen_at | timestamptz | When the user was first identified |
last_seen_at | timestamptz | Most recent activity timestamp |
Goals & Funnels
custom_goals
Goal definitions configured in the dashboard. Each goal tracks a specific user action such as visiting a URL or triggering a custom event.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
name | varchar | Human-readable goal name |
goal_type | varchar | Goal type: url, event, pageview |
url_pattern | text | URL pattern to match (for URL-type goals) |
event_name | varchar | Event name to match (for event-type goals) |
is_active | boolean | Whether the goal is currently active |
default_value | numeric | Default monetary value per completion |
goal_completions
Individual goal conversion events. Each row represents a single instance of a visitor completing a defined goal.
| Column | Type | Description |
|---|---|---|
goal_id | uuid | Reference to the goal definition |
website_id | uuid | Website identifier |
visitor_id | text | Visitor who completed the goal |
completion_value | numeric | Value of this specific completion |
page_url | text | Page where the completion occurred |
utm_source | varchar | UTM source at time of completion |
device_type | varchar | Device used |
country_name | varchar | Country of the visitor |
completed_at | timestamptz | When the goal was completed |
funnels
Funnel definitions for multi-step conversion tracking.
| Column | Type | Description |
|---|---|---|
id | uuid | Unique funnel identifier |
website_id | uuid | Website identifier |
name | varchar | Funnel name |
funnel_steps
Individual steps within a funnel, ordered sequentially. Join with funnels on funnel_id to get the full funnel configuration.
| Column | Type | Description |
|---|---|---|
funnel_id | uuid | Reference to the parent funnel |
step_order | integer | Position in the funnel sequence (1-based) |
step_name | varchar | Display name for this step |
step_type | varchar | Step type: url, event |
url_pattern | text | URL pattern to match (for URL steps) |
event_name | varchar | Event name to match (for event steps) |
Errors & Performance
error_groups
Grouped error types with occurrence counts and severity. Errors are automatically deduplicated and grouped by type and message.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
error_type | varchar | Error category: javascript, network, unhandled_rejection |
error_message | text | The error message string |
occurrence_count | integer | Total number of times this error has occurred |
user_count | integer | Number of unique users affected |
severity | varchar | Severity level: low, medium, high, critical |
status | varchar | Triage status: open, resolved, ignored |
first_seen | timestamptz | When this error was first recorded |
last_seen | timestamptz | Most recent occurrence |
error_occurrences
Individual error events with full context including stack traces and environment details.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
error_type | varchar | Error category |
error_message | text | The error message |
stacktrace | jsonb | Full stack trace as structured JSON |
page_url | text | Page where the error occurred |
browser | varchar | Browser name and version |
os | varchar | Operating system |
severity | varchar | Severity level |
timestamp | timestamptz | When the error occurred |
performance_metrics
Core Web Vitals measurements (LCP, CLS, INP) collected from real user monitoring. Each row is a single measurement from a page load.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
page_url | text | Page where metrics were collected |
lcp_value | numeric | Largest Contentful Paint in milliseconds |
lcp_rating | varchar | LCP rating: good, needs-improvement, poor |
cls_value | numeric | Cumulative Layout Shift score |
cls_rating | varchar | CLS rating: good, needs-improvement, poor |
inp_value | integer | Interaction to Next Paint in milliseconds |
inp_rating | varchar | INP rating: good, needs-improvement, poor |
device_type | varchar | Device type used for this measurement |
browser | varchar | Browser name |
recorded_at | timestamptz | When the measurement was recorded |
Uptime Monitoring
uptime_checks
Individual uptime check results from the monitoring system. Each row represents a single health check ping to your website.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
checked_at | timestamptz | When the check was performed |
is_up | boolean | Whether the site responded successfully |
status_code | integer | HTTP response status code |
response_time_ms | integer | Response time in milliseconds |
error_message | text | Error message if the check failed |
region | varchar | Monitoring region (e.g., us-east, eu-west, ap-south) |
uptime_daily
Daily uptime aggregates. Use this for SLA reporting and trend analysis instead of querying individual checks.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
date | date | Calendar date |
uptime_percentage | numeric | Uptime as a percentage (e.g., 99.95) |
avg_response_time_ms | integer | Average response time in milliseconds |
incidents_count | integer | Number of downtime incidents |
checks_total | integer | Total number of checks performed |
User Behavior
heatmap_data
Aggregated click and scroll heatmap data on a grid overlay. Each row represents a grid cell with accumulated interaction counts.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
page_path | varchar | Page path for this heatmap |
heatmap_type | varchar | Type: click, scroll, move |
grid_x | smallint | Horizontal grid coordinate |
grid_y | smallint | Vertical grid coordinate |
hit_count | integer | Number of interactions in this grid cell |
intensity | numeric | Normalized intensity value (0.0 to 1.0) |
heatmap_sessions
Session-level summaries of heatmap interaction data per page.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
page_url | text | Full URL of the page |
total_clicks | integer | Total clicks recorded |
total_movements | integer | Total mouse movements recorded |
total_scroll_events | integer | Total scroll events recorded |
replay_sessions
Session replay recording metadata. Each row represents a recorded browsing session that can be replayed in the dashboard.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
visitor_id | varchar | Visitor who was recorded |
duration_ms | integer | Total recording duration in milliseconds |
total_events | integer | Number of DOM events captured |
total_size | integer | Recording data size in bytes |
started_at | timestamptz | When the recording started |
frustration_events
Detected user frustration signals including rage clicks, dead clicks, and error clicks.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
frustration_type | varchar | Type: rage_click, dead_click, error_click, thrashed_cursor |
page_url | text | Page where frustration was detected |
timestamp | timestamptz | When the event occurred |
scroll_depth_stats
Aggregated scroll depth statistics by page, showing how far visitors scroll on each page.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
page_path | varchar | Page path |
depth_percentage | smallint | Scroll depth bucket (e.g., 25, 50, 75, 100) |
reach_count | integer | Number of visitors who reached this depth |
session_history
Completed session summaries with engagement and conversion metrics.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
visitor_id | uuid | Visitor identifier |
total_duration_seconds | integer | Total session duration in seconds |
pages_viewed | integer | Number of pages viewed in the session |
bounce | boolean | true if the visitor left after one page |
converted | boolean | true if a conversion event was triggered |
conversion_value | numeric | Total conversion value for the session |
B2B & Companies
b2b_companies
Identified companies visiting your website, enriched with firmographic data from IP-to-company resolution.
| Column | Type | Description |
|---|---|---|
id | text | Unique company identifier |
name | text | Company name |
domain | text | Company website domain |
industry | text | Industry classification |
employee_count | integer | Estimated number of employees |
revenue_range | text | Estimated annual revenue range (e.g., $10M-$50M) |
b2b_company_visits
Company-level visit aggregates. Join with b2b_companies on company_id = id for full company details.
| Column | Type | Description |
|---|---|---|
company_id | text | Reference to the company |
website_id | uuid | Website identifier |
total_visits | integer | Total number of visits from this company |
total_page_views | integer | Total page views from this company |
engagement_score | numeric | Computed engagement score (0-100) |
last_visit | timestamptz | Most recent visit timestamp |
Marketing & Campaigns
campaign_performance
UTM campaign performance metrics aggregated by date. Use this for marketing ROI analysis and campaign comparison.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
utm_source | varchar | UTM source parameter |
utm_campaign | varchar | UTM campaign name |
visitors | integer | Number of visitors from this campaign |
conversions | integer | Number of conversions attributed |
revenue | numeric | Total revenue attributed |
bounce_rate | numeric | Bounce rate as a decimal |
date | date | Date of the metrics |
gsc_keyword_data
Google Search Console keyword performance data synced via the GSC integration. Shows how your pages perform in Google search results.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
query | text | Search query (keyword) |
clicks | integer | Number of clicks from search results |
impressions | integer | Number of times shown in search results |
ctr | numeric | Click-through rate as a decimal (e.g., 0.034 = 3.4%) |
position | numeric | Average position in search results |
date | date | Date of the search data |
Custom Events
custom_events
User-defined tracking events sent via the custom events API. Each row represents a single event occurrence with optional properties and revenue data.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
event_name | varchar | Name of the custom event (e.g., signup, add_to_cart) |
event_category | varchar | Event category for grouping |
visitor_id | uuid | Visitor who triggered the event |
properties | jsonb | Custom key-value properties attached to the event |
revenue | numeric | Revenue value associated with this event |
page_url | text | Page where the event was triggered |
The properties column is JSONB. Query specific properties using properties->>'key_name'. Example: WHERE properties->>'plan' = 'pro'.
events
System-level events tracked automatically by the Zenovay tracker. Includes page views, clicks, form submissions, and other built-in event types.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
visitor_id | uuid | Visitor identifier |
event_type | text | Event type: pageview, click, form_submit, video_progress, file_upload, scroll, custom |
event_name | text | Specific event name |
event_value | text | String value associated with the event |
event_data | jsonb | Additional structured event data |
timestamp | timestamptz | When the event occurred |
Other
chart_notes
Dashboard annotations attached to specific dates. These appear as markers on time-series charts to provide context for data trends.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
note_date | date | Date the annotation is attached to |
content | text | Annotation text content |
show_on_chart | boolean | Whether to display this note on dashboard charts |
alerts
Configured alert rules that trigger notifications when specified conditions are met.
| Column | Type | Description |
|---|---|---|
website_id | uuid | Website identifier |
alert_type | text | Alert category: traffic_spike, traffic_drop, error_rate, uptime, goal |
name | text | Human-readable alert name |
conditions | jsonb | Alert trigger conditions as structured JSON |
status | text | Alert status: active, paused, triggered |
websites
Website configuration records. Each tracked website has an entry here with its settings and tracking code.
| Column | Type | Description |
|---|---|---|
id | uuid | Unique website identifier (used as website_id everywhere) |
domain | varchar | Website domain (e.g., example.com) |
name | varchar | Display name for the website |
is_active | boolean | Whether tracking is currently active |
tracking_code | varchar | Unique tracking code for the embed script |
timezone | varchar | Timezone for date aggregations (e.g., America/New_York) |
Example Queries
Core Analytics
SELECT page_url, COUNT(*) as visits, AVG(time_on_page) as avg_time
FROM visitors
WHERE website_id = 'YOUR_WEBSITE_ID'
AND visited_at >= date_trunc('month', now())
GROUP BY page_url
ORDER BY visits DESC
LIMIT 10;SELECT date, visitors, page_views, bounce_rate
FROM analytics_daily
WHERE website_id = 'YOUR_WEBSITE_ID'
AND date >= now() - interval '30 days'
ORDER BY date ASC;Revenue & Payments
SELECT marketing_channel, SUM(amount) as total_revenue, COUNT(*) as transactions
FROM payments
WHERE website_id = 'YOUR_WEBSITE_ID'
AND status = 'succeeded'
AND created_at >= date_trunc('month', now())
GROUP BY marketing_channel
ORDER BY total_revenue DESC;SELECT email, name, total_revenue, subscription_status, subscription_plan
FROM identified_users
WHERE website_id = 'YOUR_WEBSITE_ID'
ORDER BY total_revenue DESC
LIMIT 20;Goals & Funnels
SELECT utm_source, COUNT(*) as completions, SUM(completion_value) as total_value
FROM goal_completions
WHERE website_id = 'YOUR_WEBSITE_ID'
AND completed_at >= date_trunc('week', now())
GROUP BY utm_source
ORDER BY completions DESC;Errors & Performance
SELECT error_type, error_message, occurrence_count, user_count, severity, last_seen
FROM error_groups
WHERE website_id = 'YOUR_WEBSITE_ID'
AND status = 'open'
ORDER BY occurrence_count DESC
LIMIT 10;SELECT page_url,
ROUND(AVG(lcp_value), 0) as avg_lcp_ms,
ROUND(AVG(cls_value), 3) as avg_cls,
ROUND(AVG(inp_value), 0) as avg_inp_ms
FROM performance_metrics
WHERE website_id = 'YOUR_WEBSITE_ID'
AND recorded_at >= now() - interval '7 days'
GROUP BY page_url
ORDER BY avg_lcp_ms DESC
LIMIT 10;Uptime Monitoring
SELECT date, uptime_percentage, avg_response_time_ms, incidents_count
FROM uptime_daily
WHERE website_id = 'YOUR_WEBSITE_ID'
AND date >= now() - interval '30 days'
ORDER BY date ASC;User Behavior
SELECT page_url, frustration_type, COUNT(*) as occurrences
FROM frustration_events
WHERE website_id = 'YOUR_WEBSITE_ID'
AND timestamp >= now() - interval '7 days'
GROUP BY page_url, frustration_type
ORDER BY occurrences DESC
LIMIT 10;SELECT visitor_id, duration_ms / 1000 as duration_seconds, total_events, started_at
FROM replay_sessions
WHERE website_id = 'YOUR_WEBSITE_ID'
AND duration_ms > 120000
ORDER BY started_at DESC
LIMIT 20;B2B & Companies
SELECT c.name, c.industry, c.employee_count, v.total_visits, v.engagement_score, v.last_visit
FROM b2b_company_visits v
JOIN b2b_companies c ON c.id = v.company_id
WHERE v.website_id = 'YOUR_WEBSITE_ID'
ORDER BY v.engagement_score DESC
LIMIT 15;Marketing & Campaigns
SELECT utm_source, utm_campaign, SUM(visitors) as total_visitors,
SUM(conversions) as total_conversions, SUM(revenue) as total_revenue,
ROUND(AVG(bounce_rate), 3) as avg_bounce_rate
FROM campaign_performance
WHERE website_id = 'YOUR_WEBSITE_ID'
AND date >= now() - interval '30 days'
GROUP BY utm_source, utm_campaign
ORDER BY total_revenue DESC;SELECT query, SUM(clicks) as total_clicks, SUM(impressions) as total_impressions,
ROUND(AVG(ctr), 4) as avg_ctr, ROUND(AVG(position), 1) as avg_position
FROM gsc_keyword_data
WHERE website_id = 'YOUR_WEBSITE_ID'
AND date >= now() - interval '28 days'
GROUP BY query
ORDER BY total_clicks DESC
LIMIT 20;Custom Events
SELECT event_name, event_category, COUNT(*) as occurrences, SUM(revenue) as total_revenue
FROM custom_events
WHERE website_id = 'YOUR_WEBSITE_ID'
AND properties->>'source' IS NOT NULL
GROUP BY event_name, event_category
ORDER BY occurrences DESC
LIMIT 20;Other
SELECT note_date, content
FROM chart_notes
WHERE website_id = 'YOUR_WEBSITE_ID'
AND note_date >= date_trunc('month', now())
AND show_on_chart = true
ORDER BY note_date ASC;SELECT name, alert_type, status, conditions
FROM alerts
WHERE website_id = 'YOUR_WEBSITE_ID'
AND status = 'active'
ORDER BY name;