The OpenRTB Native Asset Cheat Sheet Every PMP Bid Ops Engineer Needs AdMesh released an OpenRTB 2.6 adapter on November 9, 2026 that supports Native 1.2, letting DSPs backfill conversational inventory without a bespoke integration. The adapter keeps the standard handshake of a JSON string in imp.native.request and native markup in bid.adm when mtype is 4, and it does not relax asset matching: bids that omit a required asset id are still discarded by the exchange. The accompanying reference sheet maps publisher-requested native assets to the ids, subtypes and trackers a response must return. On November 9, 2026, AdMesh shipped an OpenRTB 2.6 adapter that speaks Native 1.2 https://useadmesh.com/blog/openrtb-programmatic-demand-agentic-advertising so DSPs can backfill conversational inventory without a bespoke integration. The handshake is still the same object OpenRTB has carried since 2.3: a JSON string in imp.native.request , and a native markup object or another encoded string in bid.adm when mtype is 4. Agentic routing does not relax asset matching. If your response omits a required asset id, the exchange still throws the bid away even when every field type-checks. I keep this sheet pinned for native PMP and in-app deals. It maps what the publisher asked for inside the encoded request to what must come back in the response. One malformed attribute is never the whole story; the table is the contract. Bid ops engineers who receive a native line item, a Prebid ortb2Imp , or a forwarded imp.native blob and need to know which ids and subtypes are non-negotiable before the creative studio builds markup. If you only validate the outer OpenRTB object, you have not validated native. imp.native.request Decode request once. From Native 1.1 onward the root is the request object ver , assets , … , not the legacy {"native":{...}} wrapper unless you are on 1.0. Each row is one assets element the publisher may mark required: 1 . | Request piece | Native field | What the publisher is asking for | Response must include | |---|---|---|---| | Title slot | title.len max length | Headline text, length cap | assets entry with same id , title.text ≤ len | | Main image | img.type: 3 plus w / h or wmin / hmin | Hero image type 3 = main | Same id , img.url , type 3, dimensions within min/max | | Icon / logo | img.type: 1 or 2 | Small brand mark | Same id , matching img.type and url | | Description | data.type: 2 plus optional len | Body / desc text data type 2 | Same id , data.value within length | | CTA / rating / other | data.type 3–12 per Native data asset enum https://rtblint.org/docs/openrtb/fields/native/request/ | Sponsored label, downloads, price, etc. | Same id , same data type, populated data.value | | Video asset | video object vasttag or network params | In-feed video unit | Same id , video.vasttag or agreed video payload | | Privacy support | privacy: 1 on request | Publisher can render privacy link | Response privacy url when required | | Tracking contract | eventtrackers with event + methods | Which events and pixel vs js are allowed | Response eventtrackers with url per chosen method see eventtrackers FAQ https://rtblint.org/answers/native-eventtrackers/ | | OpenRTB envelope | imp.native.ver | Declared Native Ads API version | Bid adm uses same major native version | | Blocked creative types | imp.native.battr | Bitfield of blocked creative attributes | Bid must not violate listed battr flags https://rtblint.org/docs/openrtb/fields/native/battr/ | | Supported APIs | imp.native.api | MRAID / OMID / etc. the slot supports | Creative must only claim supported api values https://rtblint.org/docs/openrtb/fields/native/api/ | The canonical request shape lives in the native bid request example https://rtblint.org/docs/openrtb-examples/native-bid-request/ : title id 1, main image id 2, optional data id 3, and eventtrackers instead of deprecated imptrackers for new 1.2 traffic. | Bid field | Value | Role | |---|---|---| | mtype | 4 | Declares adm is native markup not banner HTML or VAST XML | | adm | JSON object Native Markup Response or single-encoded JSON string | Root contains native 1.0 or native response root 1.1+ with assets , link , trackers | | assets .id | Same integers as request | Required pairing : every required: 1 request id must appear | | link.url | Click-through | Landing page; link.clicktrackers optional | | eventtrackers | event , method , url | Must honor request methods ; method 1 = img, 2 = js | | burl / nurl | Macro URLs | Billing and win notices; unrelated to render but still OpenRTB | Protobuf gRPC hops may use imp.native.requestNative / bid.admNative objects instead of strings. Only one spelling of the oneof may be set; mixing string and object alternatives fails parsers before native rules run. Double-encoded imp.native.request . The outer OpenRTB parses. The inner string is "{\"ver\":\"1.2\"...}" so the exchange sees a string, not assets. Rule family: openrtb.native.request.double encoded . Prebid and SSP serializers are the usual source. Required asset ids present in QA JSON but missing in the served adm . Unit tests often lint the bid object alone. Production loss Equativ 1002 https://rtblint.org/docs/openrtb/loss/exchange/equativ/1002/ is “native response does not match the native request,” which is almost always a missing or mistyped asset id, not a missing imp field. mtype: 4 with adm as a JSON string that is itself stringified. Schema says adm is a string, so a double-encoded native body passes type checks. The renderer receives escaped JSON and shows a blank unit openrtb.bid.adm.double encoded . eventtrackers with the right event but wrong method . Request allows { "event": 1, "methods": 1 } image pixel only . Response sends method: 2 with a script URL. Valid JSON, rejected or untracked depending on the exchange. An LLM or codegen tool can emit plausible native JSON and still return RPC or CI green. The wire contract is pairing: request asset ids, subtypes, and tracker methods against the decoded adm object. RTBlint https://rtblint.org/docs/openrtb/ is the deterministic check on that payload cargo install rtblint or npm install rtblint-core . Validate the request, validate the response, then run paired validation so openrtb.native.asset.required missing and openrtb.native.asset.type mismatch fire before the bid leaves your seat. It is independent of IAB Tech Lab and of AgenticAdvertising.org; the spec does not require it, but it is what I use when a model cannot be the authority on its own output. bash $ rtblint validate --type request req.json $ rtblint validate --type response --request req.json resp.json When a native asset carries video.vasttag , creative readiness is VAST, not native JSON. Paste that XML into the VAST tag tester https://vastlint.org/tester/ for fetch, preview, and tracking URLs, and use the VAST inspector https://vastlint.org/inspect/ if the tag is a wrapper chain. If the embedded VAST uses SIMID, the IAB-style VAST tester workbench https://iab-tech-lab-vast-tester.vastlint.org/ is an independent fork not an IAB Tech Lab product for the interactive handshake beside the linear asset. request , ver , battr , api . If you are debugging a specific id mismatch, start from the example request, diff your studio export against the decoded assets list, then pair-validate. Native is unforgiving about ids; the cheat sheet is really a checklist of integers that must survive encoding twice.