GA4Google AdsMetaTikTokIntermediateGuide

The Agency Reporting Stack in 2026: What to Use and Why

A client report in 2026 has four kinds of columns: what the platforms claim, what the warehouse observed, what customers said, and what an experiment proved. Each comes from a different tool category, moves on a different cadence, and answers a different question. The categories, what belongs in weekly versus monthly, the one-number-per-source rule that keeps the report honest, and where an agent layer like Orbit fits without replacing any of it.

Updated September 29, 202615 min read

the reporting problem at agencies is not a tooling gap. it is a column problem. a weekly deck shows meta's purchases next to ga4's purchases next to shopify's orders, calls all three "conversions," and lets the client pick the one they like. this guide is about which tools produce which columns, which columns belong in which report, and the one rule that keeps them from being blended into a number nobody can defend.


what a reporting stack actually is

a reporting stack is the set of systems that move a number from where it was created to where a client reads it, without changing what the number means on the way. it has four kinds of columns, and every reporting tool falls into one of the categories that produces them:

column typequestion it answersproduced bycadence
platform-reportedwhat does the platform claim it drovegoogle ads, meta, tiktok, linkedin apis, through a connectordaily
observedwhat did our own systems see happenga4, product analytics, shopify or stripe, a warehousedaily
statedwhat did customers say caused the purchasepost-purchase surveys (fairing, knocommerce, and similar)weekly to monthly
provenwhat would not have happened without the spendgeo holdouts, conversion lift, mmm (haus, measured, platform lift tools)monthly to quarterly

what most guides get wrong is treating these as competing sources of one truth. they are four different truths. platform-reported numbers are what the platform's model attributed within its window and its modeling. observed numbers are what happened on your properties, attributed by your analytics model. stated numbers are memory and perception. proven numbers are causal, and they are the only ones that answer "should we spend more."

the tool categories map onto the columns:

  • connectors (supermetrics, funnel, fivetran, improvado, windsor, airbyte) move platform-reported and observed data into a destination. they do not create truth; they preserve it.
  • warehouse (bigquery, snowflake, postgres) stores every column with its source and settings attached, so history survives platform reprocessing and tool changes.
  • bi (looker studio, power bi, metabase, tableau) renders. it should never compute a metric the warehouse cannot reproduce.
  • attribution vendors (northbeam, triple whale, hyros, rockerbox) produce a fifth column, modeled multi-touch, built from their own tracking. useful, but it is a model, not an observation, and it needs the same label as everything else.
  • survey tools produce the stated column.
  • incrementality tools produce the proven column.
  • an agent layer reads across all of them, applies checks, and writes the narrative. it is not a source.

the fundamental shift: from one dashboard to labeled columns

before: a connector pulled every platform into one looker studio dashboard. "conversions" was a summed field. attribution settings lived inside each platform and nobody wrote them down. the monthly report was the dashboard with commentary.

after: three things changed the columns.

first, the platform-reported column drifted from observed reality by an amount that varies by platform, by campaign type, and by quarter. haus analyzed 640 meta incrementality experiments on brands averaging $14 million in annual meta spend and found that for every $100 in platform-attributed dtc revenue on a 7-day click window meta generated $115 in incremental revenue on average, while advantage+ over-reported by 12 percentage points relative to manual campaigns and 58% of brands saw higher incremental roas on manual (haus, the meta report, july 2025). in july 2026 haus re-ran its incremental attribution comparison and found the relationship had flipped: incremental attribution now beats standard attribution by a pooled geo-mean of 1.26x, versus 0.80x in the prior year (haus, july 2026). the same platform column meant different things twelve months apart.

second, the observed column stopped being one number. ga4's attribution model applies to event-scoped dimensions only, session reports are session attribution, and since january 2026 the model and lookback are set per key event. the ga4 attribution guide has the detail. an "observed" purchase count without the model and scope attached is not a defined number.

third, the client's own finance number arrived in the room. stripe or shopify revenue after refunds and cancellations is now on the same page as platform roas. the moment a client sees platform-attributed revenue exceed collected revenue, every other column loses credibility unless it was labeled.

the shift is from "one dashboard" to "labeled columns, each with its source, its attribution setting, and its date." the tools did not change much. the discipline did.


what this broke in existing accounts

1. the blended conversions field

a summed "conversions" across platforms double counts every purchase that touched two platforms, and each platform's count already includes modeled conversions. a client who compares that sum to shopify orders finds the agency reporting more sales than happened.

2. roas columns with three different windows

meta on 7-day click and 1-day view, google ads on a 30-day click conversion window with data-driven attribution, tiktok on its own defaults. the same $50,000 of spend produces three roas numbers built on three definitions, presented in one column.

3. connectors that silently backfilled

platforms restate conversions for days after the fact (ga4 reattributes for up to 7 days; meta and google both backfill modeled conversions). a connector that overwrites yesterday's row with today's restatement makes last week's report unreproducible. without a warehouse keeping the version the client saw, the agency cannot explain why the number moved.

4. survey columns read as attribution

