Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .changeset/measurement-audit-cleanups.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
"adcontextprotocol": minor
---

Three small cleanups from the measurement schema audit (closes audit findings §3.8 and §3.10; finishes the prose-side work for #3863).

**§3.8 — `attribution-window` dedup.** `optimization-goal.json` previously inlined a partial `attribution_window` shape with `post_click` and `post_view` but no `model`, with `post_click` required. The canonical `core/attribution-window.json` has `post_click`, `post_view`, and `model` with `model` required. Two surfaces describing the same concept with conflicting constraints. Fix:

- `optimization-goal.json` `attribution_window` collapses to `$ref attribution-window.json` so there's one canonical shape.
- `attribution-window.json` `model` becomes optional (was required). Absence means the seller's default attribution model applies (typically `last_touch` per industry convention). Sellers SHOULD populate `model` when committing to a specific methodology. Buyers reading delivery reports get the seller's choice when set; fall back to default when not.

**§3.10 — `dooh_metrics.calculation_notes` description tightening.** Previously a one-liner ("Explanation of how DOOH impressions were calculated") that read like a primary methodology surface. Tightened to clarify it's for **row-specific supplementary context** (a particular daypart's calculation, a venue-mix exception) — the canonical methodology declaration belongs on the measurement vendor's `get_adcp_capabilities.measurement.metrics[]` block where it's discoverable once and inherited across delivery rows. Doesn't deprecate the field — DOOH methodology genuinely has row-level exceptions worth carrying inline.

**#3863 — `forecastable-metric.json` description drift fix.** The description previously claimed `audience_size`, `measured_impressions`, `grps`, `reach`, `frequency` were forecast-only deltas. **Wrong:** `grps`, `reach`, `frequency` are also in `available-metric.json` (have been since their introduction). The actual forecast-only deltas are `audience_size` and `measured_impressions`. Description corrected. Closes the prose-cross-reference half of #3863; the schema-level enforcement of overlap (build-script work, not schema work) is deferred.

**Backwards compatibility.** All three changes are additive or relax existing constraints (the `attribution-window.model` requirement relaxation makes previously-failing payloads valid; previously-valid payloads remain valid). No breaking changes.

