Three copies, three checks
Stop when you know which copy failed. Do not send the creative team a player bug that was an unresolved macro.
| Copy | Check | Typical failure | Who can fix it |
|---|---|---|---|
| XML attached to the email | Validator | Missing Impression, bad Duration, VPAID where the line is CTV, no verification block the client required | Creative or the team that exported the file |
| URL in the ad server line item | Tester | The URL errors, returns HTML, or serves a different version than the attachment | Whoever owns that endpoint |
| The chain behind that URL | Inspector | A wrapper drops MediaFiles, trackers, or AdVerifications on a later hop | The wrapper owner, often not the creative team |

A trafficker is the person who puts a tag into a line item and is blamed when it does not serve. The tag arrives as an attachment, a cell in a sheet, or a URL another team swears was tested. Those are not interchangeable. The player, and the stitcher in front of the player, will request the URL. They will not open the email. If you validate only the attachment, you have checked a document that may never be fetched.
The pass is three steps because the failures belong to different people. The attachment is the creative export. The URL is the ad server or the vendor host. The chain is every hop after the first response. Sending one screenshot of one of them to all three owners wastes the launch window. vastlint splits the same way: the validator reads XML you already have, the tester fetches a URL, the inspector walks hops.
The attachment, including macros that are not real yet
Paste the file into the validator before you paste the URL anywhere. You are looking for a document that declares a VAST version and then violates it: no Impression where the version requires one, a MediaFile with no delivery type, a Duration that will not parse, a VPAID media file on a line you already know is a television or an SSAI stitch, a verification block the client paid for and the export omitted. Those are reasons to send the file back. They are not reasons to start a player ticket.
Macros are the other reason the attachment lies. A file full of bracketed cachebusters and click placeholders is what the creative tool exported. The ad server fills them at request time. Validating that file tells you the skeleton. It does not tell you the filled URL will be https, or that the click macro will land on a host the publisher allows. If the only copy you have is unfilled, say so in the note. Do not treat a clean skeleton as a clean line item.
If the client required a named verification vendor, this is the pass where you look for that vendor string. Absence here is already a problem. Presence here is not presence after the wrapper. Do not close the ticket on the attachment.
The URL, and then the chain
Put the URL that will be in the line item into the tester, not a URL from a previous campaign that happens to look similar. You want the status, the content type, and whether the body is VAST. A 200 that returns an HTML error page is a failed tag. A VAST response that is a Wrapper is not finished work. The creative the player needs is at the end of the chain, on another host.
Inspect that wrapper. The usual break is a hop that returns another wrapper until depth or timeout, a VASTAdTagURI that is empty once macros are considered, or an inline that no longer carries the trackers and the verification block you saw on hop one. The impression can still fire on the first hop. The measurement the client bought can be on a hop that never arrives. Write down the hop number. The person who owns hop three is often not the person who sent the email.
Then stop. A tag that survives this pass can still fail on a Roku or a Samsung panel because the MediaFile profile is wrong, or because the mezzanine an SSAI stitcher needs is absent. That is the CTV-after-QA problem, and it is a different checklist. Do not pretend the browser pass was the device pass. Do tell the next person the structural pass is clean, and name what you did not run.
Get VAST spec updates, platform guides, and release notes in your inbox.
What you send back
To the creative team: the validator findings on their file, and nothing about wrapper hosts they do not operate. To the tag vendor or the ad server owner: the URL status and the hop that broke. To the verification manager: which vendor strings survived to the inline. To yourself: the line item still gets the URL you tested, not a newer URL someone dropped in the sheet an hour later.
You are not the fraud report. A direct IO can still be full of invalid traffic, and you will not see that in the XML. Your reject list is the document and the chain. Their reject list is the measurement after it serves.
Before the line item is saved
- Validator on the attachment. Note if macros are still unfilled.
- Tester on the exact URL that will be trafficked.
- Inspector if the first body is a Wrapper. Record the hop that lost MediaFiles, trackers, or AdVerifications.
- Verification strings the client required, checked on the inline, not only on hop one.
- Device and SSAI playback: not this pass. Say that in the handoff.
Start with the copy the player will request
Paste XML into the validator, or a live tag URL into the tester. Nothing is stored.
Sources
Why a single URL fetch is not the hop-by-hop chain.
What this pass does not cover once the tag reaches a television.
The client-side pass on the same tag, limited to the verification block.
The ad-server-specific list once the structural pass is clean.