Warehouse export
Every raw event, in your own warehouse. Not a report, not an aggregate — the same rows we process, in a stable schema you can join with your orders table.
Available on the Growth plan and above.
Why you'd want it
No lock-in. If you leave us tomorrow, your historical data is already yours.
Questions we don't answer. Blended ROAS across channels, cohort retention curves, first-touch vs last-touch comparisons — anything you can write SQL for.
One join away from real LTV. order_id and profile_id line up with your own tables, so you can connect ad spend to margin instead of revenue.
Pick a target
| Target | Good for |
|---|---|
| Webhook | you already have an ingestion endpoint; simplest to try |
| S3 / Cloudflare R2 | cheap archival, query later with Athena or DuckDB |
| BigQuery | you already live in GCP; rows queryable within seconds |
| Snowflake | you already live in Snowflake |
Configure it under Websites → your site → Destinations → Warehouse Export. See also Destinations.
How delivery works
Events are buffered at the edge and delivered in batches — nothing is added to the request path, so collection speed is unchanged. If your warehouse is down the rows wait and are retried; after repeated failures they're marked and kept so you can investigate, never silently dropped.
| Target | Sends when |
|---|---|
| Webhook | 100 rows, or 60 seconds |
| BigQuery / Snowflake | 200 rows, or 60 seconds |
| S3 / R2 | 5,000 rows, or 15 minutes |
S3 waits longer on purpose: one object per minute would leave you with thousands of tiny files.
Each batch shows up on the Delivery page as a warehouse row.
Personal data is off by default
By default you get the event plus pseudonymous and hashed identifiers — enough to join on profile_id and order_id, without clear-text personal data sitting in the pipe.
Turn on Include personal data and email and phone are exported in clear text — your own first-party data — but still only for events that carry consent. On a US opt-out (GPC) they are never exported, whatever the toggle says. IP address and user agent are never exported.
The schema is a contract
Every row carries _srf_schema_version. Within a version, fields are added, never renamed or removed — your queries won't break under you. A breaking change ships as a new version, announced.
Key columns: event_id, event_name, event_time, profile_id, order_id, value, currency, items_json, consent, click_ids_json, email_sha256, geo_country.
The full field list, the CREATE TABLE statements for BigQuery and Snowflake, and the webhook signature verification snippet are in the setup guide your account manager can send you — or ask at [email protected].
Verifying a webhook
Every request carries X-SRF-Signature: v1=<hmac> and X-SRF-Timestamp. The signature is HMAC-SHA256 of timestamp + "." + body with your secret. Verify it, and reject timestamps older than 5 minutes so a captured request can't be replayed at you.