Skip to content

[Change] § 5.5 — Third-party vendor controls by reference (vendor_controls_accepted, vendor_controls) #158

Open

Description

@tmdbckr

What kind of change?

Add a new field

Which section?

5.5 — Targeting envelope

Current text

At v3.0-draft-1, § 5.5 defines geo, device, daypart and frequency_cap. There is no field through which a buyer can attach a third-party pre-serve control, such as a brand suitability or contextual segment maintained by a verification or data vendor.

Proposed text

§ 5.5, two new rows:

| `vendor_controls_accepted` | Object | seller-set | Third-party controls this line item can enforce: `{ vendors[], enforcement_party, enforcement, resolution[], pricing }` |
| `vendor_controls` | Array | supplied | The buyer's controls: `[{ vendor, control_ref, resolution }]` |

Shape:


vendor_controls_accepted:
  vendors:           ["example-vendor.com"]       # vendor domains
  enforcement_party: SSP_PLATFORM                 # a § 5.9 execution party
  enforcement:       pre_serve                    # pre_serve | best_effort
  resolution:        [live, pinned]
  pricing:           { "example-vendor.com": { delta_cpm: 0.00 } }

vendor_controls:
  - vendor:      "example-vendor.com"
    control_ref: "<opaque id issued by the vendor>"
    resolution:  live


Rules:

- A buyer MUST NOT supply a control whose `vendor` is absent from `vendor_controls_accepted.vendors[]`, or whose `resolution` is absent from `vendor_controls_accepted.resolution[]`. A seller agent MUST reject it deterministically (`not_offered`, if #130 is adopted), never ignore it.
- `control_ref` is opaque to the buyer agent and the seller agent. Only the vendor and the enforcing party resolve it. A seller agent MUST NOT require the control's contents in order to accept it.
- `resolution: live`: the reference is fixed in the record at `agreed`; its contents are resolved by the enforcing party at serve time and MAY change during the flight. The § 2.2 rule that references resolve into the stored record at `agreed` does not apply to `live` controls.
- `resolution: pinned`: the control MUST be hash-pinned and resolved into the record at `agreed`, as for `catalog_ref` (§ 2.2).
- Vendor controls narrow delivery. They combine as AND with every other § 5.3 and § 5.5 restriction, including `exclusions` if #25 is adopted.
- `vendor_controls` are recompute inputs (§ 3.3): `addressable_scale`, `availability` and price MUST reflect them before commitment.
- A vendor's `delta_cpm` applies when a control from that vendor is supplied. The buyer cannot set it.
- `best_effort` enforcement MUST NOT be presented as a guarantee. A guarantee is a `committed_metrics[]` entry measured by the same vendor (see #38).
- Vendor controls are visible only to the counterparty and the enforcing party (§ 5.8).
- `vendor` SHOULD be the vendor's registrable domain, the same identity used for `measurement_source` (§ 5.7).
- A line item MAY carry more than one vendor control. Like every line-item field, they are never inherited (§ 2).

Why

Buyers routinely transact with a third-party pre-serve control attached: a brand suitability profile, a contextual segment, a do-not-air list. The draft has no buyer-side route for it. A seller can only anticipate one, as a selectable option or in advisory not_suitable_for[] (§ 4.2), which means guessing each buyer's vendor and settings or publishing many variants of the same inventory.

#25 lets buyers carry block lists, which is right for domains, apps, keywords and IAB categories. A vendor-maintained control does not fit that shape:

  • It is not a list. It combines category risk levels, custom classifications, exception lists and, on CTV, genre and rating rules.
  • The seller cannot evaluate it. It is enforced through the vendor's integration at the DSP, SSP or ad server.
  • Buyers update it during a flight. A copy frozen at agreed goes stale.
  • Its contents reveal buyer strategy, the concern [Change] § 5.5 — Buyer-supplied block lists (exclusions_accepted, exclusions) #25 raises for § 5.8.

For PROGRAMMATIC_GUARANTEED and DIRECT_IO, the control has to be applied on the sell side, so if the proposal cannot carry it the buyer cannot ask for it before commitment. AdCP closed the same gap in 3.1 with product-level signal targeting and targeting_overlay.signal_targeting_groups; matching it keeps agents interoperable across both protocols.

This is a targeting change, not a measurement one. It states what a line item must be restricted by and who enforces it. How enforcement is measured stays with § 5.7 and the 4.0 work (#20, item 9).

Knock-on effects

Would this break an implementation already built to this draft?

No — additive or editorial

Alternatives you considered and rejected

  • Extending exclusions ([Change] § 5.5 — Buyer-supplied block lists (exclusions_accepted, exclusions) #25): lossy for anything but lists, frozen at agreed, and hands the seller data it cannot evaluate.
  • Seller-declared options in audiences.available[]: works only when the seller anticipated the buyer's vendor and settings, and mixes who is reached with where the ad runs.
  • The buyer_supplied pattern in § 5.3: built for audience data; reusing it would blur its meaning.
  • The brief only: the brief is not defined in 3.0 and would not bind the commitment.

You are commenting as

Measurement / verification vendor

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

  1. KonstantinMirin commented on Nov 11, 2026

    @KonstantinMirin

    Thanks, @tmdbckr. Two points from our PRs that bear on this.

    In #151, ExclusionType is an open vocabulary (§ 5.5). A seller can accept a vendor's own type, such as vendor.example:suitability_profile, with pre_serve or best_effort enforcement, and the type's definition sets the form of its entries. An entry can then be the vendor's profile id, with the contents left to the vendor. The id stays as it stood at agreed, and the disclosure rule already admits the vendors that enforce the lists. That covers avoidance controls, not a positive segment, a price per vendor, or a named enforcing party.

    #137 removes catalog_ref. A hash-pinned reference there is a DocumentRef, with a required digest, and an EntryRef pins a version without one (§ 2.2).

    Analyzed and generated with the help of Claude, fully reviewed by me.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions