Repository navigation
Description
What kind of change?
Change a field's type or shape
Which section?
5.7 — Guarantees
Current text
§ 5.7:
| `committed_metrics[]` | Array[Object] | requestable | `{ metric, value, basis }` tuples — `viewable_rate` for display, `completion_rate` for video/audio/CTV, an audience-modelled metric for DOOH. Seller declares a ceiling; a buyer MAY request above it |
| `measurement_source` | Object | selectable | `available[]` of `{ vendor, attribution_window, qualifier }` with `pricing`. Lets a buyer transact in its own currency |
examples/line-item-display.yaml (§ 6.2):
committed_metrics:
- { metric: viewable_rate, value: 0.70, basis: mrc }
measurement_source:
available: [{ vendor: "IAS", attribution_window: "30d" },
{ vendor: "DoubleVerify", attribution_window: "30d" }]
included: ["IAS"]
examples/line-item-ctv.yaml (§ 6.3), serving_mode: ssai, no measurement_source:
committed_metrics: [{ metric: completion_rate, value: 0.95, basis: seller_reported }]
examples/line-item-audio.yaml (§ 6.4), serving_mode: dai, no measurement_source:
committed_metrics: [{ metric: completion_rate, value: 0.92, basis: seller_reported }]Proposed text
Replace the two § 5.7 rows:
| `committed_metrics[]` | Array[Object] | requestable | `{ metric, value, basis, measurement_source_ref }` tuples. `viewable_rate` for display, `completion_rate` for video, audio and CTV, an audience-modeled metric for DOOH. `measurement_source_ref` MUST equal an `id` in `measurement_source.available[]`. A seller MAY declare more than one tuple for the same `metric`, one per `measurement_source` option, each with its own ceiling. The tuple whose `measurement_source_ref` matches the resolved `measurement_source` selection governs. If no tuple for a `metric` matches the resolved selection, the line item carries no commitment on that `metric`, and an agent MUST show it as uncommitted. The seller declares a ceiling; a buyer MAY request above it. `basis` keeps its current meaning; where it and `counts[]` differ, `counts[]` governs |
| `measurement_source` | Object | selectable | `available[]` of `{ id, vendor, attribution_window, qualifier, counts[] }` with `pricing`. Lets a buyer transact in its own currency. REQUIRED when `committed_metrics[]` is non-empty. MUST declare `max_select: 1`, and `included[]` MUST name exactly one option. In each option, `id`, `vendor` and `counts[]` are REQUIRED; `attribution_window` and `qualifier` are OPTIONAL. A seller that settles on its own data declares itself as an option with `vendor: seller`. `counts[]` is defined in § 5.7.1 |
Add § 5.7.1 What a measurement source counts
Each `measurement_source.available[]` option carries `counts[]`, one entry per metric it can settle:
| Key | Required | Values |
| :--- | :--- | :--- |
| `metric` | REQUIRED | As in `committed_metrics[]` |
| `numerator` | REQUIRED when `metric` ends in `_rate` | `impression` \| `start` \| `first_quartile` \| `midpoint` \| `third_quartile` \| `complete` \| `viewable_impression` |
| `denominator` | REQUIRED when `metric` ends in `_rate` | Same values as `numerator` |
| `tracking` | REQUIRED | `client` \| `stitched_client_tracked` \| `server` \| `unknown`. Same meanings as OpenRTB 2.6 `imp.ssai` values 1, 2, 3 and 0 |
| `ivt_filtration` | REQUIRED | `none` \| `givt` \| `givt_sivt` \| `unknown` |
| `accreditation` | REQUIRED | `{ status: accredited \| in_audit \| not_accredited \| unknown, body, scope }`. `body` and `scope` are OPTIONAL |
| `viewability_threshold` | REQUIRED when `numerator` is `viewable_impression` | `{ pixels, seconds, audio_required }`. `pixels` is a percentage, 0 to 100 |
| `audience_unit` | REQUIRED when `metric` is not a rate | `{ unit: device \| household \| person \| listener, modeled: true \| false }`. Same vocabulary as `frequency_cap.basis` (§ 5.5) plus `person` |
| `methodology_ref` | REQUIRED | A `catalog_ref` (§ 2.2), or a version-pinned URI whose content MUST NOT change once referenced. It MUST be readable by the counterparty before `agreed`. A public document is RECOMMENDED but not required |
`unknown` is a valid declaration. An agent MUST treat it as unknown and MUST NOT substitute a default.
A buying agent MUST NOT present two committed metrics as equivalent unless their `metric`, `numerator`, `denominator`, `tracking` and `ivt_filtration` match, and their `viewability_threshold` matches where present, and none of those values is `unknown`. Different `methodology_ref` values do not by themselves make two metrics non-comparable, but the agent MUST keep both visible. An agent MAY score unlike guarantees against a buyer's own objectives.
§ 2.1, add to the per-line-item Summary Representation:
`measurement_source.available[].{ id, vendor, counts[].tracking }`
`committed_metrics[]` is already in the summary and now carries `measurement_source_ref`.
§ 6.3, replace the committed_metrics line in examples/line-item-ctv.yaml with:
committed_metrics:
- { metric: completion_rate, value: 0.95, basis: seller_reported, measurement_source_ref: seller }
- { metric: completion_rate, value: 0.90, basis: mrc, measurement_source_ref: vendor-a }
measurement_source:
available:
- id: seller
vendor: seller
counts:
- { metric: completion_rate, numerator: complete, denominator: impression,
tracking: server, ivt_filtration: givt,
accreditation: { status: not_accredited },
methodology_ref: "examplepub/methodologies/ssai-completion@1" }
- id: vendor-a
vendor: "Vendor A"
attribution_window: "30d"
counts:
- { metric: completion_rate, numerator: complete, denominator: impression,
tracking: stitched_client_tracked, ivt_filtration: givt_sivt,
accreditation: { status: accredited, body: mrc, scope: "CTV video completion" },
methodology_ref: "https://vendor-a.example/methodology/ctv-video" }
included: ["seller"]
max_select: 1Why
The basis key in the examples is doing two different jobs today. In the CTV example (§ 6.3) basis: seller_reported tells you who reports the number, and in the display example (§ 6.2) basis: mrc tells you which standards body is involved. Neither one tells a buying agent what is actually being counted, and that is the part it needs in order to compare two guarantees or settle one.
The draft's own examples show the problem:
- § 6.2 lets the buyer pick IAS or DoubleVerify, but there is a single
viewable_rateof 0.70, and it is not clear whose 0.70 the seller is signing up for. Sincemeasurement_sourceis selectable and resolves without seller assent (§ 3), the buyer's choice of vendor can quietly change what that requestable value means. - § 6.3 and § 6.4 both commit to a completion rate with no
measurement_sourceat all, so a buyer has nothing to select its own vendor against. - § 6.3 is
serving_mode: ssai, which is where this shows up most in practice; anyone who has reconciled an SSAI campaign against a third-party vendor report has likely run into it. With SSAI the tracking can come from the player (OpenRTB 2.6imp.ssai2) or from the stitcher (imp.ssai3), and the MRC's SSAI and OTT Guidance (2021) treats those differently: counting has to be client-initiated, the ad has to begin to render, and anything short of that is reported separately and disclaimed as non-compliant. So two lines can both read completion_rate 0.95, seller_reported, and still be counting under different rules. Both approaches are in use and both can be legitimate, but a buying agent should be able to see which one it is buying.
To be clear about scope, this is not an attempt to reopen the proposed 4.0 deferral of measurement and verification in #20 and #25. There is no new methodology and no normalization here, and settlement windows, restatement and reconciliation stay with 4.0. The ask is narrower: record, in closed values a seller can fill in today, which source settles each committed value and what that source counts. Cross-channel normalization stays with the workstream § 8 points to (likely WS4; OQ-3, #4), and this would give that work defined inputs to start from.
I tried to keep the enumerations to values sellers already emit, namely OpenRTB 2.6 imp.ssai and the VAST tracking events, plus the MRC's terms for invalid traffic filtration and accreditation, so nobody has to invent a new vocabulary to fill them in.
Commenting in a personal capacity. Product leader in CTV, identity and data; I have led teams that built DSP bidding, household identity graphs, and CTV ad insertion and monetization platforms. I maintain OpenCTV, an open-source, non-commercial project on CTV ad delivery diagnostics.
Knock-on effects
- Breaking, but narrowly: a seller implementation that emits
committed_metrics[]withoutmeasurement_sourcemust add one option (vendor: seller). No consumer breaks:basiskeeps its current meaning and is not renamed. - No marker changes.
committed_metrics[]stays requestable andmeasurement_sourcestays selectable.measurement_source_refandcounts[]sit inside existing fields, so Appendix A gains no rows and the Appendix B counts do not change. - § 3 "resolves without a round trip" is preserved: every governing tuple is declared up front, so a buyer's selection picks among declared commitments instead of re-basing one.
- § 2.1: three identifiers added to the summary. Coordinates with [Change] § 2.1, § 5.10 — Cross-publisher composition: searchable summary metadata and source_ref #28, which also edits that list. If [Change] § 2.1, § 5.10 — Cross-publisher composition: searchable summary metadata and source_ref #28 is adopted, this proposal adds: an aggregated line item MUST carry its source's
measurement_sourceoptions andcounts[]unchanged, and MUST NOT add ameasurement_source_refthe source does not offer. - [Change] § 3 — Name the key the buyer writes its selection to:
selected[]on selectable fields,valueon settable fields #22: "resolved selection" meansmeasurement_source.selected[]if [Change] § 3 — Name the key the buyer writes its selection to:selected[]on selectable fields,valueon settable fields #22 is adopted, otherwiseincluded[]. - § 2.2: no change. The agreed record already resolves catalog references and is immutable, which freezes the governing tuple and its
counts[]atagreed. - § 6.2: each existing IAS and DoubleVerify option gains an
idandcounts[]; the 0.70 tuple gainsmeasurement_source_ref: ias; a seller that also commits under DoubleVerify adds a second tuple. § 6.4 gains avendor: selleroption like § 6.3. - Downstream: no change to OpenDirect, Deals API or OpenRTB.
trackingmirrors OpenRTB 2.6imp.ssai, so the governing source's value can be checked against the bid request'simp.ssai.
Would this break an implementation already built to this draft?
Yes — breaking
Alternatives you considered and rejected
- Renaming
basisand turning it into a methodology object. That breaks every parser built against the examples, and it pulls methodology into the object model, which [Comment] Whole document — Feedback from the Agentic Bootcamp, 24 September 2026 #20 proposes leaving to 4.0. - Declaring the counting rules on each committed_metrics tuple instead of on the source. The same vendor's definition would then be repeated on every line item, and the link to the buyer's choice of currency gets lost.
- A free-text basis. Easy to write, but an agent has no way to compare two of them.
- Mandating one completion_rate definition in 3.0. Client-tracked and server-tracked SSAI measurement are both in use today, so a single definition would either shut some sellers out or paper over the difference. Asking sellers to declare which one they use avoids both problems.
- Deferring all of it to 4.0. The § 6.2 example already offers two vendors against one value, so the ambiguity is in 3.0 whether or not the methodology work is.
You are commenting as
Individual, no organisational position
Before you submit
- I have read CONTRIBUTING.md and agree my contribution may be published under this repository's licence.
- This contains no confidential or commercially sensitive information.
Activity
aleksUIX commentedon Oct 21, 2026
In the proposed § 5.7.1, could the minimum equivalence check also compare
audience_unitfor non-rate metrics?The object requires
{ unit, modeled }, but the comparison paragraph does not include either. As a constructed example, two commitments with the same non-rate metric name and the same listed comparison fields could each say 1,000,000 while one counts households and the other counts persons. The declared unit exposes the mismatch, but the stated guard does not check it.Suggested addition:
It would also help to state that the numerator and denominator comparisons apply to rate metrics. A missing required
audience_unitshould fail validation rather than be treated as a matching empty value.This carries the unit distinction already raised in #39 into the comparison rule here. No conversion between households and persons is implied.
Commenting in a personal capacity.
unreconciled commentedon Oct 22, 2026
Agreed, the comparison rule should check the unit for non-rate metrics; as written it would treat a household count and a person count as equivalent. Folding in the suggested sentence, the § 5.7.1 equivalence paragraph would read:
Three filings from this week describe the same declarations from the audit and out-of-home side and could be considered together with this one: #51 (methodology, provider and measurement period for audience figures), #54 (forecast versus guaranteed audience) and #56 (third-party verification reference).
On the breaking label, for adjudication: the only implementations affected are seller-side ones that emit
committed_metrics[]withoutmeasurement_source, and each of those adds onevendor: selleroption.basisis not renamed and keeps its meaning, so nothing that reads the current fields breaks.KonstantinMirin commentedon Oct 22, 2026
Postindustria (IAB Tech Lab member) supports this, with the revised equivalence paragraph. Three points from our PRs bear on it.
basisand renamesvaluetolevel. A committed metric is ametricterm, alevel, and adirection. Each coremetricterm's definition names its standard. Ameasurement_sourceoption names its provider inmeasured_by, in place ofvendor.measured_by: sellercovers whatbasis: seller_reportedsaid. Which source settles a level stays this issue's rule.cost_parameters.demographic, such asratings.example:adults_25_54, beside itsrating_source. A guarantee of 150 rating points among adults 25–54 is aCPPentry on aguaranteedline item, counted by thatrating_source. The term's definition can state whom it counts, including whether co-viewers count: Nielsen counts co-viewers on CTV by default. This replaces thetargetobject and thein_target_impressionsandgrpmetrics we proposed.impressionsterm counts DOOH only, so a podcast count is its ownmetricterm, citing the guidelines' Ad Delivered count (§ 6.3). It never matches an impression. Until a core term exists, a seller defines one under its own domain. This replaces thedownloadandad_deliveredvalues, thenumeratorSHOULD on counts, and ourmodeledreading.Points 2 and 3 add no key to
counts[].Open questions:
co_viewingsit on the tuple'stargetor on the source'scounts[]entry, as a boolean or an enum? Noco_viewingkey remains. Still open: must ademographicterm's definition state co-viewing, or does therating_source's methodology decide it?in_target_rate) with a newin_target_impressionnumerator? A share would be ametricterm, with no numerator value. Still open: should it be added, or should shares stay out of this version?agetake aninclude_unknownflag? Noagekey remains. Still open: should ademographicterm say whether impressions with unknown age count, or should the source's methodology decide that?impressionas our pricing change request defines CPM, or get its own cost method?accreditation.status: accredited, or does it need its own status value?Details: Demographic and podcast counts: full rationale
Revised 2026-11-03: A
demographicterm and a podcastmetricterm replace thetargetobject, the two new metrics, and the new numerator values. Point 1 gives the names our settlement PR changes, and questions 1 to 3 are answered in part.Analyzed and generated with the help of Claude, fully reviewed by me.
aleksUIX commentedon Oct 25, 2026
The revised equivalence paragraph in your reply already incorporates the audience-unit distinction I raised. I would build on that text with acceptance examples and one clarification about what passing its checks establishes.
Proposed addition after that paragraph in § 5.7.1:
This adds no window, population or methodology-version field to
counts[]. The existing proposal's version-pinned methodology reference can define those conditions, alongside the resolved line-item context. If an implementation cannot establish them from the available declarations, it cannot assert equivalence. Structured population definitions and channel-specific counts can be considered with the existing comments here and #51, rather than introduced a second time.Constructed acceptance cases:
denominator: startand the other withdenominator: impression: incompatible definitions, despite the equal percentages.ivt_filtration: unknown: insufficient information, not equivalent filtration.ivt_filtration: givt, the othergivt_sivt: the existing comparison guard must reject equivalence. Apply filtration per counted metric; an impression's filtration does not establish a click's filtration.The useful distinction for an implementer is between an invalid declaration, a known mismatch, an unresolved comparison, and passing the minimum checks. These are labels for the examples, not a proposed wire enum or a new ranking model. Passing the minimum checks must not be converted into an automatic equivalent=true result.
An unresolved comparison does not make an otherwise valid offer invalid or prevent a buyer from selecting it. It limits the claim that the offer's guarantee is equivalent to another guarantee.
These rules concern what the guarantees mean. They do not establish equal delivery outcomes, permit aggregating overlapping audiences, or identify the count used for invoicing. Controlling measurement and settlement remain separate work in #95. Cross-channel normalization remains with #4.
These are proposed acceptance cases, not implementation test results.
Member of the IAB Tech Lab Agentic Taskforce, commenting in a personal capacity.
unreconciled commentedon Oct 26, 2026
Thanks for this, and for the acceptance cases. I agree with the proposed paragraphs and would put them into § 5.7.1 as written, right after the revised equivalence paragraph. They say out loud what the field checks already imply: matching fields are only the floor. In practice, when the methodology references don't settle population or window, an agent will usually have to report the comparison as unresolved, and I think that is the honest answer.
On the seven cases, I would keep them as worked examples under § 5.7.1 rather than normative text. That way they help implementers without turning into a test suite the spec has to maintain. Scope is the same as you laid out: no new fields in
counts[], settlement and the controlling count stay with #95, and normalization stays with #4.unreconciled commentedon Nov 5, 2026
Thanks for the revision. On point 1: if #147 is adopted, this change reads with its names (
measured_byforvendor,levelforvalue) and thebasissentence drops. The rule here does not change:measurement_source_refnames the option that settles each level, and that option'scounts[]say what it counts.On the open questions, answered from the scope this change started with: declare what is counted, add no methodology.
demographicterm's definition should state whether co-viewers count, withunknownallowed. Who a guarantee counts is part of what is committed; how co-viewers are measured stays with therating_source's methodology. Otherwise two guarantees on adults 25-54 from different rating sources read as equivalent when one includes co-viewers and the other does not.unknownallowed, because that changes who is counted. How a source assigns age stays with its methodology.impressionwhile the guarantee counts delivered ads; a line item should be priced on the unit it is counted and settled on.statusvalue, with its ownbodyandscope. Buyers readaccreditedas an audited accreditation, and a compliance certification is a different claim.