DEV Community

Aleksander Sekowski
Aleksander Sekowski

Posted on

The Deal Sync vs OpenRTB Cheat Sheet Every PMP Bid Ops Engineer Needs

On October 18, 2026, PPC Land reported that TripleLift became Uber Advertising's first U.S. partner for offsite audience expansion: Uber ride and Eats signals packaged into private marketplace deals across TripleLift's open-web display, native, and online video supply. Buyers activate "within preferred DSP workflows using streamlined PMP deal curation." The release does not say how curator fees, data costs, or audience definitions show up in the bid stream. That gap is normal. Programmatic curation is sold as inventory plus data; on the wire it is still imp.pmp.deals with the same small field set IAB has used for years.

This sheet is for bid ops engineers, SSP integrators, and DSP QA leads who ingest IAB's Deal Sync API (Deals API v1.0, finalized February 6, 2026) and still have to traffic campaigns against live OpenRTB 2.6 templates. You need one place that maps sidecar metadata to the Deal object that actually rides the request, without pretending the two schemas merged.

Deal Sync fields versus what OpenRTB carries

IAB Tech Lab is explicit: Deal Sync is not part of the OpenRTB request or response, and criteria pushed through Deal Sync are not guaranteed to match the next bid request. The only hard join key is deal.id in the push payload and imp.pmp.deals[].id in traffic. Everything else is reconciliation, buyer-side targeting, or trust.

Deal Sync (sidecar) OpenRTB 2.6 (imp.pmp.deals[]) Notes
deal.id id (required) Must match when bidding; origin system's id wins per spec guidance.
terms.dealfloor + terms.cur bidfloor + bidfloorcur Floor can diverge if the SSP reprices live; sync is guidance unless pricetype is Fixed.
terms.pricetype (0–3, 500+) at (1 first, 2 second+, 3 fixed) Auction semantics; curated lines often look like any other PMP at value.
terms.guar guar Programmatic guaranteed flag; same integer meaning, still no curation marker.
deal.wseat / deal.bseat wseat / (no bseat on Deal) Seat allow/block; block lists are not symmetric on the request Deal object.
terms.countries (no deal-level geo) Geo may appear on device.geo or filters, not as a Deal child.
inventory.sellerids, sitedomains, appbundles site / app on the impression Scope is impression-level; Deal Sync inventory is static overview when dinventory=1.
deal.auxdata (non-publisher data fee flag) (none) No OpenRTB field; retail and data packages hide economics here.
curation.curator (none) Canonical curator domain; absent from bid request by design.
curation.cdealid (none) Curator's deal id; not the same namespace as SSP deal.id.
curation.curfeetype (0–4) (none) Fee disclosure (undisclosed, % spend, flat, CPM, none); never on the Deal object.
deal.origin, deal.seller (none) Business entities on the push; schain and ads.txt answer authorization on the request.

The OpenRTB deals and PMP guide walks the request-side vocabulary: private_auction, deal floors, at, guar, and seat lists. Every curated package still lands in that map.

Rows that validate and still fail in production

Matching id only. A bid request with "id": "uber-triplelift-001" validates as JSON and as OpenRTB. It says nothing about Uber as data curator, TripleLift as seller, or which segments were applied upstream. Deal Sync's curation object holds that story; the auction does not.

terms.dealfloor synced, live bidfloor lower. Deal Sync explicitly treats pushed floors as guidance unless price type is Fixed. QA that diffs sync JSON to the request and expects a byte match will false-alarm on legitimate repricing, or miss cases where the live floor dropped below what finance approved.

curfeetype and auxdata present in sync, absent everywhere in traffic. Fee transparency fields never appear under imp.pmp.deals. A bidder running rtblint on the request alone will never prove the buyer saw disclosed curation economics; that is a CRM and contract problem backed by the sidecar ingest, not by OpenRTB schema validation.

How you catch it

An LLM implementing Deal Sync ingestion, AdCP create_media_buy, or an ARTF agent that patches imp.pmp.deals can emit plausible JSON and still leave curator domains, fee types, or inventory scope only in the sidecar feed. The HTTP 200 on push or the RPC OK does not re-run OpenRTB against your pinned dated snapshot.

rtblint (cargo install rtblint, npm install rtblint-core, MCP rtblint-mcp) is the deterministic check on the OpenRTB object that actually hits the exchange: PMP shape, deal ids, floors, at, guar, and the video or native fields that decide whether the impression matches the deal type you trafficked. It does not validate the Deal Sync API payload; that traffic never rides the bidstream. Anyone wiring agentic buying still has to validate both surfaces. These packages are that check on the auction side. They are independent of IAB Tech Lab and of AAO; the spec does not require them.

Pin the same OpenRTB dated snapshot in CI that your exchange runs, validate production templates after every deal sync refresh, and diff deal ids against your ingest store. The OpenRTB docs index and what rtblint checks list the deal and PMP rules that show up on curated lines first.

Where to go next

Top comments (0)