Skippable linear VAST ads
A skippable linear ad is a linear ad that presents a skip button to the viewer after a defined number of seconds. The viewer can dismiss the ad early. Skippable ads typically have higher viewer tolerance for longer durations (30–60s or more) and are used in pre-roll and mid-roll placements on web and CTV.
Quick reference
| Skippable signal | <Linear skipoffset="00:00:05"> |
| Offset formats | Absolute (HH:MM:SS) or percentage (25%) |
| Skip tracking event | skip (VAST 3+) — fires when viewer skips |
| Industry default | 5-second skip offset (TrueView-style) |
| VAST versions | 3.0+ (skipoffset introduced in VAST 3.0) |
The skipoffset attribute
The skipoffset attribute on <Linear> is the only VAST mechanism for declaring a skippable ad. It accepts two formats:
- Absolute time —
HH:MM:SSorHH:MM:SS.mmm. Skip button appears after this many seconds of playback. - Percentage —
N%. Skip button appears after N% of the declared duration has elapsed. Rarely used in practice.
<!-- ✅ Absolute time — skip button after 5 seconds -->
<Linear skipoffset="00:00:05">
<Duration>00:00:30</Duration>
...
</Linear>
<!-- ✅ Percentage — skip button after 25% of 30s = 7.5s -->
<Linear skipoffset="25%">
<Duration>00:00:30</Duration>
...
</Linear>
<!-- ❌ Wrong — skipoffset="" disables skip but may be parsed as 0 by some players -->
<Linear skipoffset="">
...
</Linear>→ vastlint rule: VAST-3.0-skipoffset-format
Full skippable ad example
<VAST version="4.2">
<Ad id="1">
<InLine>
<AdSystem>My Ad Server</AdSystem>
<AdTitle>My Skippable Ad</AdTitle>
<Impression id="imp1"><![CDATA[https://track.example.com/impression]]></Impression>
<UniversalAdId idRegistry="Ad-ID">8465904</UniversalAdId>
<Creatives>
<Creative id="creative1" sequence="1">
<Linear skipoffset="00:00:05">
<Duration>00:00:30</Duration>
<TrackingEvents>
<Tracking event="start"><![CDATA[https://track.example.com/start]]></Tracking>
<Tracking event="firstQuartile"><![CDATA[https://track.example.com/q1]]></Tracking>
<Tracking event="midpoint"><![CDATA[https://track.example.com/mid]]></Tracking>
<Tracking event="thirdQuartile"><![CDATA[https://track.example.com/q3]]></Tracking>
<Tracking event="complete"><![CDATA[https://track.example.com/complete]]></Tracking>
<!-- Skip event fires if the viewer clicks skip -->
<Tracking event="skip"><![CDATA[https://track.example.com/skip]]></Tracking>
</TrackingEvents>
<VideoClicks>
<ClickThrough id="click1"><![CDATA[https://example.com/landing]]></ClickThrough>
<ClickTracking id="ctrack1"><![CDATA[https://track.example.com/click]]></ClickTracking>
</VideoClicks>
<MediaFiles>
<MediaFile delivery="progressive" type="video/mp4"
width="1920" height="1080" bitrate="2500">
<![CDATA[https://cdn.example.com/ad-1080p.mp4]]>
</MediaFile>
<MediaFile delivery="progressive" type="video/mp4"
width="1280" height="720" bitrate="1200">
<![CDATA[https://cdn.example.com/ad-720p.mp4]]>
</MediaFile>
</MediaFiles>
</Linear>
</Creative>
</Creatives>
</InLine>
</Ad>
</VAST>The skip tracking event
The skip tracking event (introduced in VAST 3.0) fires when the viewer clicks the skip button. After a skip, the player does not fire complete — the two events are mutually exclusive. Buyers use the skip event to measure earned attention and calculate video completion rates correctly.
VAST 4.x also defines a skipped event as an alias for backward compatibility. Most platforms only fire one or the other. Provide both if you need to cover all players:
<TrackingEvents>
...
<Tracking event="skip"><![CDATA[https://track.example.com/skip]]></Tracking>
<!-- VAST 4.x alias — include for broader compatibility -->
<Tracking event="skipped"><![CDATA[https://track.example.com/skip]]></Tracking>
</TrackingEvents>Platform skip button behaviour
The skipoffset in VAST controls when the skip becomes available. The visual design of the skip button is controlled entirely by the player. You cannot style it from VAST. Platform-specific notes:
| Platform | Skip UI behaviour |
|---|---|
| Google IMA SDK (web) | Shows countdown timer, then "Skip Ad" button. Respects skipoffset. |
| Google IMA SDK (CTV) | Skip supported on tvOS / Android TV. Skip button triggered via remote D-pad select. |
| Roku RAF | Skip supported. Viewer presses back/select on remote. Countdown shown. |
| JW Player | Respects skipoffset. Renders a "Skip" button after offset. |
| Video.js / contrib-ads | Respects skipoffset when using videojs-ima or vast-client plugin. |
VAST version compatibility
The skipoffset attribute was introduced in VAST 3.0. Tags declaring version="2.0" that include skipoffset will have the attribute ignored by spec-compliant parsers. Always declare version="3.0" or higher when using skipoffset.
Common mistakes checklist
- skipoffset on a VAST 2.0 tag — the attribute did not exist in VAST 2.0 and will be silently ignored. Declare version 3.0+.
- Missing skip tracking event — buyers cannot measure skip rate without it. Most DSP contracts require it.
- Firing complete after a skip — the player should not fire
completewhen the user skips. If your ad server fires both, you will over-report completion rates. - skipoffset exceeds duration — if
skipoffsetis longer than<Duration>, the skip button never appears and the ad behaves like a non-skippable. Validate the offset against the declared duration. - Percentage offset with missing duration — percentage-based
skipoffsetrequires a valid<Duration>to calculate the absolute offset. If duration is missing or malformed, the skip never fires.