VASTlint
Back to blog
Product update/9 min read

VMAP and DAAST validation land in vastlint core

vastlint core now validates VMAP 1.0 ad-break playlists and DAAST 1.0 digital-audio tags alongside VAST 2.0–4.3. 53 new rules, document-type detection, and embedded-VAST checking, all from the same CLI, library, and MCP server. Here is what shipped, why these two formats still break in production, and how to put structural checks in front of every break and every audio tag.

Author

Alex Sekowski

Published

June 13, 2026

Updated

June 13, 2026

Reading time

9 min read

VMAPDAASTDigital audioAd opsVAST validator

What shipped

vastlint core 0.5.0 adds dedicated validation chains for two IAB formats that sit right next to VAST in real ad stacks but rarely get the same scrutiny: VMAP 1.0 (the playlist that schedules your ad breaks) and DAAST 1.0 (the audio sibling of VAST). The validator now detects the document type automatically and routes each file to the right rule set: 24 new rules for VMAP, 29 for DAAST, on top of the existing VAST 2.0–4.3 coverage. The catalog is now 182 rules.

There is nothing new to install or configure. The same validate() entry point that handles a VAST tag now recognises a <vmap:VMAP> or <DAAST> root and runs the matching chain. The result carries a new document_type field (Vast, Vmap, or Daast) so you always know which rule set produced the findings. Every rule keeps the vastlint contract: a stable ID, a default severity, a spec reference, and a docs page with examples and fix guidance.

VMAP, briefly: the where and when of ad breaks

VMAP (Video Multiple Ad Playlist) is the IAB standard a content owner uses to describe ad-break structure when they do not control the player. It was published on July 19, 2012 and has had exactly one version since. The mental model worth keeping: VMAP handles the where and the when of ad placement (pre-roll, mid-rolls at specific offsets, post-roll), and VAST handles the what (the actual creative inside each break).

