Home / VAST Integration

🎬 VAST Integration Guide

Everything you need to know about VAST (Video Ad Serving Template) — from what it is and how it works, to live code examples for every major video player.

VAST 2.0 VAST 3.0 VAST 4.0 IAB Compliant Pre-roll & Mid-roll Real-Time Tracking
1
Get your VAST URL
From your dashboard publisher key
2
Pick your video player
JW Player, Video.js, IMA, Flowplayer…
3
Paste the VAST tag URL
Into your player's advertising settings
4
Test & go live
Validate with Google IMA Inspector

1. What is VAST?

VAST (Video Ad Serving Template) is an XML-based specification published by the IAB (Interactive Advertising Bureau) that defines a standard way for video players to communicate with ad servers. It has been the industry standard since 2008 and is supported by virtually every video player and ad platform in existence.

Before VAST, every ad network had its own proprietary video ad format. Publishers had to integrate each ad network separately. VAST solved this by defining one universal contract between a video player (the client) and an ad server (the server):

💡 In simple terms: Your video player asks the ad server "what ad should I show?" The ad server responds with a VAST XML document that says exactly what video file to play, where to send tracking events, and what to do when the user clicks.

Why use VAST?

  • Universal compatibility — one VAST URL works with JW Player, Video.js, Flowplayer, Brightcove, and hundreds of other players
  • Standardized tracking — impression, click, quartile events all reported automatically by the player
  • No SDK required — the player does all the work; you just supply the tag URL
  • Full creative control — supports MP4/WebM video files, companion banners, and click-through URLs
  • Works with Google IMA — Google's widely-used IMA SDK is fully VAST-compatible

2. How VAST Works — The Request/Response Cycle

Every time a video starts (or a mid-roll position is reached), this sequence happens automatically:

1
Page Loads
Player initialises on the publisher's page
2
VAST Request
Player fetches your VAST tag URL via HTTP GET
3
VAST XML Response
Ad server returns XML describing the ad creative
4
Creative Loaded
Player downloads the video file from the Media URL
5
Ad Plays
Player overlays or pre-rolls the ad over content
6
Events Fired
Impression, quartile, click events ping tracking URLs

The VAST XML response contains everything the player needs: the video file URL, duration, click-through URL, skip offset, and a list of tracking pixel URLs the player must call at specific moments (start, 25%, 50%, 75%, 100% watched, click, etc.).

3. VAST Versions

Our ad server supports VAST 2.0, 3.0, and 4.0. Here's what each version adds:

VAST 2.0 (2008)

  • Core linear (pre-roll) video ads
  • Media files (MP4, WebM)
  • Click-through tracking
  • Impression tracking pixel
  • Non-linear (overlay) ads
  • Companion banners
  • Ad wrapping (VAST Wrapper)

VAST 3.0 Recommended

  • Everything in 2.0
  • Ad pods (multiple ads in sequence)
  • Skippable ads (skip offset)
  • Progress tracking events
  • Error codes (standardised 900 range)
  • Social actions tracking
  • Icon support

VAST 4.0 / 4.2 (2016–2022)

  • Everything in 3.0
  • Universal Ad ID (ISCI code)
  • Viewability measurement (OMID)
  • InteractiveCreativeFile (SIMID)
  • Muted autoplay support
  • AdVerifications (third-party)
  • Category / content targeting
📌 Which version should I use? For most publishers, VAST 3.0 gives the best balance of feature support and player compatibility. All modern players support it. Only request 4.0 if you specifically need viewability (OMID) or interactive ads.

4. Your Personal VAST URL

Your VAST URL is unique to your publisher account. It contains your publisher key which identifies you for earnings attribution and tracking. Keep it private.

⚠️ Log in to see your personal VAST URL. The examples below use a placeholder key — replace YOUR_PUBLISHER_KEY with your actual key from the dashboard.
https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY

Adding optional parameters

You can append parameters to control targeting and ad selection. For example, to serve only pre-roll ads at 1920×1080:

https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY&position=preroll&width=1920&height=1080

See the full URL Parameters reference below for all options.

5. Player Integration Examples

Choose the player you use. All examples use your VAST URL — replace YOUR_VAST_URL with the value from the box above.

