nod.

Reading the attribution dashboard

What each surface shows, how drilling and the model switcher work, and the conventions behind the numbers.

Updated July 31, 2026

The active method is shown on the report. A workspace promoted to nod. Mix V3 reads one shared score across the dashboard, agent and browser extension. Older workspaces keep the V2 surfaces until their controlled promotion. The version is not a browser setting.

The four surfaces

Matrix. One model at a time, one row per channel. Columns: credited revenue, credited conversions, orders, refunds, share of revenue. This is the fastest read when you just want "how much came from Meta this month." Revenue here is gross — refunds are broken out in their own column, not subtracted.

Comparison. Every model side by side for the same entity: first click, last click, U-shape, nod. Mix, data-driven and Unique participation. Comparison models use observed conversion truth only. Eligible verified exposure belongs only to nod. Mix V3, so a comparison never quietly gives another model a different evidence pool.

Deep Dive. Under nod. Mix V3, each released entity shows Created, Intent captured, Final closed, Captured, nod. Mix credit, Observed and Verified, plus a Value column. Created + Intent captured + Final closed conserves the released total (nod. Mix credit). A restricted cell says Withheld; it does not render as 0. Value instead reads no value when the outcome carries no monetary field at all (leads), no currency when the money exists but the currency on those conversions could not be read, or Withheld when privacy suppression applied to the whole cell. A Legend toggle under the table spells out every column in one sentence each, and each header carries the same sentence as a tooltip.

Cross-channel. A flat list of every campaign, ad set, or ad across all channels at once — nothing nested under a channel. If a campaign name happens to exist on two channels, cross-channel merges them into one row and shows you which channels it spans, rather than showing two separate rows with the same name. It's the view for "what are my top 10 campaigns, period," not "what are my top Meta campaigns."

The evidence cards show observed share, verified share, unattributed share, verified-feed state, active-engagement state, data-through date and method revision. A delayed feed marks the result provisional. A missing feed marks verified exposure unavailable and leaves the observed score intact.

Order Journey. This is an observed sequence, not a reconstruction of everything a platform may have seen. It distinguishes active seconds from wall-clock duration, shows explicit milestone links and the V3 role each eligible touch earned. Aggregate-only or internal-only provider evidence is never exposed as an order-level match. Heuristic modeled context stays outside the observed timeline.

Search Demand is a separate context surface

Search Demand sits beside the attribution views, but it is not a sixth attribution model. It reads aggregate Google Search Console data: organic clicks, impressions, Brand, Non-brand and Unknown demand, plus privacy-safe query and landing-page breakdowns. Its dates stay in Google's Pacific Time source calendar (America/Los_Angeles).

Search Console has no visitor, session, order or conversion identifier. Search Demand therefore never adds a touchpoint to a customer journey and never receives conversion credit. Brand Search growth after paid activity is an association signal, not causal proof. Use it to form a hypothesis, then use a controlled test when the decision depends on causality.

Order conventions differ by column, not by surface

Two numbers that look similar mean different things:

ColumnWhat it countsConvention
OrdersWhole ordersEach order counts once, credited entirely to its last touch's channel — the conventional "order of record." Sums to your true order total.
Credited conversionsFractional creditSplit across eligible evidence under the selected model. Under nod. Mix V3 the three role components conserve 1.0 per released conversion.

So "Orders: 40" next to "Credited conversions: 40.0" for the same channel only lines up under last-click; under any multi-touch model they diverge on purpose. Neither number is wrong — they're answering different questions ("who gets the order of record" vs. "who gets the credit").

Drilling: channel → campaign → ad set → ad

The drill ladder depends on the channel, not a fixed hierarchy:

  • Meta, Google, TikTok, Snapchat, Microsoft (paid channels): channel → campaign → ad set → ad. Google appears as up to three rows — Google Brand, Google Generic, and a plain Google row for campaigns the brand-term matcher can't classify — each with its own drill.
  • ChatGPT Ads: channel → campaign → ad set → ad on the pixel basis, but campaign is where the spend ends. OpenAI expands {ad_group_id} and {ad_id} at click time, so once the Tracking page's string is live the Ad set and Ad rows resolve to real entities and carry attributed conversions. The Advertiser API reports delivery at campaign level only, so those rows show a dashed cost, CPA and ROAS rather than a guessed split, and the platform basis stays empty below campaign. OpenAI syncs no ad-group or ad names either, so those rows label by raw id. Spend, impressions and clicks come from OpenAI; revenue and conversions come only from your nod. pixel, because the platform reports none.
  • Email: channel → campaign → flow. There's no ad-level chip for email.
  • Everything else (organic search, organic social, referral, direct, AI search): channel → campaign, which is the leaf — no further drill.

Clicking a level chip from a shallower scope (a "jump") aggregates same-named entities across whatever level you skipped. Drilling into a fully-scoped parent instead keeps one row per object. When a rolled-up row spans several objects with no single joinable cost path, cost shows as a dash rather than a guessed number — nod. doesn't fabricate cost.

The model switcher re-queries, it doesn't relabel

The server resolves the active immutable config revision and stable data revisions before scoring. Switching a comparison model changes the model input, not the active method version. Editing attribution settings creates a new revision; it must pass validation before promotion. Brand-term changes also require Search Console reclassification to complete before the revision can become active.

One honest caveat: data-driven is a placeholder today. It always falls back to U-shape credit and is badged as such in the UI, regardless of how much conversion volume you have. Don't read a "data-driven" column as a live Markov model yet — see the models article for the full breakdown.

Currency and timezone labels

Every day boundary on the dashboard — including "today," "yesterday," and the series x-axis — is computed in your shop's timezone, not UTC, so daily totals reconcile with your Shopify admin rather than a UTC calendar. The zone is read from your Shopify connection; if it can't be resolved, nod. falls back to Europe/Berlin. Currency labels are normalized to a valid 3-letter code; a malformed value falls back to your store's currency rather than showing garbage.

A few things worth knowing before you dig in

  • The matrix shows gross revenue (refunds broken out, not netted). Deep dive and cross-channel show both gross and net (gross minus the credited refund share). If you're reconciling matrix against deep dive, this is the reason they won't match to the cent — see "Why your numbers differ" for more.
  • Unattributed is a real, visible bucket for orders that never stitched to a touch. nod. doesn't redistribute that revenue into other channels.
  • ROAS costs come only from synced Meta and Google spend today. Ad-level cost and any other channel's cost resolve to a dash rather than a fabricated figure.