post-purchase surveys are stated data with a response rate. in practice response rates run 25 to 45% across categories, and a channel needs on the order of 100 responses per period before its share is stable (hyros, survey versus tracked attribution, 2026). vendors report higher completion on single-question surveys, with fairing citing north of 70% for its customers; those are vendor claims without published methodology and should be treated as such. a survey share for a channel with 12 responses is not a data point.

5. the incrementality result that never made it into the report

a geo holdout ran in q1 and showed meta retargeting at a fraction of its reported roas. the weekly report kept showing platform roas because the connector feeds the dashboard and the experiment lived in a slide deck. the proven column existed and never touched the report.

6. the agency's data strategy owned by nobody

supermetrics surveyed 435 marketing leaders and contributors across brand, agency, and ecommerce teams between october and december 2025: 52% said an external team defines their data strategy and measurement, 44% report access to high-quality data, 45% are still struggling with measurement, and 40% name proving roi across channels as their biggest challenge (supermetrics, the 2026 marketing data report). the external team is often the agency. when the agency's own stack has no column discipline, the client inherits it.


the data

  • 640 meta incrementality experiments, brands averaging $14 million annual meta spend, published july 28, 2025: 19% average lift to the primary kpi; $115 incremental per $100 platform-attributed dtc revenue on 7-day click; advantage+ over-reporting by 12 points versus manual; 58% of brands with higher incremental roas on manual. (haus, the meta report.)
  • meta incremental attribution versus standard attribution: pooled geo-mean 0.80x for july 2024 through june 2025; 1.26x for experiments since july 2025; dtc-only brands 1.38x, omnichannel 1.02x. (haus, july 2026.)
  • 601 hyros implementations reviewed by checkthat.ai in 2026: tracked attribution surfaced 29 to 33% more conversions than native platform reporting. vendor-adjacent, useful as a magnitude for how much a modeled column can differ from a platform column. (hyros, 2026.)
  • post-purchase survey response rates: 25 to 45% in practice; roughly 100 responses per channel per period for stability. (hyros, 2026.) fairing claims 70%+ completion for its customers and, for its advanced attribution beta launched september 10, 2026, "up to 50% more usable attribution signal from the same order volume," with no published methodology (ppc land, september 2026).
  • 435 marketers surveyed october to december 2025: 44% with access to high-quality data; 52% with data strategy defined externally; 45% still struggling with measurement; 35% using ai for reporting and analytics versus 50% for content. (supermetrics, 2026 marketing data report.)
  • google ads records conversions on the click date, ga4 on the event date, and google ads applies modeling on top of the observed conversions ga4 exports. (google analytics and google ads documentation, summarized in the ga4 attribution guide.)

no public dataset measures how often agency reports blend columns. the haus and hyros numbers are the size of the error when they do.


what changed in 2026 specifically

ga4, january 16, 2026: per-conversion attribution settings and a conversion attribution analysis report. the observed column can now differ per key event within one property. a report must state the setting per key event.

ga4, august 11, 2026: integer lookback windows. the observed column's window is now a free parameter, which makes labeling it mandatory.

google ads, august 17, 2026: budget-limited target campaigns deliver to target. platform cpa and roas moved without any spend change. a report that did not carry the target as a column could not explain the move. see the bidding guide.

meta, through 2026: incremental attribution flipped from under-performing to out-performing standard attribution in haus's data. a report that fixed its meta column definition in 2025 is describing a different setting now.

tooling: connectors added warehouse-native destinations and ai summaries. useful, and irrelevant to the column problem. an ai summary of blended columns is a faster wrong answer.


what actually works now

1. adopt the one-number-per-source rule

every metric in a client report carries exactly one source, one attribution setting, and one window, in the column header. "meta purchases (meta, 7d click 1d view)" and "purchases (ga4, dda, 45d)" and "orders (shopify, net of refunds)" can sit side by side. "conversions" cannot. never sum across sources. if a client wants a blended efficiency number, it is marketing efficiency ratio: total collected revenue divided by total spend, and it carries the revenue source in its name.

2. put a warehouse under the connector, even a small one

bigquery is enough. store each day's platform pull as an immutable row with a pulled-at timestamp. when a platform restates, append, do not overwrite. every report can then be reproduced as of the date the client saw it. this is the difference between "the number changed" and "meta restated 6% on the 4th, here is both."

3. split weekly from monthly by column type

weekly: platform-reported spend, results, and efficiency per platform against plan; pacing; tracking health (pixel, capi, key events firing, ga4 versus platform gaps); creative fatigue; the open decisions. all daily-cadence columns, all labeled. no blended roas.

monthly: collected revenue from the payment system or shopify; marketing efficiency ratio and blended cac from that revenue; the stated column (survey channel mix, with response count); the proven column (any incrementality readout, with its test window); cohort payback where the business is subscription. monthly is where budgets get argued, so monthly is where the proven and stated columns belong.

4. give the survey column a floor

publish the response count next to every survey share. below 100 responses for a channel in the period, show the share in grey or not at all. compare survey share to platform share and observed share in one table, quarterly, and treat a gap above 10 points as a question, not a conclusion.