🎬 JW Player
▶️ Video.js + IMA
▶️ Video.js + VAST
🌊 Flowplayer
🌐 Plain HTML5
🔵 Google IMA SDK

JW Player 8 / 9

Add the advertising block to your existing jwplayer().setup() call.

JavaScript
jwplayer("player-container").setup({
  playlist: [{
    file: "https://example.com/your-video.mp4",
    image: "https://example.com/thumb.jpg"
  }],
  advertising: {
    client: "vast",          // use "googima" for IMA SDK on JW8+
    tag:    "https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY",
    schedule: [{
      offset: "pre",     // "pre", "post", or seconds for mid-roll
      tag:    "https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY"
    }]
  }
});
On JW Player 9, set client: "googima" for better skip-ad and quartile tracking support.

Video.js + Google IMA3 SDK (recommended)

The most robust approach — uses Google's free IMA3 SDK which handles all VAST/VPAID logic.

HTML
<!-- 1. Include dependencies in <head> -->
<link  href="https://vjs.zencdn.net/8/video-js.css" rel="stylesheet">
<script src="https://vjs.zencdn.net/8/video.js"></script>
<script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-ads/6.9.0/videojs.ads.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-ima/1.10.1/videojs.ima.min.js"></script>

<!-- 2. Player element -->
<video id="my-player" class="video-js vjs-default-skin"
       controls preload="auto" width="640" height="360"
       data-setup="{}">
  <source src="https://example.com/video.mp4" type="video/mp4">
</video>

<!-- 3. Initialise IMA plugin -->
<script>
  var player = videojs('my-player');
  player.ima({
    adTagUrl:      'https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY',
    debug:         false,
    prerollTimeout:5000   // ms to wait for VAST response
  });
</script>

Video.js + videojs-vast-vpaid Plugin (lightweight)

HTML
<script src="https://vjs.zencdn.net/8/video.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/videojs-contrib-ads/6.9.0/videojs.ads.min.js"></script>
<!-- videojs-vast by MailOnline -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/bin/videojs.vast.vpaid.js"></script>

<script>
  var player = videojs('player');
  player.vast({
    url: 'https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY'
  });
</script>

Flowplayer 7 / 8

JavaScript
flowplayer('#player', {
  clip: {
    sources: [
      { type: 'video/mp4', src: 'https://example.com/video.mp4' }
    ]
  },
  ima: {
    ads: [
      {
        time: 0,          // 0 = pre-roll; integer seconds for mid-roll
        adTag: 'https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY'
      }
    ]
  }
});
Flowplayer's commercial IMA plugin is required for VAST support on v7+. Install via npm install @flowplayer/player-ima or add the CDN script.

Plain HTML5 + Google IMA SDK (no framework)

Minimum code to serve a pre-roll ad with Google's free IMA SDK, no video.js required.

HTML
<!DOCTYPE html>
<html><head>
  <script src="https://imasdk.googleapis.com/js/sdkloader/ima3.js"></script>
</head><body>
<div id="content-wrapper" style="position:relative;width:640px;height:360px;">
  <video id="content-video" width="640" height="360"
         src="https://example.com/video.mp4"></video>
  <div id="ad-container" style="position:absolute;top:0;left:0;width:100%;height:100%;"></div>
</div>
<script>
  var adDisplayContainer, adsLoader, adsManager;
  var videoElement   = document.getElementById('content-video');
  var adContainer    = document.getElementById('ad-container');
  var AD_TAG_URL     = 'https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY';

  function init() {
    adDisplayContainer = new google.ima.AdDisplayContainer(adContainer, videoElement);
    adsLoader = new google.ima.AdsLoader(adDisplayContainer);
    adsLoader.addEventListener(google.ima.AdsManagerLoadedEvent.Type.ADS_MANAGER_LOADED, onAdsManagerLoaded);
    var req = new google.ima.AdsRequest();
    req.adTagUrl = AD_TAG_URL;
    req.linearAdSlotWidth  = 640;
    req.linearAdSlotHeight = 360;
    adsLoader.requestAds(req);
  }

  function onAdsManagerLoaded(e) {
    adsManager = e.getAdsManager(videoElement);
    adsManager.init(640, 360, google.ima.ViewMode.NORMAL);
    adsManager.start();
  }

  videoElement.addEventListener('play', function() {
    adDisplayContainer.initialize();
    init();
  }, { once: true });
</script>
</body></html>

MediaOnDemand / UVP

  1. Login → Playlists → Edit your playlist.
  2. Enable Monetization tab → set Ad Delivery Format to VAST XML.
  3. Paste your VAST URL into the VAST Tag field.
  4. Set Ad Position to Pre-roll, Mid-roll, or Post-roll and save.

6. VAST XML Structure Explained

When a player fetches your VAST URL it receives XML like this. Understanding it helps when debugging:

XML
<VAST version="3.0">
  <Ad id="ad-123">
    <InLine>
      <!-- Ad server name (informational) -->
      <AdSystem>Unlimited Text Ads</AdSystem>
      <AdTitle>My Video Campaign</AdTitle>

      <!-- Fires once when ad starts rendering in player -->
      <Impression></Impression>

      <Creatives>
        <Creative>
          <Linear>

            <!-- Total video length -->
            <Duration>00:00:30</Duration>

            <!-- User can skip after 5s (remove to make non-skippable) -->
            <SkipOffset>00:00:05</SkipOffset>

            <TrackingEvents>
              <Tracking event="start"></Tracking>
              <Tracking event="firstQuartile"></Tracking>
              <Tracking event="midpoint"></Tracking>
              <Tracking event="thirdQuartile"></Tracking>
              <Tracking event="complete"></Tracking>
            </TrackingEvents>

            <!-- Where user goes on click -->
            <VideoClicks>
              <ClickThrough></ClickThrough>
              <ClickTracking></ClickTracking>
            </VideoClicks>

            <!-- Actual video files, in order of preference -->
            <MediaFiles>
              <MediaFile type="video/mp4" width="1280" height="720"
                         bitrate="2000" delivery="progressive">
                
              </MediaFile>
            </MediaFiles>

          </Linear>
        </Creative>
      </Creatives>
    </InLine>
  </Ad>
</VAST>

7. Tracking Events

The player automatically fires HTTP GET requests (pixel pings) to the tracking URLs in the VAST XML at each of these moments. Each event is recorded in your dashboard:

impression
Ad rendered in player and begins buffering
start
First frame of ad video plays (≥ 1 second)
firstQuartile
25% of ad duration watched
midpoint
50% (halfway point) of ad watched
thirdQuartile
75% of ad duration watched
complete
Ad watched to 100% completion
click
User clicked the ad (ClickTracking)
skip
User clicked Skip Ad (VAST 3.0+)
mute / unmute
User toggled audio during ad
pause / resume
User paused/resumed during ad
fullscreen
User went fullscreen during ad
closeLinear
User dismissed overlay / companion
📊 All impression, click, and completion events are counted toward your publisher earnings and are visible in real time on your Click Analytics dashboard.

8. URL Parameters — Control Which Ads Play

Append these query parameters to your VAST URL to customise ad delivery per placement or per page.

ParameterRequired?ValuesDescription
publisher_idRequired32-char hex keyYour publisher key — identifies your account for earnings and tracking
positionOptionalpreroll, midroll, postrollTells the ad server which position ad should fill (default: preroll)
widthOptionalInteger pixelsPreferred video width. Ad server picks the closest matching media file (default: 1280)
heightOptionalInteger pixelsPreferred video height (default: 720)
ad_idOptionalInteger IDForce a specific ad to play. Useful for previewing or guaranteed delivery
campaign_idOptionalInteger IDServe only ads from a specific campaign (rotated randomly)
placementOptionalPlacement codeLink to a placement. Enables 30% house-ad rotation for that placement owner
houseOptional0 or 1Set 1 to serve 100% house ads for the placement (requires placement)
urlOptionalURL-encoded page URLReferring page URL for geo/context targeting. Auto-captured by referer header if omitted
ipOptionalIPv4 / IPv6Override visitor IP for geo-targeting (useful for server-side VAST proxy setups)

Example URLs

