VASTlint

VAST examples / Required fields

A VAST 4.x InLine with no <AdServingId>

VAST 4.11 error2 warningsVAST-4.1-adservingid-present

The scenario

A buyer running a programmatic CTV campaign wanted to reconcile its own impression logs against the publisher's and the verification vendor's, so it could audit discrepancies at the level of an individual ad serving — not just aggregate totals. That reconciliation depends on a shared per-response key.

The broken tag

<VAST version="4.1">
  <Ad id="1">
    <InLine>
      <AdSystem>Test</AdSystem>
      <AdTitle>Test</AdTitle>
      <!-- missing AdServingId (required since 4.1) -->
      <Impression>https://t.example.com/imp</Impression>
      <Creatives>
        <Creative>
          <UniversalAdId idRegistry="ad-id.org">ABCD1234567</UniversalAdId>
          <Linear>
            <Duration>00:00:30</Duration>
            <MediaFiles>
              <MediaFile delivery="progressive" type="video/mp4" width="640" height="360">
                https://cdn.example.com/ad.mp4
              </MediaFile>
            </MediaFiles>
          </Linear>
        </Creative>
      </Creatives>
    </InLine>
  </Ad>
</VAST>

What the validator reports

Running this tag through vastlint produces the following. The primary failure for this example:

errorVAST-4.1-adservingid-presentIAB VAST 4.1 §3.4.1line 3

<InLine> is missing required <AdServingId> (required since VAST 4.1)

The same tag also surfaces these secondary findings — real tags rarely fail in isolation:

warningVAST-2.0-version-mismatchIAB VAST 2.0 §2.1

VAST version attribute does not match structural signals in the document

warningVAST-2.0-linear-tracking-quartilesIAB VAST 4.1 §3.14.2line 11

<Linear> has no standard quartile tracking events (start/firstQuartile/midpoint/thirdQuartile/complete) — ad will serve but measurement system receives no signal

infoVAST-4.1-mezzanine-recommendedIAB VAST 4.1 §3.9.2line 13

<MediaFiles> has no <Mezzanine> — ad-stitching servers may reject this tag in CTV/SSAI contexts

Why it breaks

The InLine ad omits <AdServingId>. VAST 4.0 introduced AdServingId specifically so that every party that touches a given ad response — ad server, player, verification vendor — can stamp the same value on its logs and later join them back together. It is required on InLine ads in 4.x. Without it, each system has only its own internal IDs, which do not line up across parties.

What it costs

Cross-party reconciliation becomes guesswork. When the buyer's count disagrees with the seller's, there is no shared key to trace a single impression through both logs, so disputes are settled by aggregate fuzzy-matching instead of exact joins. That slows make-good negotiations, weakens fraud investigations, and undercuts the transparency that 4.x was designed to deliver.

The fix

Add a unique <AdServingId> to every InLine ad, generated per ad response and propagated unchanged through the chain. It belongs near the top of <InLine>, alongside AdSystem and AdTitle.

<InLine>
  <AdSystem>Acme Ad Server</AdSystem>
  <AdTitle>CTV Spot 30s</AdTitle>
  <!-- VAST 4.0+: unique per-response id shared across the chain -->
  <AdServingId>a532-4f1c-9b20-1e7d</AdServingId>
  <Impression><![CDATA[https://ads.example.com/imp]]></Impression>
  ...
</InLine>

VAST XML fragment only. This excerpt belongs inside a complete VAST document, so standalone validation will fail until it is wrapped in a full <VAST>response.

Check your own version of this tag

Paste the resolved XML to run the same spec check, test a live tag URL, or inspect the wrapper chain hop by hop.

Related examples

Related reading