Skip to Content
StreamsEvents Warehouse

Event Warehouse

Write collected events to your data warehouse for long-term storage and analysis.

Overview

When a forwarding rule targets a warehouse source (BigQuery, Snowflake, Databricks), events are batched, serialized, uploaded to staging, and bulk-loaded into per-event-type tables. Every event carries its originating source identity, consent state, and is partitioned on its event timestamp for efficient time-range queries.

Configuration

  1. Navigate to Streams > Forwarding
  2. Click Create Forwarding Rule
  3. Select the event source and choose a warehouse source as the target
  4. Configure the warehouse settings:
    • Schema name (default: signalsmith_events) — target dataset/schema
    • Custom table name (optional) — override the auto-derived table name
    • Partition column (default: timestamp) — column used for day-partitioning/clustering
  5. Click Save

Table Naming

Zeotap creates one table per event type. The table name depends on whether the forwarding rule is scoped to a specific source and whether a custom table name is configured.

Event TypeSource PrefixTable Name
tracknonetracks
identifynoneidentifies
pagenonepages
screennonescreens
groupnonegroups
track”Web App”web_app_tracks
identify”Mobile App”mobile_app_identifies
purchase (custom)nonepurchases
app.install (custom)noneapp_installs

Source prefixes are derived from the event source (write key) name: lowercased, non-alphanumeric characters replaced with underscores, and truncated to a safe length. Custom event types are pluralized idempotently (names already ending in s are left alone).

To override the auto-naming, set Custom Table Name on the forwarding rule. This is useful when downstream consumers expect a specific table name.

Table Schema

Every event table has the same columns regardless of warehouse dialect:

ColumnTypeDescription
idstringMessage ID (unique per event)
workspace_idstringWorkspace identifier
write_key_idstringWhich event source sent this event
write_key_namestringHuman-readable source name for quick inspection
user_idstringIdentified user ID
anonymous_idstringAnonymous user ID
eventstringEvent name (for track)
propertiesJSON / VARIANTEvent properties
traitsJSON / VARIANTUser traits (for identify)
contextJSON / VARIANTEvent context (page, device, campaign, etc.)
timestamptimestampWhen the event occurred (client-provided)
received_attimestampWhen Zeotap received the event
sent_attimestampWhen the client sent the event
group_idstringGroup ID (for group events)
namestringPage/screen name
categorystringPage/screen category
server_ipstringClient IP address
consent_stringstringIAB TCF v2 consent string
us_privacystringIAB CCPA US Privacy string (e.g., 1YNN)
consent_categoriesJSON / VARIANTGranted consent categories as a JSON object

Partitioning and Clustering

New event tables are partitioned (or clustered, depending on the warehouse) on the timestamp column so time-range queries scan only the relevant partitions:

WarehouseStrategy
BigQueryDay-partitioned on timestamp via TimePartitioning
SnowflakeCLUSTER BY (timestamp) after table creation
DatabricksCLUSTER BY (timestamp) on Delta tables

You can override the partition/clustering column per forwarding rule by setting Partition Column in the rule config. This is useful when you have a custom event timestamp field that better reflects your query patterns.

Note: BigQuery cannot retroactively partition existing tables. If you need to change the partition column or enable partitioning on a pre-existing table, you must drop and recreate it.

Every event row carries structured consent context extracted from context.consent:

  • consent_string — IAB TCF v2 consent string or your own consent string
  • us_privacy — IAB CCPA US Privacy string
  • consent_categories — JSON object of granted categories (e.g., {"analytics": true, "marketing": false})

This lets you query consent-aware cohorts directly in SQL:

-- Count users who opted out of marketing SELECT COUNT(DISTINCT user_id) FROM web_app_tracks WHERE JSON_EXTRACT(consent_categories, '$.marketing') = false AND timestamp >= '2026-01-01';

Schema Evolution

  • The column list is fixed — new event properties are stored inside the properties JSON column
  • Query JSON columns using your warehouse’s JSON functions (JSON_EXTRACT, ->, ::variant)
  • Custom event types automatically get their own table on first event arrival

API Reference

See Events API for warehouse configuration endpoints.

Next Steps

Last updated on