Skip to content

paid-media: add optional measurement-run fieldgroup for identity-based measurement summary outputs - #2234

Open
fenghao-chen wants to merge 1 commit into
adobe:masterfrom
fenghao-chen:feature-2233-paid-media-measurement-run
Open

paid-media: add optional measurement-run fieldgroup for identity-based measurement summary outputs#2234
fenghao-chen wants to merge 1 commit into
adobe:masterfrom
fenghao-chen:feature-2233-paid-media-measurement-run

Conversation

@fenghao-chen

@fenghao-chen fenghao-chen commented Aug 12, 2026

Copy link
Copy Markdown

Summary

Adds a new optional fieldgroup core-paid-media-measurement-run and references it from the paid-media-summary-metrics composite schema. The fieldgroup carries run-level context that identity-based paid-media measurement pipelines (clean-room measurement, first-party attribution, third-party measurement partners) stamp onto each summary row and that does not fit the existing paid-media fieldgroups.

Fixes #2233

Motivation

Identity-based paid-media measurement — where impressions and conversions are joined across a shared identity space (hashed email, hashed IP, device id, ECID, …), aggregated across breakout dims, and written out as pre-rolled summary rows for CJA / analytics ingestion — is a common pattern across clean-room measurement, first-party attribution pipelines, and third-party measurement partners.

These pipelines need to stamp each summary row with seven fields that don't fit the existing paid-media fieldgroups:

  • moduleID — identifier of the measurement module / report that produced this run; constant across every row of a single run so a row can be traced back to its originating pipeline execution.
  • matchRate — identity match rate (fraction of source conversions that identity-joined at least one impression across the shared identity space, ignoring time windows). Meaningful only at the whole-input rollup grain. Conceptually distinct from attributionMetrics.attributionConfidence (a per-touchpoint credibility score under a multi-touch model).
  • groupedConversions — attributed conversions deduplicated by resolved household or identity group. Complements paidMedia.metrics.conversions (per-conversion count) with a household/group-level count at the same rollup grain.
  • conversionEventType — type of the source conversion event (e.g. retail.purchase, signup), carried through verbatim from the upstream conversion source. Customer-defined vocabulary; no fixed set. Used to slice conversion breakouts in a summary output; no existing string dimension for conversion event type in core-paid-media-dimensional-breakdowns.
  • audienceName / placementName / siteName — human-readable display names for the audience segment, placement, and site associated with the row. dimensionalBreakdowns.audienceSegment and dimensionalBreakdowns.placement carry the IDs but the summary dataset (unlike campaign / ad / account) has no corresponding lookup dataset for these dims, and denormalizedNames today only covers entity names that mirror the paid-media lookups. siteName has no ID form at all (open publisher domain).

Producers today have no global place to put these fields. Downstream consumers that want to ingest such a summary output into AEP have to define these as tenant-specific field groups per sandbox, which prevents cross-sandbox and cross-customer productization on a single global schema.

This change introduces an optional fieldgroup, following the exact shape and precedent of core-paid-media-denormalized-names (#2187 / #2188):

  • Producers that don't emit measurement-run context (e.g. classical DSP metric feeds) leave xdm:paidMedia.xdm:measurementRun.* null — no regression, no bloat, no impact on existing summary-metrics consumers.
  • Identity-based measurement producers populate the block inline and ingest onto the same global schema.

Changes

  • New: components/fieldgroups/paid-media/core-paid-media-measurement-run.schema.json — the fieldgroup. meta:status: experimental, meta:intendedToExtend: [summarymetrics], all properties under xdm:paidMedia.xdm:measurementRun.
  • New: components/fieldgroups/paid-media/core-paid-media-measurement-run.example.1.json — fieldgroup example.
  • New: schemas/paid-media/paid-media-summary-metrics.example.9.json — composite-schema example exercising the new fields end-to-end on a realistic identity-attribution row.
  • Modified: schemas/paid-media/paid-media-summary-metrics.schema.json — one $ref added to allOf for the new fieldgroup.

Validation

  • npm test — 2413 passing (was 2412 on master; +1 for the new example.9).
  • npm run lint — clean (prettier did not reformat any of the new/modified files).
  • npm run validate — no new failures on the added/modified files; pre-existing failures in unrelated schemas remain.
  • npm run incompatibility-check — clean.

Breaking changes

None. The new fieldgroup adds optional properties only; no existing field is renamed, retyped, or removed. paid-media-summary-metrics.schema.json only gains one additional $ref in allOf — every previously valid example still validates.

…d measurement summary outputs

Adds a new optional fieldgroup 'core-paid-media-measurement-run' and
references it from the 'paid-media-summary-metrics' composite schema.

The fieldgroup carries run-level context that identity-based
paid-media measurement pipelines (clean-room measurement, first-party
attribution, third-party measurement partners) stamp onto each
summary row and that does not fit the existing paid-media fieldgroups:

  - moduleID           : identifier of the measurement module/report
                         that produced this run
  - matchRate          : identity match rate over the whole input
  - groupedConversions : household/identity-group-deduped conversion
                         count at the row's rollup grain
  - conversionEventType: type of the source conversion event (open
                         string, customer-defined vocabulary)
  - audienceName       : display name of the audience segment
  - placementName      : display name of the placement
  - siteName           : publisher site/domain

Producers that do not emit measurement-run context leave the block
null; no regression, no impact on existing summary-metrics consumers.

Fixes adobe#2233
@ejsuncy

ejsuncy commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

One correction to the above PR description:

Fieldgroup is marked meta:status: experimental, consistent with the rest of the paid-media schemas

This likely an AI agent copying from previous PRs where the schemas were experimental. But today the paid media schemas are all marked stable. It's fine to add this new fieldgroup as experimental, and it can be transitioned to stable once it's been tested.

"title": "Identity Match Rate",
"description": "Fraction of source conversions that identity-joined at least one impression across the fixed match-key set, ignoring time windows. Typically populated only on the whole-input rollup grain and left null on lower-grain rows where a single ratio is not meaningful. Expressed as a fraction in [0, 1].",
"minimum": 0,
"maximum": 1

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just double checking that this could never exceed 1.0. We had another issue where I assumed a rate could never exceed 1.0 but in practice it did, and we had to deprecate the field and add another where there was no maximum set.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good check. I gave it some thoughts, in this case, the matched impressions will always be a subset of total impressions, so I think it's safe to cap it to 1.0

"maximum": 1
},
"xdm:groupedConversions": {
"type": "number",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this could ever be a really large number (>2B), you might want to set a maximum value like we do here to force a larger datatype resolution on the backend. But if this is a count of households/identity group that sounds unlikely to need a large number.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Realistically 2B cap is a a safe number for household/identity group

@fenghao-chen

Copy link
Copy Markdown
Author

One correction to the above PR description:

Fieldgroup is marked meta:status: experimental, consistent with the rest of the paid-media schemas

This likely an AI agent copying from previous PRs where the schemas were experimental. But today the paid media schemas are all marked stable. It's fine to add this new fieldgroup as experimental, and it can be transitioned to stable once it's been tested.

Good catch. Updated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

paid-media: add optional measurement-run fieldgroup for identity-based measurement summary outputs

2 participants