SSAI vs CSAI is the delivery comparison that decides what an impression beacon means. Client-side ad insertion leaves the VAST on the device. The player requests the tag, chooses a media file, plays it beside or instead of the content, and fires impression and quartile URLs from that device. Server-side ad insertion moves the fetch upstream. A stitcher requests the tag, splices the creative into the content stream, and gives the device one continuous video. The device may never parse the XML. Who fires the beacon is then a choice: the device, if the stitcher passed tracking metadata down, or the stitcher itself, on the device's behalf.
Those are not two flavors of the same count. A beacon from the device carries the device's address, user agent, and the player's idea of progress. A beacon from the stitcher carries the stitcher's address unless someone forwarded the device context on purpose. Fraud models that treat a data-center IP plus a server user agent as invalid will flag the second pattern. The MRC's IVT addendum lists server-side ad insertion spoofing among falsified measurement events in the sophisticated category. Legitimate SSAI and spoofed SSAI can look alike if the beacon is all you have.
The creative file can be identical. The measurement is not. Remove the acronyms and a pixel fired by the box that played the ad is still a different event from a pixel fired by the server that spliced it.

What client-side insertion measures
CSAI is the path VAST was first written for. The player is the client. It walks wrappers, applies media file selection, and emits tracking events when its own playhead crosses the thresholds. An impression URL that fires has at least been requested by something that parsed the document. Quartiles mean that playhead moved in that player. Viewability, if the player implements it, is a question about that player's surface.
The failures are the player's failures. A wrapper chain that times out on a phone never becomes an impression. A VPAID creative the device will not execute never starts. A missing mezzanine does not matter, because nobody is transcoding for a stitcher. QA that plays the tag in a browser is looking at a cousin of this path. It is a poor picture of SSAI, and it is a fair picture of CSAI on a similar runtime.
The fraud signal is also the device. Many impressions from one residential IP can be a household. The same pattern from one data center is not this path, unless a proxy is involved. A post-bid model trained on CSAI learns to trust device-shaped traffic. That training becomes a liability the moment the same tag is trafficked into a stitcher that beacons from its own hosts.
What server-side insertion measures
The stitcher fetches server-side, so wrapper depth and redirect latency are spent in a data center. It selects or transcodes a media file to match the content stream. VAST 4 added Mezzanine for that consumer: a high-quality source to transcode, rather than an already-compressed progressive file blown up to living-room size. The device then plays a stream that already contains the ad. Progress events, if the device reports them at all, are about the combined stream.
Tracking has two modes, and the mode is the measurement. In client-side beaconing the stitcher still tells a player SDK which URLs to fire, and the device fires them. In server-side beaconing the stitcher fires impression and quartiles itself. Server-side beaconing can mark a quartile when the stitcher has inserted that many seconds, including when the television is off, the app is backgrounded, or the device never confirmed a frame. The impression pixel has not become a lie in the XML. It has changed authors.
Macros make the authorship visible when they are filled. A device identifier, a user agent, and an IP forwarded from the client tell the measurement vendor the stitcher is speaking for a device. Empty macros, or macros filled with the stitcher's own values, tell the vendor a server generated the event. Teams that compare SSAI and CSAI completion rates without knowing which mode fired the URL are comparing a playhead to a splice clock.
Why the same tag produces two fraud stories
A verification vendor that sees thousands of impressions from one data-center range will often call them general invalid traffic. That call is correct for a botnet and incorrect for a stitcher beaconing server-side without forwarding the client. The engineering fix is configuration: forward the device address and user agent on every server-fired beacon. The reporting fix is a split by delivery path. An IVT rate that mixes CSAI device beacons and SSAI server beacons will move when the mix moves, even if the audience does not.
The other direction is spoofing. A caller can claim to be a stitcher, fire quartile URLs, and never have spliced anything. The MRC lists that under sophisticated invalid traffic because a routine data-center list cannot separate a real stitcher from a pretend one. Both come from servers. The difference is authorization and evidence that a device was in the path. Pre-bid fields that say "CTV" do not settle it. Post-bid beacons that all look like servers do not settle it either, unless the forwarded device context is present and consistent.
QA has to follow the author of the beacon. Validating the tag you uploaded tells you the document you handed the stitcher. It does not tell you what the stitcher emitted, which media file it selected, or whether it rewrote the trackers. Validating only in a browser tells you the CSAI cousin. The production question is the served result on the path you actually buy.
Get VAST spec updates, platform guides, and release notes in your inbox.
What to do with the two paths
Name the beacon author on every CTV line. Device-fired or stitcher-fired. If it is stitcher-fired, confirm the device IP and user agent are forwarded. Compare IVT, completion, and viewability inside one mode before you compare SSAI with CSAI. A gap between modes is an instrumentation gap until a playback gap is proven.
Keep a mezzanine or a stitcher-approved master on tags that enter SSAI, and keep a device-playable progressive file on tags that enter CSAI. One file that satisfies a browser preview can fail the stitcher's transcoder and still be the only file a phone player needed. The path chooses the file. The file does not choose the path.
vastlint does not detect stitcher spoofing and does not know whether a beacon host is a real stitcher. It checks the document: media files, mezzanine presence, HTTPS, wrapper depth, and tracker consistency for VAST 2.0–4.4. Run it on the tag you ship and, when you can capture it, on the tag the stitcher actually requested. The second run is the SSAI document. The first run is only the CSAI-shaped input.
Questions that decide which count you have
- Does the device parse the VAST, or only play a stitched stream?
- Who requests the impression and quartile URLs, the device or the stitcher?
- If the stitcher fires them, are the device address and user agent forwarded?
- Is there a mezzanine for the stitcher and a progressive file for the device player?
- Are IVT and completion reported separately for server-fired and device-fired paths?
The impression URL can be identical and still mean a playhead on the device or a clock on the stitcher.
Validate the tag each path will actually fetch
Run VAST 2.0–4.4 tags against specification-derived rules so media files, mezzanine, and trackers are consistent before a stitcher or a device player rewrites the path. Nothing is stored.
Open the VAST validatorSources
MRC places SSAI spoofing among falsified measurement events in the sophisticated invalid category.
What a stitcher does to wrappers, media files, and beacons between QA and the screen.
Why a data-center list cannot tell a stitcher from a botnet by itself.