5. feed incrementality results back into the platform column

when a holdout produces an incrementality factor for a channel or campaign type, store it in the warehouse with its test dates and apply it as a labeled column, "meta retargeting, platform-reported x 0.6 (haus geo test, q1 2026)." the proven column is only useful if it changes what the weekly report shows. the incrementality guide covers the test design.

6. state what the number is measured against

a cpa without a target is a fact, not a finding. every efficiency metric in the report is shown next to the goal it is measured against, and when no goal exists the report says so instead of calling the number good or bad.

7. put an agent on top, not in place of

an agent layer is good at exactly the discipline above: reading every source through its api, labeling each number with its source and settings, checking gaps between columns, flagging a tracking break versus a pacing move, and writing the monday narrative from the numbers rather than from memory. orbit does this through orbit-mcp, which reads google ads, meta, tiktok, ga4, and stripe live, plus posthog and semrush through proxies, and runs the agent tasks embedded in guides like this one against the account. what orbit is not: a warehouse, a connector, a survey tool, or an incrementality platform. it reads live apis; it does not store your history or run your holdouts. keep the warehouse for history, keep the survey and lift tools for the stated and proven columns, and use the agent to enforce the labeling and do the reading. the honest description is an analyst who never blends columns, not a replacement for the stack.


what to stop doing immediately

  • stop summing conversions across platforms.
  • stop presenting roas columns with different windows under one header.
  • stop overwriting yesterday's platform pull with today's restatement.
  • stop showing a survey channel share without its response count.
  • stop keeping incrementality results in a deck instead of in the report.
  • stop showing efficiency metrics without the goal they are measured against.
  • stop letting the bi layer compute metrics the warehouse cannot reproduce.
  • stop describing any agent, including orbit, as a source of truth. it is a reader.

the orbit agent instructions

{
  "guide": "agency-reporting-stack",
  "agent_tasks": {
    "audit_report_column_provenance": {
      "check": "for every metric in the brand's weekly and monthly reports, identify its source system, attribution model or window, and whether it is platform-reported, observed, stated, proven, or modeled",
      "flag": "any metric summed across sources, any conversions or roas column without a stated window and model, or any header that does not name the source",
      "recommend": "rename the column with source, model, and window, split blended columns into one per source, and replace blended roas with marketing efficiency ratio on collected revenue"
    },
    "reconcile_platform_claims_to_revenue": {
      "check": "for the trailing 30 days, sum platform-attributed revenue across google ads, meta, and tiktok and compare it to collected revenue from stripe or the order system, then compare each platform's attributed conversions to ga4 key events for the same period",
      "flag": "platform-attributed revenue above 100% of collected revenue, or any platform whose attributed conversions exceed ga4 key events for its channel by more than 50%",
      "recommend": "present the ratios per platform as the reporting factor, label the platform column as claimed, and use collected revenue for any blended efficiency number"
    },
    "audit_attribution_settings_consistency": {
      "check": "read the attribution window and model in each ad platform's conversion settings and the ga4 reporting and per-key-event attribution settings, and compare them to what the report headers state",
      "flag": "any header whose stated window or model does not match the live setting, or a change to any of those settings in the last 30 days not reflected in the report",
      "recommend": "update the headers, note the change date in the report, and hold period-over-period comparisons across the change"
    },
    "monitor_survey_response_floor": {
      "check": "where a post-purchase survey is connected or its export is available, count responses per channel for the reporting period and compare survey share to platform share and ga4 share per channel",
      "flag": "any channel share reported from fewer than 100 responses, or a survey-versus-observed gap above 10 points on a channel with 100 or more responses",
      "recommend": "suppress or grey out shares below the floor, and open a reconciliation question rather than a budget change for gaps above 10 points"
    },
    "audit_incrementality_calibration_freshness": {
      "check": "list any stored incrementality factors per channel or campaign type with their test dates and the platform columns they are applied to",
      "flag": "a factor older than two quarters still applied, a channel above 20% of spend with no factor at all, or a factor not applied in the weekly report",
      "recommend": "schedule a holdout for the uncovered or stale channel and apply the current factor as a labeled column next to the platform-reported number"
    },
    "monitor_source_freshness_and_restatements": {
      "check": "for each source feeding the report, read the last successful pull time and compare the last 7 days of stored values against a fresh pull",
      "flag": "any source not refreshed in 36 hours, or any day whose conversions or revenue restated by more than 5%",
      "recommend": "note the restatement in the report with both values and the date, and keep the earlier value in the warehouse rather than overwriting it"
    }
  }
}

the bottom line

a report has four kinds of columns: claimed, observed, stated, proven. each comes from its own tool category, on its own cadence, with its own definition. one number per source, labeled with its model and window, never summed across sources. weekly for the daily columns and the decisions, monthly for revenue, surveys, and experiments.

the tools are fine. the discipline is the product. an agent can enforce the discipline every week, and that is the honest place for one.


built by orbit - the performance marketing intelligence layer. questions? jose@orbitllm.com