URLs
# Default — serve random active video ad
https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_KEY

# Pre-roll at 1920×1080 resolution
https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_KEY&position=preroll&width=1920&height=1080

# Mid-roll: fires at whatever time the player requests
https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_KEY&position=midroll

# Only ads from campaign 42
https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_KEY&campaign_id=42

# Force a specific ad (by ID) — for testing
https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_KEY&ad_id=7

# Placement with 30% house ads, 70% network ads
https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_KEY&placement=PLC_XXXXXX

# Force 100% house ads for a placement
https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_KEY&placement=PLC_XXXXXX&house=1

9. Testing & Validation Tools

Quick test with curl

Shell
# Fetch and pretty-print your VAST XML
curl -s "https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY" | xmllint --format -

# Check HTTP status code only
curl -o /dev/null -s -w "%{http_code}" "https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY"

# Follow redirects (for VAST Wrapper chains)
curl -L -s "https://unlimitedtextads.com/api/vast.php?publisher_id=YOUR_PUBLISHER_KEY" | xmllint --format -

A valid response returns HTTP 200 with Content-Type: application/xml and starts with <VAST version=. An empty VAST (no active ads) still returns 200 with an empty <VAST></VAST> document — this is correct IAB behaviour.

10. Troubleshooting

SymptomMost likely causeFix
Empty VAST / no ad playsNo active video ads in the systemCreate an active video ad with a valid MP4 URL in the Ads page
Video loads but won't playMedia file is HTTP not HTTPS, or not MP4Ensure the media URL is HTTPS and encodes as H.264 / AAC MP4
CORS error in browser consoleServer blocks cross-origin VAST requestsOur server sends Access-Control-Allow-Origin: *. If error persists, check your hosting's WAF rules
Impression tracked but no click earningsClick tracking URL not pinged by playerEnsure ClickTracking is present in VAST XML (curl and inspect). Some lightweight players skip this.
Duration shows 0:00Video file has no duration metadataRe-encode with FFmpeg: ffmpeg -i input.mp4 -c copy -movflags +faststart output.mp4
VAST wrapper chain error3+ wrapper hops timing outTest each VAST URL in the wrapper chain individually using curl
Ads not serving on mobileSome mobile browsers block autoplayAdd muted attribute and use playsinline on video element. Use IMA SDK v3.550+
Skip button not showingPlayer doesn't support VAST 3.0 skipUpgrade to JW Player 8+ or use Google IMA SDK

11. Frequently Asked Questions

Do I need to install anything as a publisher?
No. You only need a video player that accepts a VAST tag URL. Paste your URL into the player's advertising settings and you're done. No SDK, plugin, or backend changes required.
As an advertiser, what video format do I need to upload?
We recommend MP4 (H.264 video, AAC audio) for maximum compatibility. Supported: MP4, WebM, MOV. Minimum resolution 320×240, recommended 1280×720 or higher. Files must be hosted on a publicly accessible HTTPS URL.
What's the difference between pre-roll and mid-roll?
Pre-roll: ad plays before the main content starts. Mid-roll: ad plays at a specific timestamp during content (e.g., 30 seconds in). Post-roll: ad plays after content ends. Pre-roll typically has the highest completion rate and CPM.
Can I serve multiple ads in sequence (ad pod)?
Ad pods (multiple ads in one slot, like TV ad breaks) are supported from VAST 3.0 onwards. Contact support to enable pod scheduling on your account.
How does earnings work for video ads?
Publishers earn credits on each tracked impression (when the ad starts playing) and on each click. Video ads typically earn higher CPM than text ads because they hold user attention longer. Earnings are visible in real time on your dashboard.
Can I use a third-party VAST tag (not mine) as an advertiser?
Yes. When creating a video ad, you can enter an external VAST tag URL instead of uploading a file. Our server will wrap it and handle impression/click attribution on our side.
Is there a way to test VAST without a live video player?
Yes — paste your VAST URL into the Google IMA Video Suite Inspector. It will parse the XML, show all creatives, and let you play the ad in a sandboxed environment.
🎬

Ready to run video ads?

Create a video campaign as an advertiser, or paste your VAST URL into your video player as a publisher to start earning.