VASTlint
Back to blog
Verification envelope/12 min read

How to Validate AdVerifications in VAST Tags

A tag can list AdVerifications and still ship zero OMID measurement if Verification has no executable resource or the vendor key is empty.

Author

Alex Sekowski

Published

September 10, 2026

Updated

September 10, 2026

Reading time

12 min read

AdVerificationsOMIDVAST 4.1How-toCTV

A VAST InLine can play a clean MP4, fire every quartile, and still deliver zero third-party measurement. The buyer's verification vendor sees an unmeasured impression. The seller's ad server logs a completed view. Both sides think the other side broke something, because the XML looked verified at trafficking time.

The usual production bug is not a missing OM SDK build on the player. It is an AdVerifications envelope that exists on paper but cannot execute: a Verification node with an empty vendor attribute, a JavaScriptResource with no URL inside the CDATA, or a wrapper chain where Impression pixels survive every hop but AdVerifications never reaches the InLine the player actually parses.

IAB Tech Lab moved verification out of Extensions and into a first-class AdVerifications element in VAST 4.1. That envelope is the contract between trafficking, the player, and the measurement vendor. This piece is the container check: where the block has to live, which fields must be present before OM SDK ever runs, and what XML validation can catch while the video still plays normally.

Why the verification envelope is a money problem

Programmatic video buys increasingly price verification into the deal. A PMP that requires viewability or IVT measurement assumes the tag carries a parseable Verification entry with a loadable resource. When that entry is hollow, the impression still clears. The buyer's post-bid report simply marks it unmeasured, and reconciliation drifts toward the buyer's lower count.

That drift is slow until it is not. Inventory that persistently fails measurement gets repriced without a support ticket. DSP algorithms shade bids on supply that cannot prove itself. The seller sees CPM decay and assumes creative fatigue, when the actual failure is a Verification shell that never pointed at an executable script.

SSAI makes the envelope problem worse because the stitcher is a new publisher of VAST. It may copy Impression and MediaFiles faithfully and drop AdVerifications because the downstream player template only understands VAST 3.0 shapes. The stitched InLine plays. The verification block from the pre-stitch package is gone. Buyer and seller reports disagree, and neither side's dashboard names XML as the root cause.

Wrapper chains create the same invisible loss. AdVerifications can legally sit on a Wrapper or on the InLine. Players that accumulate verification from every hop will merge entries from outer wrappers with the final InLine. A QA paste of hop one that shows a Verification block is compatible with an InLine three redirects later that never inherited it, especially when an intermediary SSP re-renders the document and strips 4.x-only children.

What AdVerifications actually carries

AdVerifications is a container, not a measurement session. It holds one or more Verification children. Each Verification names a vendor and points at the resource the player should load: JavaScriptResource for web and many CTV SDK paths, ExecutableResource for native binaries on some platforms. Optional VerificationParameters pass vendor-specific configuration. TrackingEvents under Verification should include verificationNotExecuted so the vendor learns when load or execution failed instead of inferring silence.

None of that runs at ad-server response time. The player parses the final document, discovers Verification entries, and asks OM SDK (or a legacy integration) to load the resource. If vendor is missing, both resource types are absent, or the JavaScript URL is empty, the player has nothing to execute. Many stacks still start the linear creative. Quartile pixels fire. The verification vendor sees nothing.

That is the distinction from an OMID runtime guide. OM SDK integration, access modes, and session APIs matter after the envelope is valid. Envelope validation asks a narrower question: did this tag actually hand the player an identifiable vendor and a fetchable resource, in the place and shape the declared VAST version expects?

Where the block lives: InLine, Wrapper, and the chain you must fetch

On VAST 4.1 and later, AdVerifications is a direct child of InLine or Wrapper. It is not a Creative child and not a substitute for Linear tracking. Checking a Wrapper paste for verification while never unwrapping to the InLine is the same category error as demanding Duration on hop one.

Operational QA should mirror how the player resolves the chain. Paste or fetch the entry URL, follow VASTAdTagURI redirects until you hold the InLine (or the deepest document your player timeout allows), and validate that merged view. A green first hop plus a missing block on the InLine is a common false negative in manual review.

For SSAI, validate the document the device receives after stitching, not only the pre-stitch asset in the creative library. Stitchers that downgrade version or rebuild InLine from MediaFiles often omit AdVerifications even when the upstream chain included it. The player never sees the upstream envelope.

What AdVerifications envelope validation can catch before playback

  • AdVerifications containing anything other than Verification elements.
  • Verification missing the required vendor attribute, or vendor present but empty.
  • Verification with neither JavaScriptResource nor ExecutableResource.
  • JavaScriptResource or ExecutableResource missing apiFramework, or OMID resources not declaring apiFramework="omid".
  • ExecutableResource missing type when the platform requires it.
  • Empty or HTTP verification script URLs on secure inventory.
  • Duplicate vendor identifiers inside one AdVerifications block.
  • VerificationParameters missing or empty when the vendor script requires runtime configuration.
  • verificationNotExecuted tracking missing the [REASON] macro, weakening post-mortems.
  • Extension type="AdVerifications" on pre-4.1 documents where the player expects a top-level block instead.