A VMAP document is a playlist of <AdBreak> elements. Each break carries a timeOffset (a timecode, a percentage, the keywords start or end, or an #m position), a breakType (linear, nonlinear, display), and an <AdSource> that either embeds a VAST document inline, points at an ad tag URI, or carries custom data. That flexibility is exactly where it breaks in production.

What actually goes wrong with VMAP

  • Malformed timeOffset. A mid-roll meant for 00:15:00 written as 15:00, or a stray percentage sign, silently drops the break instead of failing loud. vastlint flags the format against the spec grammar before a player ever has to guess.
  • An <AdSource> with more than one payload, or none. The spec requires exactly one of <VASTAdData>, <AdTagURI>, or <CustomAdData>. Stitchers and ad servers that template these documents routinely emit two, or leave the element empty.
  • AdTagURI or CustomAdData not wrapped in CDATA. URIs with query strings and ampersands corrupt the document when they are not in a CDATA block. This is the classic mid-roll that works in test and breaks on the first real macro-laden tag.
  • Inline VAST that is broken on its own terms. A structurally valid VMAP can wrap a structurally invalid VAST. vastlint validates the embedded <VAST> with the full VAST rule chain and reports issues with /VMAP/AdBreak[i]/AdSource/VASTAdData paths plus document-absolute line and column, so you know which break failed and why.
  • repeatAfter that does nothing. repeatAfter has no effect when timeOffset is start or end. vastlint warns instead of letting a no-op ship as if it scheduled recurring breaks.
VMAP that looks fine and is not
xml
<vmap:VMAP xmlns:vmap="http://www.iab.net/videosuite/vmap" version="1.0">  <vmap:AdBreak timeOffset="15:00" breakType="linear">    <vmap:AdSource id="mid-1">      <vmap:AdTagURI templateType="vast3">        https://ads.example.com/vast?cb=[CACHEBUSTER]&pos=mid      </vmap:AdTagURI>    </vmap:AdSource>  </vmap:AdBreak></vmap:VMAP>

What vastlint reports on that snippet

  • VMAP-1.0-adbreak-timeoffset-format (error): timeOffset "15:00" is not a valid hh:mm:ss[.mmm], n%, start, end, or #m value. The mid-roll will not schedule where you think.
  • VMAP-1.0-adtaguri-cdata (error): the AdTagURI contains an unescaped ampersand and is not inside a CDATA block, so the document is not well-formed once the macro expands.
  • VMAP-1.0-root-namespace (warning) would also fire if the vmap namespace URI were missing or wrong.

DAAST, and why audio still matters in 2026

DAAST (Digital Audio Ad Serving Template) is the audio counterpart the IAB released for public comment in 2014. It mirrors VAST 3.0 but swaps the video assumptions for audio ones: <Category> is required, creatives carry audio MediaFiles, <VideoClicks> becomes <AdInteractions>, and the tracking event set is audio-specific.

Here is the part that trips teams up: DAAST 1.0 is formally deprecated. In November 2018 the IAB merged audio support into VAST 4.1 via an optional adType attribute on the <Ad> element, and the recommendation since then is to serve audio with VAST 4.1 or later. So why validate DAAST at all in 2026?

Because the money has not stopped and neither have the legacy tags. IAB and PwC put US digital audio ad spend at $8.4 billion in 2025, up 10.2% year over year, with podcast revenue alone growing 17.6% to roughly $2.9 billion. A market that large still has long-lived DAAST inventory, DSP creatives, and ad-server templates in circulation. When a DAAST tag shows up, you want to know whether it is a clean DAAST document, a DAAST document with VAST leftovers, or a VAST tag someone mislabeled. vastlint answers exactly that.

The DAAST checks that catch real mistakes

  • VAST elements smuggled into DAAST. <VideoClicks> and <VASTAdTagURI> are VAST constructs. In DAAST you use <AdInteractions> and <DAASTAdTagURI>. vastlint flags both, which is the single most common symptom of a copy-pasted VAST tag wearing a DAAST root.
  • Missing <Category>. Optional in VAST, required in DAAST. Easy to drop when a template was forked from a video flow.
  • Video MIME types on an audio creative. A MediaFile typed video/mp4 inside a DAAST creative is almost always wrong; vastlint warns so the audio rendition is not a silent video.
  • AudioInteractions vs AdInteractions. The element was renamed to <AdInteractions> in the final DAAST release. Old generators still emit the draft name.
  • Audio pricing models. DAAST adds cpo (cost per order) to the usual cpm/cpc/cpe/cpv set, and requires model plus currency. vastlint validates the enum and the required attributes.
  • Error and tracking macros. Root-level <Error> presence and the [ERRORCODE] macro are checked so failed audio impressions are actually reportable.

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

A VAST tag pretending to be DAAST
xml
<DAAST version="1.0">  <Ad id="audio-1">    <InLine>      <AdTitle>Morning drive spot</AdTitle>      <Impression><![CDATA[https://t.example.com/imp]]></Impression>      <Creatives>        <Creative>          <Linear>            <Duration>00:00:30</Duration>            <MediaFiles>              <MediaFile delivery="progressive" type="video/mp4">                <![CDATA[https://cdn.example.com/spot.mp4]]>              </MediaFile>            </MediaFiles>            <VideoClicks>              <ClickThrough><![CDATA[https://example.com]]></ClickThrough>            </VideoClicks>          </Linear>        </Creative>      </Creatives>    </InLine>  </Ad></DAAST>

vastlint's verdict

  • DAAST-1.0-inline-category (error): <Category> is required in DAAST and is missing.
  • DAAST-1.0-mediafile-audio-type (warning): the MediaFile type is video/mp4 on an audio creative.
  • DAAST-1.0-videoclicks-element (warning): <VideoClicks> is a VAST element; DAAST uses <AdInteractions>. This is the tell that the tag was lifted from a video flow.

Why this belongs in core, not a separate tool

Ad ops teams do not deal with one format at a time. A single campaign can ship a VMAP schedule whose breaks wrap VAST 4.x creatives, while the audio line item delivers a DAAST tag. Asking people to remember which validator handles which format, and to paste tags into three different web tools, is how broken tags reach production.

Putting all three formats behind one entry point removes that decision. You hand vastlint a document, it tells you what the document is, and it validates it against the right spec with consistent rule IDs and severities. Because the embedded-VAST check inside VMAP runs the same VAST chain, a wrapper problem two levels deep surfaces with a path that points straight at the break it lives in. One engine, one report format, three formats covered.

Where the same checks run

  • CLI: validate VMAP and DAAST files in a pre-flight step or a git hook, same command you already use for VAST.
  • Library: call validate() and branch on document_type; the result shape is identical across formats.
  • CI: gate merges on a clean run so a malformed timeOffset or a DAAST tag with VAST leftovers never reaches a release.
  • MCP server: an AI agent doing campaign QA can validate a VMAP playlist or an audio tag through the same tool surface it uses for VAST.

Validate a VMAP or DAAST tag now

Paste a VMAP playlist or a DAAST audio tag into the validator. It detects the document type and returns every issue with a rule ID, severity, and the exact fix, the same way it does for VAST.

Open the validator

Authoritative references

The original IAB VMAP 1.0 PDF, published July 19, 2012. The grammar vastlint's VMAP rules are derived from.

IAB's DAAST landing page, including the deprecation note pointing audio buyers to VAST 4.1 and above.

The November 2018 release that folded audio support into VAST via the adType attribute.

IAB/PwC data on 2025 digital audio growth and podcast revenue, the reason legacy audio tags still circulate.

Keep reading

Related stories

All posts