Repository navigation
Description
What kind of change?
Add a new field
Which section?
Whole document / more than one section
Current text
n/a — new field. Related text, unchanged:
§ 2: A field on a line item MUST NOT inherit its value from the proposal or
from a sibling line item.Proposed text
Our errors and extensions PR carries this text. The § 4.4 row and the change_requests[] wording come with that table in our post-agreement PR. It builds on the § 2.2 shared types and section numbers of our shared types PR, which also removes catalog_ref.
§ 2.2, add a row to the shared types:
| `Ext` | `Map[Domain, Object]` | The extension container. § 2.5 states its rules |
§ 4.1 and § 5.1, add a row to each table:
| `ext` | Ext | OPTIONAL | seller-set | See Extensions (§ 2.5) |
§ 4.4, add a row to the `ChangeRequest` keys:
| `ext` | Ext | OPTIONAL | See Extensions (§ 2.5) |
### 2.5 Extensions
The proposal, each line item, and each `change_requests[]` entry (§ 4.4) MAY carry
`ext`, an `Ext`. Each key MUST be a `Domain` that its owner controls, and each value
is an object that the owner defines. A seller's own entries MUST use its
`seller.domain` as the key.
ext:
examplepub.example: { placement_code: "BD-ROS-300x250-Q4" }
- An `ext` entry MUST NOT change the meaning of a field this specification
defines. A term the counterparty must understand to transact MUST NOT be an
`ext` entry; it is a field or a vocabulary term.
- A receiver MUST ignore an `ext` entry it does not understand, and MUST NOT
reject a document because of it. It MUST keep `ext` unchanged when it
stores or forwards the document.
- In an object whose keys this specification lists, a key outside `ext` that
it does not list is invalid. An object whose content another definition
sets, such as a `FormatSpec`'s `spec` (§ 5.4), is unaffected, and so are the
open objects `DocumentRef` (§ 2.2), `ErrorObject` (§ 2.4), and `CostParameters`
(§ 5.6.5).
- On the proposal and a line item, `ext` is part of the Full Representation and
of the record frozen at `agreed` (§ 4.1.1), and a seller change to it is a
revision. On a `change_requests[]` entry, it is outside the record, as the
entry is (§ 4.4).
- Apart from an unknown term (§ 2.2), a receiver MAY skip a whole line item it
cannot read, without assenting to it. It MUST NOT keep a line item after removing
fields from it.Why
@VJAlkimi's unknown-key comment (#33) found the gap: no rule says what a parser does with a key the draft doesn't define. A strict parser rejects a seller's placement code, a lenient one drops it, and the two agreed records differ. Of #33's two answers, we take the second: ext, kept unchanged and frozen at agreed, with undefined keys invalid elsewhere. We add domain keys and a no-override rule.
Implementers already need it. IAB Tech Lab's reference seller agent adds ext to its line item on its unmerged feat/openproposal-mapping branch. Its Google Ad Manager mapper keeps fields with no OpenProposal home there. Yet its line-item model, in @jaanijuk's test, silently drops six undefined fields.
OpenRTB 2.6, § 2.9, AdCOM 1.0, OpenDirect 2.1, and the Deals API 1.0 all carry ext. OpenRTB leaves it unstructured, so two vendors can pick the same key. A Domain key names the owner, as in an extension vocabulary term, so one owner names its terms, ext entries, and error codes.
A proposal binds, so it needs rules a bid request doesn't:
- No override. Ignoring an entry is safe only if it can't change the agreed terms. A term the buyer must understand is a field, or a vocabulary term whose unknown value makes its entry unavailable or skips the line item.
- Keep it.
extis inside the binding record of our binding-record change request (#63). An intermediary that strips an entry changesrecord_digest, and the seller rejects thecommitwithrecord_mismatch. - Frozen at
agreed. An id assigned later, such as an ad server's line id, goes inexternal_references[](§ 5.10), outside the record.
Details: Extensions: full rationale and examples
Knock-on effects
- Appendix A and Appendix B: two
seller-setrows. - The print object in @matthew-iabtechlab's print channel request (#102) and the
oohobject in @premesh's static OOH comment (#125) are specification fields, notext. - A receiver rejects an undefined key with
validationand apointerat the key, under our error-model change request (#130). - A schema derived from the text, as in our schema implementation feedback (#121), sets
additionalProperties: falseon each object whose keys the text lists.
Open questions for the working group
- Should an
extkey be a domain (examplepub.example), as proposed, or a reverse-DNS key per entry (com.examplepub.placement_code), as #33 writes it? Either way, one form should serve vocabulary terms,extkeys, and extension error codes. - Answered in part in our errors and extensions PR: How does a receiver built to one release read a later release that adds keys?
spec_versionis REQUIRED on the proposal and inside the record, so each document names its release, as the well-known manifest of @Kishore-2572 (PR #76) does. Still open: what a receiver does with what its release doesn't list. It could reject an unknown major release. Within a major release, it could ignore unknown keys, as OpenRTB 2.6, § 2.6 does, and also keep them. The second option weakens the no-override rule. The PR asks this in § 8, and the rules issue lists both rules. - Answered in part in our errors and extensions PR: Should
extalso go on other objects? Eachchange_requests[]entry, which our post-agreement PR adds, carries one, outside the record. Still open: apricing[]entry,commitment, or anegotiation_history[]entry. The reference seller agent puts one on its history entry. OpenRTB 2.6 and AdCOM 1.0 allow it on any object. Each holder needs a marker and a binding-record rule. - Answered in part by @jaanijuk: Should an entry be able to require that a receiver understand it? VAST 4.3, § 3.18 requires that of every extension, and JWS
crit(RFC 7515, § 4.1.11) allows it per header. They propose that a bindingextterm need explicit acceptance beforeagreed, or the line item is rejected. One mechanism is a list of keys the receiver must understand, likecrit. Informational entries, such asext.gam, are ignored, as proposed. Still open: whether the working group wants that list, or the no-override rule, which keeps binding terms out ofext. - Answered in part in our shared types PR: May a summary in § 2.1, and so a manifest entry under PR #76, carry
ext, so that screening agents see an entry? A summary is a strict path subset of the full object, and its list has noextpath. Still open: whether screening agents need one. - Should the AAMP hub state one extension rule for OpenProposal and the primitives? The primitives use
extas the single extension slot, reservex_, and drop what they don't know on re-serialization. This change request keysextby domain and keeps it.
Would this break an implementation already built to this draft?
No — additive or editorial
Alternatives you considered and rejected
- The strict answer in [Comment] § 2 — The draft does not say what a parser does with a key it does not define #33. Vendor data moves into
descriptionormedia_kit_detailprose, where no agent parses it reliably. - Flat keys with a reserved prefix, as the primitives reserve
x_. Extension keys mix with defined ones, and a prefix names no owner. extoutside the binding record. An intermediary could change it without changingrecord_digest.
You are commenting as
Other — IAB Tech Lab member (Postindustria).
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.
Revised 2026-11-03: Rewritten to match our errors and extensions PR. Open questions 2, 3, and 5 are answered in part.
Analyzed and generated with the help of Claude, fully reviewed by me.
Activity