On November 9, 2026, AdMesh shipped an OpenRTB 2.6 adapter that speaks Native 1.2 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.
Who this is for
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.
Request assets (inside 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
|
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) |
| 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 |
| Supported APIs | imp.native.api |
MRAID / OMID / etc. the slot supports | Creative must only claim supported api values |
The canonical request shape lives in the native bid request example: title id 1, main image id 2, optional data id 3, and eventtrackers instead of deprecated imptrackers for new 1.2 traffic.
Response fields (seatbid.bid)
| 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.
Rows that validate and still lose in production
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 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.
How you catch it
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 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.
$ 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 for fetch, preview, and tracking URLs, and use the VAST inspector if the tag is a wrapper chain. If the embedded VAST uses SIMID, the IAB-style VAST tester workbench is an independent fork (not an IAB Tech Lab product) for the interactive handshake beside the linear asset.
Where to go next
-
imp.native object on the impression:
request,ver,battr,api. - imp.native.request encoding rules and version table.
- Native bid request example with a paste-ready payload.
- eventtrackers event and method codes for 1.2.
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.
Top comments (0)