Closes audit findings §3.8 and §3.10. Substantially closes #3863 (prose cross-references); build-script overlap enforcement deferred to a follow-up.
5 changes: 2 additions & 3 deletions static/schemas/source/core/attribution-window.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "/schemas/core/attribution-window.json",
"title": "Attribution Window",
"description": "Describes the attribution methodology and lookback windows used for conversion measurement. Enables cross-platform comparison by making attribution methodology transparent.",
"description": "Describes the attribution methodology and lookback windows used for conversion measurement. Enables cross-platform comparison by making attribution methodology transparent. Used as a `$ref` from `optimization-goal.json` (buyer's optimization-time attribution choice), `get-media-buy-delivery-response.json` (seller-declared attribution methodology in delivery reports), and similar surfaces. All fields are optional individually but at least one of `post_click`, `post_view`, or `model` SHOULD be populated; absence of `model` means the seller's default attribution model applies (typically `last_touch` per industry convention) — sellers SHOULD populate `model` explicitly when committing to a specific methodology.",
"type": "object",
"properties": {
"post_click": {
Expand All @@ -15,9 +15,8 @@
},
"model": {
"$ref": "/schemas/enums/attribution-model.json",
"description": "Attribution model used to assign credit when multiple touchpoints exist"
"description": "Attribution model used to assign credit when multiple touchpoints exist. SHOULD be populated when committing to a specific model; when absent, the seller's default applies."
}
},
"required": ["model"],
"additionalProperties": true
}
2 changes: 1 addition & 1 deletion static/schemas/source/core/delivery-metrics.json
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@
},
"calculation_notes": {
"type": "string",
"description": "Explanation of how DOOH impressions were calculated"
"description": "Per-row supplementary methodology notes for DOOH impression calculation (e.g., 'rotation-based; 6-second slot weighted by 70% audience overlap'). Free-form prose for context that doesn't fit the structured measurement-vendor surface. Canonical methodology declarations belong on the measurement vendor's `get_adcp_capabilities.measurement.metrics[]` block where they're discoverable once and inherited across delivery rows; this field is for row-specific context (a particular daypart's calculation, a venue-mix exception) rather than the seller's general methodology."
},
"venue_breakdown": {
"type": "array",
Expand Down
16 changes: 2 additions & 14 deletions static/schemas/source/core/optimization-goal.json
Original file line number Diff line number Diff line change
Expand Up @@ -157,20 +157,8 @@
]
},
"attribution_window": {
"type": "object",
"description": "Attribution window for this optimization goal. Values must match an option declared in the seller's conversion_tracking.attribution_windows capability. Sellers must reject windows not in their declared capabilities. When omitted, the seller uses their default window.",
"properties": {
"post_click": {
"allOf": [{ "$ref": "/schemas/core/duration.json" }],
"description": "Post-click attribution window. Conversions within this duration after a click are attributed to the ad (e.g. {\"interval\": 7, \"unit\": \"days\"})."
},
"post_view": {
"allOf": [{ "$ref": "/schemas/core/duration.json" }],
"description": "Post-view attribution window. Conversions within this duration after an ad impression (without click) are attributed to the ad (e.g. {\"interval\": 1, \"unit\": \"days\"})."
}
},
"required": ["post_click"],
"additionalProperties": true
"allOf": [{ "$ref": "/schemas/core/attribution-window.json" }],
"description": "Attribution window for this optimization goal — references the canonical `attribution-window` shape (post_click, post_view, model). Values must match an option declared in the seller's `conversion_tracking.attribution_windows` capability. Sellers MUST reject windows not in their declared capabilities. When the entire field is omitted, the seller uses their default window."
},
"priority": {
"type": "integer",
Expand Down
2 changes: 1 addition & 1 deletion static/schemas/source/enums/forecastable-metric.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$schema": "http://json-schema.org/draft-07/schema#",
"$id": "/schemas/enums/forecastable-metric.json",
"title": "Forecastable Metric",
"description": "Standard delivery and engagement metric names for forecasts. Most values mirror `available-metric.json` (the canonical closed delivery vocabulary) — `impressions`, `clicks`, `spend`, `views`, `completed_views`, `engagements`, `follows`, `saves`, `profile_visits`, `downloads`, `plays` are shared. Forecast-only deltas — `audience_size`, `measured_impressions`, `grps`, `reach`, `frequency` — exist here because forecasts can reasonably project them but delivery reporting (and `available-metric.json`) uses different paths (e.g., reach/frequency are top-level fields on `aggregated_totals`, not entries in `available-metric`). When the industry converges on adding `audience_size` or `measured_impressions` to delivery reporting, those values graduate into `available-metric.json` and this enum's deltas shrink. For outcome/conversion forecasts (purchases, leads, app installs, etc.), use event-type enum values as metric keys instead. The ForecastPoint metrics map accepts any string key, so both forecastable-metric and event-type values can be used together.",
"description": "Standard delivery and engagement metric names for forecasts. **Most values mirror `available-metric.json`** (the canonical closed delivery vocabulary) — `impressions`, `clicks`, `spend`, `views`, `completed_views`, `engagements`, `follows`, `saves`, `profile_visits`, `downloads`, `plays`, `reach`, `frequency`, `grps` are all shared. **Forecast-only deltas** are just `audience_size` and `measured_impressions` — these exist here because forecasts can reasonably project them but delivery reporting today does not surface them as `available-metric` entries (delivery uses other paths: e.g., `measured_impressions` flows through `vendor_metric_values` when a third-party vendor reports it). When the industry converges on adding either to delivery reporting, those values graduate into `available-metric.json` and this enum's deltas shrink. For outcome/conversion forecasts (purchases, leads, app installs, etc.), use event-type enum values as metric keys instead. The ForecastPoint metrics map accepts any string key, so both forecastable-metric and event-type values can be used together.",
"type": "string",
"enum": [
"audience_size",
Expand Down
Loading