VAST 4.1+ top-level placement versus the Extension compatibility path

VAST 4.1 introduced AdVerifications as a first-class sibling of Creatives under InLine and Wrapper. That is the shape modern OM SDK integrations target. Google IMA and other players document that 4.1 and higher should use the top-level element; older traffic sometimes wrapped the same data inside Extension type="AdVerifications".

The compatibility path matters in legacy feeds, but it is not interchangeable with 4.1 placement. A player configured for top-level AdVerifications will ignore verification buried only in Extensions on a document that declares version="4.2". The XML can contain the data in a spec-valid Extension and still deliver zero measurement on that player.

Migration work is therefore two-part: move verification to the top-level element for 4.1+ trafficking, and stop declaring 4.x while serializing pre-4.1 Extension shapes. Version honesty and envelope placement have to match, or parsers pick one shape and discard the other.

A VAST 4.2 AdVerifications envelope that should pass
xml
<InLine>  <AdSystem version="1.0">Example Ad Server</AdSystem>  <AdTitle>Spring CTV :15</AdTitle>  <Impression><![CDATA[https://track.example.com/imp]]></Impression>  <AdVerifications>    <Verification vendor="measurement.example.com-omid">      <JavaScriptResource apiFramework="omid" browserOptional="true"><![CDATA[https://cdn.measurement.example.com/omsdk/omid.js]]></JavaScriptResource>      <VerificationParameters><![CDATA[{"placement":"ctv-spring"}]]></VerificationParameters>      <TrackingEvents>        <Tracking event="verificationNotExecuted"><![CDATA[https://track.example.com/vne?reason=[REASON]]]></Tracking>      </TrackingEvents>    </Verification>  </AdVerifications>  <Creatives>    <Creative id="9001">      <Linear>        <Duration>00:00:15</Duration>        <MediaFiles>          <MediaFile delivery="progressive" type="video/mp4" width="1920" height="1080"><![CDATA[https://cdn.example.com/spot.mp4]]></MediaFile>        </MediaFiles>      </Linear>    </Creative>  </Creatives></InLine>

What a player does with that envelope

After the InLine resolves, the player reads AdVerifications before or during linear startup depending on the SDK. For each Verification, it records vendor, fetches the JavaScriptResource URL (unless browserOptional and native integration apply), passes VerificationParameters into the vendor script, and registers verificationNotExecuted if load fails.

Quartile TrackingEvents on Linear are unrelated to Verification TrackingEvents. Wiring start or firstQuartile under Verification is a schema and semantics error: those events belong on the creative, not on the measurement vendor block. The player may still play media while ignoring miswired verification tracking.

If every field in the passing example is present, OM SDK still might not run on a given CTV device. That is an integration question. Envelope validation only proves the tag handed the player a vendor key and a non-empty HTTPS script URL in the shape VAST 4.1 expects.

An AdVerifications block that lists verification but should be flagged
xml
<AdVerifications>  <Verification vendor="">    <VerificationParameters><![CDATA[{"campaign":"spring"}]]></VerificationParameters>    <TrackingEvents>      <Tracking event="start"><![CDATA[https://track.example.com/start]]></Tracking>    </TrackingEvents>  </Verification>  <Verification vendor="moat">    <JavaScriptResource apiFramework="OMSDK"><![CDATA[]]></JavaScriptResource>  </Verification>  <Verification vendor="moat">    <JavaScriptResource apiFramework="omid"><![CDATA[http://measurement.example.com/omid.js]]></JavaScriptResource>  </Verification></AdVerifications>

Get VAST spec updates, platform guides, and release notes in your inbox.

Why that block still looks verified in a spreadsheet

Trafficking exports often reduce verification to a yes/no column: AdVerifications present. The first Verification has Parameters and Tracking, so the row looks populated. vendor is empty, so the player cannot disambiguate which integration to load. No JavaScriptResource or ExecutableResource exists on that entry, so there is nothing to fetch even if vendor were fixed.

The second and third entries share a bare vendor name and duplicate moat, which violates the domain-qualified vendor convention and triggers duplicate-vendor warnings. The second entry's JavaScriptResource declares the wrong apiFramework and an empty CDATA body. The third points at HTTP. A shallow DOM count says three verifications. Runtime executes zero.

Fix order: require non-empty vendor in domain-omid form, exactly one Verification per vendor, a non-empty HTTPS JavaScriptResource with apiFramework="omid", move creative tracking off the Verification node, and add verificationNotExecuted with [REASON]. Re-run validation on the unwrapped InLine the player will see, not on the wrapper cover sheet.

What the AdVerifications rule set should complain about

  • VAST-4.1-verification-vendor because the first Verification has an empty vendor attribute.
  • VAST-4.1-verification-no-resource because the first Verification has no JavaScriptResource or ExecutableResource.
  • VAST-4.1-verification-vendor-format because moat is not domain-qualified.
  • VAST-4.1-verification-duplicate-vendor because moat appears twice.
  • VAST-4.1-js-resource-apiframework-value because OMSDK is not omid.
  • VAST-4.1-js-resource-https because the script URL uses HTTP.
  • Verification tracking event errors because start is not a valid Verification tracking event.
  • VAST-4.1-verification-parameters may warn on entries that need parameters; the empty-vendor entry has parameters but no resource to consume them.

Wrapper hops that drop the envelope

Verification injected at the outermost wrapper survives only if every downstream hop preserves AdVerifications and the player merges wrapper-level entries correctly. Some SSPs flatten wrappers into a single InLine for latency and copy only Impression, Creatives, and MediaFiles. Verification from hop one never reaches the device.

The failure mode looks like a vendor outage. The buyer's dashboard shows a sudden spike in unmeasured impressions on one supply path. The seller's fill and completion rates are unchanged. Support compares two VAST pastes from different days and finds verification on the trafficking export but not on the live resolved chain.

Prevention is chain inspection, not a single-hop paste. Fetch the live tag URL with the same timeout and redirect policy as production, unwrap programmatically, and diff AdVerifications nodes across hops. If an intermediary strips them, fix the intermediary or move verification injection to the InLine that survives stitching.

ExecutableResource versus JavaScriptResource on CTV

Most web and hybrid CTV stacks use JavaScriptResource with apiFramework="omid". Native-only integrations sometimes use ExecutableResource with a type attribute describing the binary interface. A Verification that lists only ExecutableResource on a player expecting JavaScript will not load measurement, even when vendor and URLs look valid for a different platform.

browserOptional on JavaScriptResource tells native players they may skip the script when a native OM SDK integration exists. Omitting browserOptional on CTV webviews that cannot execute JS should lead to verificationNotExecuted, not silent success. Envelope checks cannot prove the player honored browserOptional; they can prove the attribute and resource types match the declared VAST version.

When trafficking the same asset to web and CTV, duplicate Verification entries with different resource types are valid if vendor strings differ per integration. Duplicate vendor with conflicting resources is not.

A pre-launch AdVerifications checklist

  • Declared VAST version is 4.1+ and AdVerifications is top-level under InLine or Wrapper, not only inside Extensions unless the player documents Extension support.
  • Every Verification has a non-empty vendor in domain-omid form.
  • Every Verification includes JavaScriptResource or ExecutableResource with required attributes for the target platform.
  • OMID JavaScriptResource URLs are HTTPS, non-empty, and declare apiFramework="omid".
  • No duplicate vendor values inside one AdVerifications block.
  • VerificationParameters present when the vendor script requires them.
  • verificationNotExecuted tracking includes the [REASON] macro.
  • Creative quartile tracking is on Linear, not miswired under Verification.
  • The unwrapped live chain, including post-SSAI output, still contains the same Verification entries as the trafficking export.
Use the CLI when hollow verification should block launch
sh
vastlint check tag.xml --format json vastlint check tag.xml --fail-on-warning vastlint check "https://ad.example.com/vast?cid=9001" --unwrap

What AdVerifications envelope validation cannot prove

A valid envelope is necessary, not sufficient. XML checks do not download the script, verify the vendor signed it, or confirm OM SDK is integrated on the device. They do not prove verificationNotExecuted fires when execution fails. They will not catch a stitcher that removes the block after you validated the upstream chain.

They also will not replace OMID session debugging. Session errors, access mode mismatches, and creative container geometry belong in player logs and vendor tooling after the envelope passes.

If quartiles fire and the buyer still sees unmeasured impressions, compare the resolved InLine against the trafficking export. If the video never starts, fix Linear and MediaFiles first. If the video plays and verification is absent on the live chain, this checklist is the one.

Validate AdVerifications in your VAST tag

Paste a tag or fetch a live URL. vastlint checks the Verification envelope, vendor format, resources, and wrapper chain before launch.

Open the VAST validator

Related docs on vastlint

AdVerifications structure, Verification children, and how OM SDK uses the envelope at runtime.

Verification requires a non-empty vendor attribute.

Verification should include JavaScriptResource or ExecutableResource.

AdVerifications may only contain Verification elements.

Runtime-oriented OMID checks after the envelope is valid.

Why verification on hop one is not proof it survives the chain.

IAB Tech Lab VASTIAB Tech Lab

VAST 4.1 AdVerifications and Verification element definitions.

Keep reading

Related stories

All posts