Every derived table can be traced back to the raw export that still sits underneath it.

Raw GA4 exports often contain duplicate campaign labels, inconsistent channel names, and records that fail to join. We create a governed transformation layer that resolves those issues without modifying the raw exports beneath it. You end up with activation-ready tables with documented logic, measurable join quality, and the original raw data available for review.

A Zeo specialist moving raw data crates through an enrichment funnel into labeled jars

Some of the 500+ brands we've worked with

See all references
  • Pegasus Airlines
  • TransferGo
  • Canbebe
  • AVVA
  • Country Floors
  • Quick Sigorta
  • Amazon
  • BMW
  • Shell
  • Hyundai
  • PepsiCo
  • Red Bull
  • Decathlon
  • MediaMarkt
  • Bayer
  • Sanofi
  • EY
  • KPMG
  • GE
  • 3M
  • Domino’s
  • Lexus
  • Trendyol
  • Hepsiburada

We add a maintainable transformation layer while keeping the raw record available underneath. Four steps convert raw warehouse data into documented tables with visible quality controls.

How we hold ourselves to it

  • Preserve raw exports as the evidence layer — Transformations read from a separate raw layer without changing it, allowing anyone to compare normalized outputs with the original records.
  • Standardize repeated business labels — Campaign, channel, and product names follow consistent rules while retaining what each source originally recorded.
  • Measure every failed join — We calculate match rates and expose unmatched records rather than dropping them or assigning guessed values.
  • Date and version every rule — Each historical rule change receives a version and effective date so it does not silently rewrite previous periods.
  1. Profile the raw data

    We inspect actual values, nulls, distributions, and inconsistencies before defining transformation logic. The analyst confirms which anomalies matter.

    Data profile

    Illustrated figure examining a search result row through a large magnifier
  2. Specify the transformation rules

    We document normalization, join, and deduplication logic, including test cases for known edge conditions. Your data owner approves the join keys.

    Transformation specification

    Illustrated figure sketching plans at a drafting table
  3. Build and test

    We implement the approved rules and test them against known-good examples and boundary cases. The engineer reviews failed test cases before merge.

    Test results

    Illustrated figure feeding a data strip through a machine
  4. Release and monitor

    We deploy the transformations and add checks for schema or data drift that could break downstream tables. The on-call analyst approves the drift alert threshold.

    Monitoring setup

    Illustrated figure watching a monitor full of tracked rows

New structure sits on top. The raw data stays underneath, untouched.

Automation profiles the export, flags null spikes and label variants, drafts the join and normalization SQL, runs it against boundary-case fixtures, and watches for schema drift after each run. The calls that shape the data stay human: which anomaly matters, which join key is legitimate, and what a failed test means before anything merges.

You receive usable tables and maintainable documentation rather than an opaque query.

  • A transformation specification beside a row of data dictionary cards

    Technical specification

    Transformation specification

    Versioned documentation of the exact normalization, join, and deduplication rules.

  • A transformation specification beside a row of data dictionary cards

    Working document

    Activation-ready tables

    Clean, joined tables prepared for dashboards, models, or downstream activation.

  • A transformation specification beside a row of data dictionary cards

    Reference document

    Data dictionary

    Definitions and source lineage for each derived field so future analysts do not need to reverse-engineer the logic.

We call it done when: join match rates are measured and documented, unmatched records have a stated disposition, and the raw layer is still queryable.

Landed exports that still don't agree on labels are usually the first sign this needs to happen.

A good fit when

  • Your GA4 or other exports have landed in the warehouse, but campaign, channel, or product labels are inconsistent across sources.
  • You need joined, activation-ready tables for a dashboard, model, or downstream tool, well beyond raw event exports on their own.
  • Existing transformation logic is scattered across spreadsheets or undocumented queries that nobody fully trusts.

Better handled as other work when

  • You need the GA4 export connection built before any warehouse transformation rules are written or tested. That is GA4 Integrations & Data Activation.
  • You need server-side collection routing rather than warehouse-level transformation. That is Server-Side GTM & Cloud Setup.

If one of these is closer to your situation, start here instead: All Analytics Engineering & Data Activation tasks

We call it done when: the raw data is profiled and the data owner has approved the join keys, so the rules are written against what the export actually contains.

  • BigQuery

    holds the untouched raw export the page's whole approach depends on leaving alone

  • dbt

    where the transformation rules get built as tested, version-controlled models, not one-off scripts

Show us the raw data and what the resulting tables need to support. We will design transformations that clean and structure it without obscuring the original record.
Plan data transformation

Will this touch our raw exported data?

No. The transformation layer reads from raw exports without modifying them, so the original evidence remains available if a result needs investigation.

What happens to records that can't be matched or joined?

We measure and flag them rather than silently dropping them. You'll see how much of your data doesn't join cleanly, and why, so you can decide whether that's acceptable.

Can this fix bad source data?

It can normalize inconsistent labels and structure the data usefully, but it can't invent data that was never collected. If the real problem is in collection, that's a separate task.

What warehouse access does this need?

Access to your warehouse (typically BigQuery) where the raw exports land, and clarity on what the activation-ready tables need to support.