{
  "posts": [
    {
      "slug": "vendor-ivt-figures",
      "title": "IAS, DoubleVerify, Pixalate, and HUMAN publish numbers that do not share a scale",
      "description": "Each pair opens the note with firm, figure, unit, population, surface, and date.",
      "seoTitle": "IAS, DoubleVerify, Pixalate, and HUMAN do not share a scale",
      "seoDescription": "Each pair opens the note with firm, figure, unit, population, surface, and date.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "4 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each pair, in one row",
          "caption": "Each pair opens the note with firm, figure, unit, population, surface, and date.",
          "columns": [
            "Pair",
            "Split"
          ],
          "rows": [
            {
              "href": "/blog/ias-vs-doubleverify/",
              "cells": [
                "IAS vs DoubleVerify",
                "A click multiple beside a scheme count and a protected rate"
              ]
            },
            {
              "href": "/blog/pixalate-vs-doubleverify/",
              "cells": [
                "Pixalate vs DoubleVerify",
                "19 percent beside under 1 percent and nearly 9 percent"
              ]
            },
            {
              "href": "/blog/ias-vs-pixalate/",
              "cells": [
                "IAS vs Pixalate",
                "A click multiple beside 19 percent of US CTV"
              ]
            },
            {
              "href": "/blog/ias-vs-human/",
              "cells": [
                "IAS vs HUMAN",
                "A click multiple beside a flag on the bid"
              ]
            },
            {
              "href": "/blog/human-vs-pixalate/",
              "cells": [
                "HUMAN vs Pixalate",
                "A flag on the bid beside 19 percent of US CTV"
              ]
            },
            {
              "href": "/blog/doubleverify-vs-human/",
              "cells": [
                "DoubleVerify vs HUMAN",
                "A protected rate beside a suggestion the platform still applies"
              ]
            },
            {
              "href": "/blog/givt-vs-sivt/",
              "cells": [
                "GIVT vs SIVT",
                "Required list filtration beside an encouraged investigation"
              ]
            }
          ]
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "The pair notes keep the argument. This page is the index, and each row is the split those notes refuse to collapse.",
            "A second table answers the replacement searches: DoubleVerify alternative, Integral Ad Science alternative, Pixalate alternative, HUMAN alternative, and Moat alternative. IVT filtration is the removal from the counted metrics. The standard requires that removal on the back end, and it treats a pre-bid block as optional. A further set answers the question form, the stack, the old company name, and the rate itself: is DoubleVerify better than IAS, IAS and DoubleVerify together, White Ops vs DoubleVerify, and what a normal CTV IVT rate would even be. Another set is the cut inside the number: CTV IVT by device, whether direct CTV is free of fraud, why IAS and DoubleVerify disagree, and brand safety versus IVT. A further set is the unit people misread in a headline: the cost of CTV ad fraud, CTV fraud schemes, the mobile app IVT rate, and SSAI spoofing.",
            "vastlint is independent of IAS, DoubleVerify, Pixalate, and HUMAN. It checks VAST structure, and these notes compare published figures."
          ]
        },
        {
          "type": "table",
          "heading": "When the search is a replacement",
          "caption": "Each note names the job inside the suite, and the public artifact that can stand in for that job.",
          "columns": [
            "Query",
            "What stays in its own column"
          ],
          "rows": [
            {
              "href": "/blog/doubleverify-alternative/",
              "cells": [
                "DoubleVerify alternative",
                "A protected rate, a pre-bid segment, attention, and suitability"
              ]
            },
            {
              "href": "/blog/integral-ad-science-alternative/",
              "cells": [
                "Integral Ad Science alternative",
                "A named cluster and an avoidance list, which is also the Pixalate vs Integral Ad Science query"
              ]
            },
            {
              "href": "/blog/pixalate-alternative/",
              "cells": [
                "Pixalate alternative",
                "An open-auction share, a blocking list, and a post-bid log"
              ]
            },
            {
              "href": "/blog/human-security-alternative/",
              "cells": [
                "HUMAN alternative",
                "A suggestion on the bid, in a platform seat"
              ]
            },
            {
              "href": "/blog/moat-alternative/",
              "cells": [
                "Moat alternative",
                "A product that ended on September 30, 2024"
              ]
            },
            {
              "href": "/blog/ivt-filtration/",
              "cells": [
                "IVT filtration",
                "A required back-end removal, and a pre-bid block that stays optional"
              ]
            },
            {
              "href": "/blog/what-is-a-normal-ctv-ivt-rate/",
              "cells": [
                "A normal CTV IVT rate",
                "19 percent, under 1 percent, and nearly 9 percent are different logs"
              ]
            },
            {
              "href": "/blog/is-doubleverify-better-than-ias/",
              "cells": [
                "Is DoubleVerify better than IAS",
                "Better is a job: a protected rate, a named cluster, or an open-auction share"
              ]
            },
            {
              "href": "/blog/ias-and-doubleverify-together/",
              "cells": [
                "IAS and DoubleVerify together",
                "Two logs on one impression, and both nodes have to survive the tag"
              ]
            },
            {
              "href": "/blog/white-ops-vs-doubleverify/",
              "cells": [
                "White Ops vs DoubleVerify",
                "A 2021 rename to HUMAN, and a 2026 rate from a different firm"
              ]
            },
            {
              "href": "/blog/ctv-ivt-by-device/",
              "cells": [
                "CTV IVT by device",
                "Fire TV at 14 percent IVT, and 30 percent of large-screen spend, which is a different unit"
              ]
            },
            {
              "href": "/blog/is-direct-ctv-free-of-fraud/",
              "cells": [
                "Is direct CTV free of fraud",
                "Two named deals at 34 percent and 25 percent, beside a 19 percent open-auction share"
              ]
            },
            {
              "href": "/blog/why-ias-and-doubleverify-disagree/",
              "cells": [
                "Why IAS and DoubleVerify disagree",
                "Category, hop, population, or a verification node the wrapper dropped"
              ]
            },
            {
              "href": "/blog/brand-safety-vs-ivt/",
              "cells": [
                "Brand safety vs IVT",
                "A suitability tier and a fraud rate are different subtractions"
              ]
            },
            {
              "href": "/blog/cost-of-ctv-ad-fraud/",
              "cells": [
                "Cost of CTV ad fraud",
                "$1.8 million per billion impressions is the unprotected cell, not the market price"
              ]
            },
            {
              "href": "/blog/ctv-fraud-schemes/",
              "cells": [
                "CTV fraud schemes",
                "140 percent more schemes is a count, and the protected impression rate is under 1 percent"
              ]
            },
            {
              "href": "/blog/mobile-app-ivt-rate/",
              "cells": [
                "Mobile app IVT rate",
                "29 percent in the US and 36 percent globally, beside 19 percent US CTV"
              ]
            },
            {
              "href": "/blog/ssai-spoofing/",
              "cells": [
                "SSAI spoofing",
                "A falsified measurement event, and a legitimate stitcher also fires from a server"
              ]
            }
          ]
        }
      ]
    },
    {
      "slug": "verification-manager-checks-the-vast-tag",
      "title": "A Verification Manager Can Confirm the Node Is in the Tag, and Cannot Confirm the Vendor Scored the Impression",
      "description": "If you bought DoubleVerify, IAS, HUMAN, or Pixalate, the next artifact is the VAST tag trafficking will serve. vastlint checks whether AdVerifications is present and structurally consistent. It does not call the vendor, and it does not know that a Moat host died in 2024. A wrapper can keep one node and drop the other.",
      "seoTitle": "A verification manager checks the node in the tag, not the vendor score",
      "seoDescription": "Paste the VAST tag and see whether the verification node survived. vastlint does not score invalid traffic and does not know if the vendor host still answers.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Verification",
      "tags": [
        "Verification",
        "Ad ops",
        "VAST",
        "IVT"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "What you hold, and which check can see it",
          "caption": "The contract, the XML in the email, and the URL in the line item are three objects.",
          "columns": [
            "What you hold",
            "What to open",
            "What it can tell you",
            "What it cannot tell you"
          ],
          "rows": [
            {
              "cells": [
                "A VAST document",
                "Validator",
                "Whether Verification nodes are present and consistent",
                "Whether the vendor scored this impression"
              ]
            },
            {
              "cells": [
                "A live tag URL",
                "Tester",
                "The response that URL returns now, including media and trackers",
                "The chain of hops if the first response is a wrapper"
              ]
            },
            {
              "cells": [
                "A wrapper URL",
                "Inspector",
                "Each hop, and which hop dropped a node",
                "The IVT rate either firm will publish next week"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/verification-manager-checks-the-vast-tag.png?v=2",
          "alt": "A verification contract names a vendor. The trafficked tag may or may not still contain that vendor's Verification node after the wrapper chain.",
          "width": 1440,
          "height": 820,
          "caption": "The contract and the served document are different objects, and only the document can be checked before the impression.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "A verification manager is the person who chose the firm. The choice shows up in this site's other notes as DoubleVerify or IAS or HUMAN or Pixalate, and the notes stop at the published figures. The job that starts after the contract is quieter: the tag that will actually serve has to carry that firm's node, or the quarterly rate and the campaign report are about different inventories. You usually do not compile anything. You have an email, a tag sheet, and a line item.",
            "vastlint is the check on the document, not on the firm. Paste the XML into the validator when trafficking sent you the file. Paste the URL into the tester when the line item only has a request. Open the inspector when that request returns a wrapper, because the node can sit on the first hop and be gone on the inline the player plays. None of those three calls the vendor. A present node is a structure. A score is a later event from a host that answered."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What present means",
          "paragraphs": [
            "VAST 4 puts verification under AdVerifications, as Verification entries with a vendor, resources, and parameters. Older tags sometimes hide the same intent in an Extension. The validator's job is whether that structure is consistent with the version the tag declares: the container is allowed to hold Verification, the vendor identifier is not duplicated, the resource URLs are well formed. A duplicated vendor identifier is a structural fault. Two different vendors in two entries can both be legitimate, which is the case when the plan really is IAS and DoubleVerify together.",
            "Present does not mean the URL will answer. A Verification entry that still names Moat is a host Oracle stopped operating on September 30, 2024. The element can be well formed and still point at a service that will not score the impression. vastlint will not look up the business status of a vendor string. You bring the end-of-life list. The check brings the fact that the string is in the file.",
            "Present on the file in the email is not present on the inline. Wrapper chains exist so each hop can add or drop markup. If you were shown the buyer's original XML and the line item requests a different URL, you have not yet seen the document the player parses. That is the inspector's job: walk the hops and see which response still contains the node."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What you still cannot sign off",
          "paragraphs": [
            "You cannot sign off the invalid-traffic rate. A protected campaign under 1 percent, an open-auction share of 19 percent, and a named mobile cluster with a click multiple are studies of other logs. They do not become this campaign's result because the node is present. They also do not become a failure because the node is present and the firms later disagree. Disagreement on sophisticated invalid traffic is allowed by the MRC addendum. Disagreement because one node never arrived is a trafficking defect, and that is the defect this check is for.",
            "You cannot sign off playback. A tag can carry a correct verification block and a MediaFile the television will not select. Device QA is a later pass, and it is a different page. Mixing them produces the launch-week story where verification looked fine in a browser and the completion never fired on the set.",
            "You cannot sign off that both firms saw the impression when the plan was to run both. Count the entries after the chain resolves. One node means one log. The spreadsheet that lists two vendors is not evidence."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "A workable pass before you reply to trafficking",
          "paragraphs": [
            "Ask for both artifacts: the XML they intend, and the URL the ad server will call. If they can only send one, say which one you checked. Run that artifact. If the URL's first response is a Wrapper, do not stop. Inspect until the inline, or until the chain breaks. Then write the reply as a list of nodes found, nodes missing, and hosts you already know are dead. Leave the fraud rate out of that reply. It is not knowable from the file.",
            "If this is a one-off tag in a thread, the website is the whole tool. If the same class of tag ships every week from a repo, the check belongs in CI so the email is not the control. If a server sees the response before the player, the check belongs in that process. Those are different seats, and they are the next note."
          ]
        },
        {
          "type": "list",
          "heading": "Reply in these columns",
          "items": [
            "XML checked, URL checked, or both. Say which.",
            "Verification entries found after the chain, by vendor string.",
            "Entries required by the contract and absent.",
            "A host you know is retired, such as Moat after September 30, 2024, still sitting in a well-formed element.",
            "Anything about IVT rate, viewability, or suitability: not in this pass. The node has to exist before those reports can."
          ]
        },
        {
          "type": "cta",
          "heading": "Paste the tag trafficking will actually serve",
          "paragraph": "XML opens the validator. A live tag URL opens the tester. Nothing is stored. This does not call DoubleVerify, IAS, HUMAN, or Pixalate.",
          "href": "/validate/",
          "label": "Check the tag"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "How to validate AdVerifications in VAST tags",
              "href": "/blog/how-to-validate-adverifications-in-vast-tags/",
              "description": "What a missing or emptied verification node does to the measurement.",
              "source": "vastlint"
            },
            {
              "label": "OMID",
              "href": "/docs/omid/",
              "description": "How verification resources sit in the tag when the framework is OMID.",
              "source": "vastlint"
            },
            {
              "label": "Why IAS and DoubleVerify disagree",
              "href": "/blog/why-ias-and-doubleverify-disagree/",
              "description": "The gap that is a missing node, and the gap that is a real difference in sophisticated detection.",
              "source": "vastlint"
            },
            {
              "label": "Which vastlint surface matches the job",
              "href": "/blog/which-vastlint-surface-matches-the-job/",
              "description": "When a one-off paste should become CI or an in-process check.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "trafficker-checks-a-vast-tag-before-launch",
      "title": "A Trafficker Has Three Copies of the Tag, and Only the URL in the Line Item Is What the Player Will Request",
      "description": "The file in the creative email, the URL pasted into GAM or the DSP, and the chain that URL returns are not the same document. Validate the file you were sent. Test the URL that will be called. Inspect when the first response is a wrapper. Unresolved macros in a pasted file are not what production will send.",
      "seoTitle": "A trafficker checks the file, the line-item URL, and the chain",
      "seoDescription": "Before launch, validate the XML you were emailed, test the live tag URL, and inspect wrapper hops. The player requests the URL, not the attachment.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Ad ops",
      "tags": [
        "Ad ops",
        "VAST",
        "CTV",
        "Trafficking"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Three copies, three checks",
          "caption": "Stop when you know which copy failed. Do not send the creative team a player bug that was an unresolved macro.",
          "columns": [
            "Copy",
            "Check",
            "Typical failure",
            "Who can fix it"
          ],
          "rows": [
            {
              "cells": [
                "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"
              ]
            },
            {
              "cells": [
                "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"
              ]
            },
            {
              "cells": [
                "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"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/trafficker-checks-a-vast-tag-before-launch.png?v=2",
          "alt": "Three copies of a VAST tag: the email attachment, the URL in the line item, and the wrapper chain that URL returns. Only the chain is what the player requests.",
          "width": 1440,
          "height": 820,
          "caption": "QA on the attachment does not QA the request the player will make.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "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."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The attachment, including macros that are not real yet",
          "paragraphs": [
            "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."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The URL, and then the chain",
          "paragraphs": [
            "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."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What you send back",
          "paragraphs": [
            "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."
          ]
        },
        {
          "type": "list",
          "heading": "Before the line item is saved",
          "items": [
            "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."
          ]
        },
        {
          "type": "cta",
          "heading": "Start with the copy the player will request",
          "paragraph": "Paste XML into the validator, or a live tag URL into the tester. Nothing is stored.",
          "href": "/validate/",
          "label": "Check the tag"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "The tester is not the inspector",
              "href": "/blog/vast-tester-is-not-the-inspector/",
              "description": "Why a single URL fetch is not the hop-by-hop chain.",
              "source": "vastlint"
            },
            {
              "label": "Why CTV VAST tags still fail after QA",
              "href": "/blog/why-ctv-vast-tags-fail-after-qa/",
              "description": "What this pass does not cover once the tag reaches a television.",
              "source": "vastlint"
            },
            {
              "label": "A verification manager checks the node",
              "href": "/blog/verification-manager-checks-the-vast-tag/",
              "description": "The client-side pass on the same tag, limited to the verification block.",
              "source": "vastlint"
            },
            {
              "label": "VAST 4.3 launch checklist for GAM and IMA",
              "href": "/blog/vast-4-3-launch-checklist-for-gam-and-ima/",
              "description": "The ad-server-specific list once the structural pass is clean.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "publisher-checks-an-advertiser-vast-tag",
      "title": "A Publisher Can Reject an Advertiser's VAST Tag from the Document, and Cannot See Whether the Direct Buy Is Full of Bots",
      "description": "Publisher ad ops receiving a direct or programmatic-guaranteed tag are the last people before the player or the stitcher. Missing impressions, insecure media, VPAID on a CTV line, a mezzanine the stitcher needs and does not have, and a verification node the buyer required: those are reject reasons. A fraud rate is not in the file. Direct is not a rate of zero.",
      "seoTitle": "A publisher rejects an advertiser VAST tag from the document, not from a fraud rate",
      "seoDescription": "Check the advertiser's VAST before it hits the player or the stitcher. You can reject a broken document. You cannot see the invalid-traffic rate from the XML.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Publisher ad ops",
      "tags": [
        "Ad ops",
        "VAST",
        "CTV",
        "Programmatic"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Reject, send back, or pass to the stitcher",
          "caption": "Each row is something the document can show. The fraud rate is not in the table because the document does not contain it.",
          "columns": [
            "What you see",
            "Decision",
            "Why",
            "What you tell the buyer"
          ],
          "rows": [
            {
              "cells": [
                "No usable Impression, or a MediaFile the version cannot describe",
                "Reject",
                "The player will not record or select the ad",
                "The export does not match the VAST version it declares"
              ]
            },
            {
              "cells": [
                "Media or trackers on http while the app is https",
                "Reject",
                "The runtime blocks mixed content and the beacons never land",
                "Move every asset and tracker to https"
              ]
            },
            {
              "cells": [
                "VPAID on a CTV or SSAI line",
                "Send back",
                "The interactive runtime is not the television",
                "Send a media file the player can decode, and SIMID only if you both support it"
              ]
            },
            {
              "cells": [
                "SSAI line and no mezzanine the stitcher can transcode",
                "Send back",
                "The stitch has nothing to work with",
                "Add the mezzanine profile your spec asks for"
              ]
            },
            {
              "cells": [
                "Buyer required a verification vendor and the inline lacks it",
                "Send back",
                "Their report will not include this inventory",
                "The node has to survive your wrappers too"
              ]
            },
            {
              "cells": [
                "A clean document on a direct IO",
                "Pass the structure",
                "You still have not measured invalid traffic",
                "Direct is a path. It is not a fraud rate of zero"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/publisher-checks-an-advertiser-vast-tag.png?v=2",
          "alt": "A publisher receives an advertiser VAST tag, checks the document, and either sends it back or lets it reach the stitcher and the player. The invalid-traffic rate is not visible in that document.",
          "width": 1440,
          "height": 820,
          "caption": "The reject you can make is structural. The fraud rate arrives later, from a vendor, on impressions that actually served.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Publisher ad ops on a direct or programmatic-guaranteed deal are the last people who can refuse a tag before a player or a stitcher has to eat it. The advertiser, or their agency, sends a URL or a file and a start date. Your player will request whatever you put in the ad server. If the file is wrong, the symptom later is a dark pod, a discrepancy, or a buyer who says verification did not fire. The symptom is a bad place to discover a missing Impression.",
            "You are not the buyer's fraud vendor. DoubleVerify's May 2026 release described two direct CTV campaigns, one at 34 percent of impressions to bots and one at 25 percent. Those are examples from their log, not a property you can read off the advertiser's XML. Pixalate's 19 percent is an open-auction CTV share, and a direct buy is outside that sentence, which is also not a rate of zero. Rejecting a tag because of a headline rate rejects a population you did not measure. Accepting a tag because the IO says direct accepts a path, not a document."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The reject list that is actually in the file",
          "paragraphs": [
            "Run the file or the URL before it is booked on the pod. A document that declares VAST and then omits an Impression the version requires will not produce the beacon your reconciliation expects. A MediaFile the declared version cannot carry, or a delivery type the player will not select, fails at creative choice rather than at the business deal. Insecure URLs on a secure app fail quietly: the player drops the request, the impression pixel never lands, and the buyer sees a short delivery against a signed goal.",
            "VPAID is the interactive case that still arrives on CTV lines because the creative tool defaulted to it. The IAB deprecated it. A television and a stitcher are the wrong runtime. Send it back for a media file, and treat SIMID as a separate conversation you have already agreed, not as a synonym for VPAID. If your path is server-side insertion, also look for a mezzanine. A single web-weight progressive file can look valid and still give the stitcher nothing to transcode.",
            "The buyer's verification node is their requirement, not yours, until you have agreed to carry it. If the IO says the campaign is measured by a named firm, look for that firm on the inline after your own wrappers. Publishers add hops. A node that exists in the advertiser's original file and disappears inside your ad server is your defect, and their report will describe it as unmeasured inventory. vastlint will show whether the node is in the document you test. It will not call the firm."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What you pass through, and what you automate",
          "paragraphs": [
            "A clean structural pass means the player has a chance. It does not mean the encode will play on every device in your app, and it does not mean the campaign is free of invalid traffic. Say both of those in the acceptance note so the buyer's verification team does not treat your OK as a fraud sign-off. Point them at their own node, which you either carried or you did not.",
            "One tag a week can live on the website: validate, test, inspect. A direct sales team that onboards tags every day will not keep the habit. That volume is a fixture in a repo, checked in CI, or a check inside the ad server before the response is committed. The website remains the place a person debugs the one tag CI rejected. The gate should not be a person remembering a tab.",
            "If the tag is a wrapper into the advertiser's host, inspect it. Your player will. A wrapper that never resolves is a dark pod you could have seen without a regression on the device lab."
          ]
        },
        {
          "type": "list",
          "heading": "Acceptance note, in one pass",
          "items": [
            "Document or URL tested, and whether your own wrapper was included.",
            "Structural result: impressions, media, https, version consistency.",
            "CTV or SSAI extras you require: no VPAID, mezzanine present if the stitcher needs it.",
            "Verification vendor the IO names, present or absent on the inline.",
            "Explicitly out of scope: invalid-traffic rate, viewability, whether every device in the app will select the file."
          ]
        },
        {
          "type": "cta",
          "heading": "Check the advertiser tag before it is booked",
          "paragraph": "Paste the XML or the live URL. Nothing is stored. This does not classify invalid traffic.",
          "href": "/validate/",
          "label": "Check the tag"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Is direct CTV free of fraud",
              "href": "/blog/is-direct-ctv-free-of-fraud/",
              "description": "Why a direct path is not a fraud rate of zero, and why the 34 percent figures are single campaigns.",
              "source": "vastlint"
            },
            {
              "label": "Why CTV VAST tags still fail after QA",
              "href": "/blog/why-ctv-vast-tags-fail-after-qa/",
              "description": "Device failures that remain after the document is structurally clean.",
              "source": "vastlint"
            },
            {
              "label": "Which vastlint surface matches the job",
              "href": "/blog/which-vastlint-surface-matches-the-job/",
              "description": "When publisher volume should leave the website and enter CI or the ad server.",
              "source": "vastlint"
            },
            {
              "label": "A trafficker checks three copies of the tag",
              "href": "/blog/trafficker-checks-a-vast-tag-before-launch/",
              "description": "The agency-side pass on the same three artifacts.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "which-vastlint-surface-matches-the-job",
      "title": "The vastlint Surface You Install Depends on Whether You Hold a Tag, a Repository, or the Response",
      "description": "Evaluating vastlint means picking a surface. A tag in a thread is the website. A folder of fixtures that must not regress is the CLI in CI, where vastlint check exits non-zero and can fail on warnings. A service that sees VAST before the player is an in-process check, including vastlint-go on each hop. None of these classify invalid traffic or prove a television played the file.",
      "seoTitle": "Which vastlint surface you install depends on the artifact you hold",
      "seoDescription": "Use the website for one tag, vastlint check in CI for a repo of fixtures, and an in-process library when a server sees the response. None of them classify IVT.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Evaluation",
      "tags": [
        "VAST",
        "Ad server",
        "Ad ops",
        "CI"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "The artifact decides the install",
          "caption": "Install the surface that sees the tag at the moment you are allowed to reject it.",
          "columns": [
            "What you hold",
            "Surface",
            "Who runs it",
            "What it will not do"
          ],
          "rows": [
            {
              "cells": [
                "One tag in a thread or a ticket",
                "Website: validate, tester, inspector",
                "A person, once",
                "It will not remember the next tag"
              ]
            },
            {
              "cells": [
                "A repository of tag fixtures",
                "CLI in CI",
                "The build",
                "It will not fetch a production URL unless you ask a separate step to"
              ]
            },
            {
              "cells": [
                "The VAST response inside a server",
                "In-process library",
                "The bid path, the ad server, or the stitcher",
                "It will not play the creative on a device"
              ]
            },
            {
              "cells": [
                "An agent setting up campaigns",
                "MCP",
                "The agent, as a tool call",
                "It will not replace the human pass on a wrapper you have not fetched"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/which-vastlint-surface-matches-the-job.png?v=2",
          "alt": "Four ways to run vastlint: paste a tag on the website, fail a build in CI, validate inside the ad server, or call it from an agent. The artifact you hold picks the surface.",
          "width": 1440,
          "height": 820,
          "caption": "The same rules can run in four places. The place has to be where the tag exists before you are committed to serving it.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Someone evaluating vastlint is usually one of four seats, and they are easy to mix because the rules are the same. A verification manager holds a tag in a thread. A trafficker holds a URL and an attachment. A publisher ad ops lead holds advertiser tags arriving all week. A platform engineer holds the response inside a process that will either forward it or drop it. The website satisfies the first two on a slow day. It does not satisfy the last two, because a person with a tab is not in the path.",
            "Pick the surface from the artifact at the moment you can still reject it. If that moment is a ticket, use the website and write down what you checked. If that moment is a pull request, the CLI belongs in CI. The CI doc shows vastlint check on a path of XML files, with --fail-on-warning when a warning should fail the build, a GitHub Action that wraps the binary, and a container image for GitLab. No Rust toolchain is required to run the check. If that moment is the process that already fetched the demand or the advertiser tag, the library belongs in that process. The Go note walks a chain: fetch a hop, validate it, unwrap only when the wrapper is sound, stop at a depth limit. The ad server doc is the same idea for an SSP, a DSP, or a stitcher that cannot pay a network round trip for the check."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the website is for",
          "paragraphs": [
            "The website is a single tag, in front of a person who can read the result. Validate when you already have XML. Test when you have a URL and need the body, the media, and the trackers that URL returns now. Inspect when the body is a wrapper and the failure is on a later hop. That split matters. A tester result that looks fine on hop one is how a dropped verification node survives until the buyer complains.",
            "Do not make the website the control for a team that ships tags daily. It has no memory of yesterday's tag, and it is not on the request path. It is the debugger for the tag the other surfaces rejected, and the only surface a non-engineer will open. The verification manager and the trafficker notes are that use. Send engineers elsewhere."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What CI is for",
          "paragraphs": [
            "CI is a tree of files you are willing to store. Creative fixtures, golden wrappers, tags exported from a template. vastlint check exits non-zero when there are errors, so the build fails. --fail-on-warning is how you treat the advisory class as a break when you have decided those advisories cost money. The files in the repo are the contract. A production URL that changes under you is not in that contract unless a job fetches it and writes the body where the checker can see it.",
            "This is the right install for a creative pipeline and for a publisher or an agency that wants a known-bad tag to fail review before a person trafficks it. It is the wrong install for a bid response that exists for a few hundred milliseconds and is never a file. Do not staff an engineer to commit every demand response so CI can look at it."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What in-process is for",
          "paragraphs": [
            "In-process is the response you already have in memory. An ad server accepting programmatic demand, a stitcher about to insert, a DSP checking a creative before it bids. The Go integration validates each fetched hop instead of waiting for the player to discover a malformed body, and it can keep stable rule IDs so partner quality is a trend rather than a screenshot. The ad server page describes embedding the same core in Rust, Go, or Elixir, including an OTP port when the BEAM service must survive a bad response. The latency claim on that page is a measurement of the checker on stated tag sizes, not a promise about your whole bid. Read it as a budget inside the time you already spend, and measure your own tags.",
            "In-process will not fetch a wrapper unless your code fetches it. Validating the first hop and forwarding a wrapper you did not open repeats the trafficker's mistake inside a service. If you unwrap, validate again. If you do not unwrap, do not claim you checked the inline.",
            "An agent that sets up campaigns is a fourth seat. MCP is a tool call the agent can make, so the check is not a tab someone remembers. It is still only as good as the document or URL the agent passed. The ad ops MCP note is that workflow. It does not remove the wrapper walk."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What you should refuse to buy it for",
          "paragraphs": [
            "None of the surfaces classify invalid traffic, score viewability, or decide brand suitability. A clean result is not a DoubleVerify report and not a Pixalate benchmark. None of them prove a television played the file. Device labs and the stitcher's own transcoder logs do that. Buying the embed because a slide said CTV fraud was 19 percent is a category error: the 19 percent is someone else's log, and the embed is a structural gate on your responses.",
            "Evaluate with one hostile tag from your own traffic: a wrapper, an insecure media file, a missing verification node your buyers require, a VPAID file on a CTV fixture. Run it on the website so a non-engineer can see the result. Run the same file in CI so the build fails. If you are the service, run it in process on the hop you actually forward. If those three agree, you understand the install. If they do not, you are checking different documents and calling it one product."
          ]
        },
        {
          "type": "list",
          "heading": "Questions that pick the surface",
          "items": [
            "At the moment we can still reject the tag, is it in a ticket, a git tree, or a running process?",
            "Do we need the first body, or the inline at the end of the wrappers?",
            "Should a warning fail the build, or only an error?",
            "Are we promising a fraud number? If yes, this is the wrong tool.",
            "Who debugs the reject? They get the website. The path that must not forget gets CI or the process."
          ]
        },
        {
          "type": "cta",
          "heading": "Try the one-tag surface before you install anything",
          "paragraph": "Paste XML or a live URL. If the result is the reject you wanted, the same rules are what CI and the in-process check run. Nothing is stored.",
          "href": "/validate/",
          "label": "Check the tag"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Validate VAST in CI",
              "href": "/docs/validate-vast-in-ci/",
              "description": "GitHub Actions, GitLab, pre-commit, and Docker. vastlint check exits non-zero on errors.",
              "source": "vastlint"
            },
            {
              "label": "Using vastlint-go in ad serving components",
              "href": "/blog/using-vastlint-go-in-ad-serving-components/",
              "description": "Validate each fetched hop before you forward programmatic demand.",
              "source": "vastlint"
            },
            {
              "label": "Embedding vastlint in an SSP, DSP, or ad server",
              "href": "/docs/ad-server-integration/",
              "description": "In-process checks for a service that already holds the response.",
              "source": "vastlint"
            },
            {
              "label": "MCP preflight for ad ops",
              "href": "/blog/mcp-preflight-for-ad-ops-teams/",
              "description": "When the caller is an agent and the check has to be a tool call.",
              "source": "vastlint"
            },
            {
              "label": "A verification manager checks the node",
              "href": "/blog/verification-manager-checks-the-vast-tag/",
              "description": "The one-tag seat that should stay on the website.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "cost-of-ctv-ad-fraud",
      "title": "The Cost of CTV Ad Fraud in the May 2026 Release Is an Estimate on Unprotected Campaigns, Not a Price for the Market",
      "description": "How much CTV ad fraud costs, and the invalid-traffic cost per billion impressions. DoubleVerify's May 7, 2026 estimate is about $1.8 million per billion impressions on unprotected campaigns, and it calls that conservative. Pixalate's $6.9 billion is open-programmatic CTV spend beside a 21 percent rate, which is not a loss figure. IAS's roughly $1 million a month is one named mobile scheme.",
      "seoTitle": "Cost of CTV ad fraud lines up $1.8 million per billion on unprotected campaigns",
      "seoDescription": "DoubleVerify estimates about $1.8 million per billion CTV impressions on unprotected campaigns. That is not Pixalate's $6.9 billion spend figure, and it is not the cost of all CTV.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published dollar, in one row",
          "caption": "An estimated waste on unprotected campaigns, a spend total, and one scheme's monetization sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "DoubleVerify",
                "About $1.8 million per billion impressions",
                "Estimated cost",
                "Unprotected CTV campaigns",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud nearly 9%",
                "Impression share",
                "Controls off, the cell the estimate describes",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "$6.9 billion",
                "Ad spend",
                "Global open programmatic CTV, beside a 21% IVT rate",
                "CTV",
                "March 26, 2026"
              ]
            },
            {
              "cells": [
                "IAS",
                "Close to $1 million a month",
                "Scheme monetization",
                "Papyrus at the peak, from an observed eCPM",
                "Mobile",
                "August 6, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/cost-of-ctv-ad-fraud.png?v=2",
          "alt": "DoubleVerify's $1.8 million per billion impressions is an estimate for unprotected CTV campaigns. Pixalate's $6.9 billion is open-programmatic spend. IAS's $1 million a month is one mobile scheme.",
          "width": 1440,
          "height": 820,
          "caption": "Three dollar figures from three populations. Multiplying a rate by a spend total builds a fourth number nobody published.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Cost of CTV ad fraud is the search that wants a single invoice. People also type how much invalid traffic costs, CTV fraud cost per billion impressions, and what unprotected campaigns waste. The figure that matches the per-billion shape is in DoubleVerify's May 7, 2026 release: fraud in unprotected campaigns can cost about $1.8 million per billion CTV impressions served, and DoubleVerify calls that a conservative estimate. The cell next to it is the nearly 9 percent fraud rate where protection controls were not applied. The under-1-percent rate is the other cell, controls on, and the estimate is not written for that cell.",
            "Two other dollars travel in the same conversation and are not this estimate. Pixalate's March 26, 2026 supply-chain note puts $6.9 billion next to global open programmatic CTV ad spend, and 21 percent invalid on more than 7 billion transactions. Spend beside a rate is not the product of the rate and the spend. IAS's Papyrus note, August 6, 2026, puts monetization near $1 million a month at the peak for one mobile scheme, by applying an observed eCPM to a broader impression footprint. A month of one cluster is not a billion CTV impressions.",
            "vastlint does not price invalid traffic. It checks whether a VAST 2.0–4.4 tag can carry the verification and the impression events a cost model would have to read. A tag that drops the node is unmeasured, which is not the same as a computed $1.8 million."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the $1.8 million is allowed to say",
          "paragraphs": [
            "It is an estimate, on unprotected campaigns, per billion impressions served, from the firm whose controls define unprotected in that release. Conservative, in DoubleVerify's wording, means the firm thinks the number is not high. It does not mean the number is a census of CTV, and it does not mean a buyer with controls on should book $1.8 million of waste. The protected cell is the evidence the control is the thing being priced. Turn the control on, in that study, and the fraud rate they publish is under 1 percent. The dollar is the story of the off switch.",
            "It is also not a CPM you can audit from the outside. An estimate per billion impressions folds price, the fraud share, and whatever they excluded into one product. You cannot back into their 9 percent from $1.8 million without their price assumption, and they did not ask the reader to. Quoting the dollar as if it were 9 percent of a known CPM invents the assumption."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What multiplying the other headlines produces",
          "paragraphs": [
            "Pixalate published a spend total and an invalid share. It did not publish 21 percent of $6.9 billion as dollars lost. That multiplication treats every invalid impression as a full-price loss, ignores that open programmatic is not all CTV spend, and ignores that 7 billion transactions and 103 billion impressions are different bases. A slide that prints the product as Pixalate's fraud bill is citing a calculation the benchmark did not make.",
            "IAS's million a month is narrower still. It is Papyrus, a named cluster in reading apps, not connected TV. The method is an eCPM from supply IAS observed, applied to a broader footprint. Using it as the monthly cost of CTV fraud moves a mobile scheme onto a television budget. The direct-deal rows in the DoubleVerify release, 34 percent and 25 percent of impressions to bots on two campaigns, are also not convertible into the $1.8 million without a price and a volume those campaigns did not print.",
            "A scheme count fails the same way. One hundred forty percent more CTV fraud schemes is not 140 percent more dollars. More operations can coincide with a low rate on protected impressions. The cost note and the scheme note are different searches. This page is only the dollar."
          ]
        },
        {
          "type": "list",
          "heading": "Dollars that are not the CTV fraud bill",
          "items": [
            "DoubleVerify, May 7, 2026: about $1.8 million per billion impressions, unprotected CTV campaigns, called a conservative estimate.",
            "The paired rate is nearly 9 percent with controls off, and under 1 percent with controls on. The estimate belongs to the off cell.",
            "Pixalate, March 26, 2026: $6.9 billion in global open programmatic CTV ad spend, beside a 21 percent IVT rate. Spend is not loss.",
            "IAS Papyrus, August 6, 2026: close to $1 million a month at the peak for one mobile scheme.",
            "Multiplying 21 percent by $6.9 billion is a calculation neither release published."
          ]
        },
        {
          "type": "quote",
          "quote": "A cost per billion impressions is the price of a named cell with the control off, and a spend total beside an invalid share is still a spend total.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag before you price the impression",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so impression events and verification nodes are present. Nothing is stored. This does not estimate fraud cost.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Global Study: Fueled by AI, CTV Fraud Schemes Surge 140% Globally",
              "href": "https://doubleverify.com/company/newsroom/global-study-ctv-fraud-schemes-surge-140-globally",
              "description": "DoubleVerify, May 7, 2026. The unprotected-campaign cost estimate and the paired fraud rates.",
              "source": "DoubleVerify"
            },
            {
              "label": "Q4 2025 CTV Ad Supply Chain Trends Report",
              "href": "https://www.pixalate.com/blog/q4-2025-ctv-ad-supply-chain-trends-report",
              "description": "March 26, 2026. $6.9 billion in open programmatic CTV spend beside the 21 percent rate.",
              "source": "Pixalate"
            },
            {
              "label": "CTV fraud schemes lines up a 140% count and not an impression rate",
              "href": "/blog/ctv-fraud-schemes/",
              "description": "The count in the same DoubleVerify release, which is not this dollar.",
              "source": "vastlint"
            },
            {
              "label": "A normal CTV IVT rate lines up several logs and no single benchmark",
              "href": "/blog/what-is-a-normal-ctv-ivt-rate/",
              "description": "Why the rates next to these dollars are not one market rate.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ctv-fraud-schemes",
      "title": "A 140 Percent Rise in CTV Fraud Schemes Is a Count of Operations, Not 140 Percent of Impressions",
      "description": "CTV fraud schemes, and whether CTV fraud is up 140 percent. DoubleVerify's May 7, 2026 release counts 140 percent more schemes and variants in the first quarter of 2026 than in the first quarter of 2025. The same release puts fraud under 1 percent on protected campaigns. More operations and a low impression rate can both be true. Ten times more fraudulent CTV apps, and more than 50 bot attacks in 2025, are counts as well.",
      "seoTitle": "CTV fraud schemes lines up a 140% count and not an impression rate",
      "seoDescription": "DoubleVerify counted 140% more CTV fraud schemes in Q1 2026 than in Q1 2025. That is not 140% of impressions. Protected campaigns in the same release were under 1% fraud.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A count of schemes, a count of apps, and an impression rate sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "DoubleVerify",
                "140% more than Q1 2025",
                "Scheme and variant count",
                "CTV fraud operations",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "10× more fraudulent CTV apps than 2024",
                "App count",
                "Apps, not impressions",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "More than 50 bot attacks and variants in 2025",
                "Attack count",
                "Named operations",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/ctv-fraud-schemes.png?v=2",
          "alt": "A 140 percent increase in CTV fraud schemes is a count of operations from Q1 2025 to Q1 2026. The impression rate on protected campaigns in the same release is under 1 percent.",
          "width": 1440,
          "height": 820,
          "caption": "More schemes can be found while the share of impressions on protected campaigns stays low.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "CTV fraud schemes is the search that starts from a headline. People also type CTV fraud up 140 percent, did CTV fraud increase, and how many fraudulent CTV apps there are. DoubleVerify's May 7, 2026 release says it detected 140 percent more CTV fraud schemes and variants in the first quarter of 2026 than in the first quarter of 2025. The same release says there were 10 times more fraudulent CTV apps than in 2024, and more than 50 bot attacks and variants in 2025. Each of those is a count of things the firm classified as operations or apps. None of them is a share of impressions.",
            "The impression shares in that release go the other direction from the scary reading of 140. Protected campaigns, controls on, showed fraud under 1 percent. Unprotected tests showed nearly 9 percent. A year in which the catalog of schemes grows, and the share of impressions on campaigns with the control applied stays under 1 percent, is the release as written. Treating 140 percent as the impression rate deletes the unit and the protected cell.",
            "vastlint does not count schemes. It checks the VAST 2.0–4.4 document a scheme would have to pass through, including whether verification survived the wrapper. A scheme count will not tell you that. A valid tag will not tell you the scheme count."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What a scheme is doing in the sentence",
          "paragraphs": [
            "A scheme, in this release, is an operation: a way of extracting impressions, with variants as the operation changes. Counting them year over year measures how many such operations the firm says it distinguished. It does not measure how many impressions each one took. One scheme can be a handful of apps. Another can be the healthcare direct deal elsewhere in the release, where 34 percent of one campaign went to bots. The count goes up by one either way. That is why a scheme census and a campaign rate refuse to rank each other.",
            "Variants make the count even less like a rate. A variant is a change inside an operation, and the release adds variants into the 140 percent. Splitting one operation into more detectable variants increases the count without a new pool of impressions. A detection team that gets better at naming variants can publish a higher scheme count in a quarter when the impression share is flat. The headline reads as more fraud. The method reads as a finer catalog."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the impression rates can stay quiet",
          "paragraphs": [
            "The under-1-percent figure is conditional. It is DV-protected campaigns. If the control is doing what the study claims, new schemes are found and then kept off those campaigns, and the impression rate on the protected cell stays low while the catalog grows. That is not a contradiction. It is the control. The nearly 9 percent cell is where the controls were not applied. Quoting 140 percent and under 1 percent as if one refutes the other skips the condition.",
            "Pixalate's 19 percent US CTV share, March 9, 2026, does not referee the scheme count either. It is an impression classification of a predominantly open-auction quarter. Pixalate did not, in that benchmark, publish a count of named schemes. A quarter can show 19 percent of impressions invalid and say nothing about whether the number of operations rose 140 percent. The two firms are not even required to be looking at the same log.",
            "App counts are the same trap in a smaller frame. Ten times more fraudulent CTV apps than in 2024 is a count of apps. It is not ten times the IVT rate, and it is not Fire TV's 14 percent or Samsung's 28 percent. An app can be fraudulent and small. A device rate can move because the impression mix moved, with no change in the app census."
          ]
        },
        {
          "type": "list",
          "heading": "Counts in the May 2026 release that are not impression shares",
          "items": [
            "140 percent more CTV fraud schemes and variants, Q1 2026 versus Q1 2025.",
            "10 times more fraudulent CTV apps than in 2024.",
            "More than 50 bot attacks and variants in 2025.",
            "Impression share, same release, controls on: fraud under 1 percent.",
            "Impression share, controls off: fraud near 9 percent.",
            "Pixalate's 19 percent US CTV figure is an impression share from a different firm and a different log. It does not confirm or cancel the 140 percent."
          ]
        },
        {
          "type": "quote",
          "quote": "A higher count of named schemes is a larger catalog, and the share of impressions on a protected campaign can stay low while the catalog grows.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag the scheme would have to pass through",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification nodes and media files are present. Nothing is stored. This does not count fraud schemes.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Global Study: Fueled by AI, CTV Fraud Schemes Surge 140% Globally",
              "href": "https://doubleverify.com/company/newsroom/global-study-ctv-fraud-schemes-surge-140-globally",
              "description": "DoubleVerify, May 7, 2026. Scheme counts, app counts, and the protected and unprotected impression rates.",
              "source": "DoubleVerify"
            },
            {
              "label": "Cost of CTV ad fraud lines up $1.8 million per billion on unprotected campaigns",
              "href": "/blog/cost-of-ctv-ad-fraud/",
              "description": "The dollar in the same release, which is not this count.",
              "source": "vastlint"
            },
            {
              "label": "IAS vs DoubleVerify lines up nearly 25× clicks and a scheme count",
              "href": "/blog/ias-vs-doubleverify/",
              "description": "Why the 140 percent does not rank a click multiple from another firm.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "mobile-app-ivt-rate",
      "title": "The Mobile App IVT Rate in Pixalate's Q4 2025 Table Is 29 Percent in the US and 36 Percent Globally",
      "description": "Mobile app IVT rate, in-app ad fraud, and the invalid-traffic benchmark for apps. Pixalate's March 9, 2026 table puts Q4 2025 US mobile app invalid traffic at 29 percent and global mobile app at 36 percent, against US CTV at 19 percent, in a predominantly open-auction set. IAS's Papyrus note is a named cluster's click multiple, not that quarterly share.",
      "seoTitle": "Mobile app IVT rate lines up 29% in the US and 36% globally",
      "seoDescription": "Pixalate's Q4 2025 mobile app IVT is 29% in the US and 36% globally, in open auction. US CTV in the same table is 19%. Papyrus's 25× click lift is a different mobile object.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "Mobile fraud",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A quarterly app share and a named mobile cluster sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "Pixalate",
                "29% invalid",
                "Impression share",
                "Q4 2025 US mobile app, mostly open auction",
                "In-app",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "36% invalid",
                "Impression share",
                "Q4 2025 global mobile app",
                "In-app",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "27% invalid",
                "Impression share",
                "Q4 2025 Canada mobile app",
                "In-app",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, same table",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "IAS",
                "Nearly 25× clicks",
                "Cluster lift",
                "Papyrus vs other IAS traffic",
                "Mobile reading apps",
                "August 6, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/mobile-app-ivt-rate.png?v=2",
          "alt": "Pixalate's Q4 2025 mobile app invalid share is 29 percent in the US and 36 percent globally. US CTV in the same table is 19 percent. Papyrus is a click multiple on a named cluster, not that quarterly share.",
          "width": 1440,
          "height": 820,
          "caption": "The app row, the web row, and the CTV row are three populations in one benchmark.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Mobile app IVT rate is the cell next to the CTV number people already quote. People also type in-app ad fraud rate, mobile invalid traffic benchmark, and whether app fraud is worse than CTV. Pixalate's March 9, 2026 table, for the fourth quarter of 2025, puts United States mobile app invalid traffic at 29 percent, global mobile app at 36 percent, and Canada mobile app at 27 percent. The same rows put US desktop and mobile web at 25 percent and US CTV at 19 percent. The base is more than 103 billion global programmatic impressions, predominantly buy-side open auction.",
            "The app row is higher than the CTV row in that table, in the US and globally. That is a surface difference inside one method and one quarter. It is not a ranking of app fraud against connected TV as markets, and it is not IAS's Papyrus result. Papyrus, August 6, 2026, is a named cluster in novel-reading apps: nearly 25 times the click success rate, roughly 4 times the eCPM, about 13 percent higher attention, versus other traffic IAS had already separated. A click multiple on a cluster is not 29 percent of US in-app impressions.",
            "vastlint does not publish an app IVT rate. In-app video still arrives as VAST. The check is whether that tag's media, trackers, and verification nodes are structurally present in versions 2.0–4.4."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the 29 percent includes, and what it leaves out",
          "paragraphs": [
            "It is the share of US mobile app impressions in Pixalate's set that the firm classified invalid. Open auction is the source it names as predominant. A campaign bought as a private marketplace, or a log that already passed a pre-bid filter, is not automatically inside that 29 percent. Global at 36 percent is the same kind of sentence on a wider geography, not a restatement of the US. Canada at 27 percent is a third geography. Using the global number for a US app buy, or the US number for a Canadian buy, is how a benchmark becomes a target for the wrong country.",
            "Web is the neighboring row, 25 percent in the US and 23 percent globally, so the table is not an app-versus-everything story. Desktop and mobile web, mobile app, and CTV are three surfaces. The US app cell is four points above US web and ten points above US CTV. Those gaps are large enough to matter and small enough to vanish if you round the whole release to one fraud rate. The normal-rate note is what happens when the CTV cell is asked to stand for all three."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why Papyrus is not the app benchmark",
          "paragraphs": [
            "Papyrus is evidence that a mobile scheme can inflate clicks, price, and attention on real phones, with more than 800 domains and nearly 8,000 host values, and an estimated peak near $1 million a month. IAS says the associated apps and hostnames are then filtered for clients on IVT avoidance. That is a list after identification. The 29 percent is a classification of a quarterly impression set before you know whether any of those apps were in it. A buyer who treats Papyrus as the explanation of the 29 percent has assigned one cluster to a denominator the cluster study did not claim.",
            "The two mobile facts can both be used. The quarterly share is the open-auction app baseline in that table. The cluster is a mechanism: hidden webviews, taps passed through as clicks. Mechanism plus baseline is not a sum. An app campaign that has already excluded the Papyrus list is no longer the unfiltered quarterly set, and its remaining IVT is a third number."
          ]
        },
        {
          "type": "list",
          "heading": "App cells that are not the CTV cell and not Papyrus",
          "items": [
            "Pixalate, Q4 2025, US mobile app, March 9, 2026: 29 percent of impressions invalid.",
            "Same release, global mobile app: 36 percent. Canada mobile app: 27 percent.",
            "Same release, US web: 25 percent. US CTV: 19 percent. Three surfaces.",
            "Base: more than 103 billion impressions, predominantly buy-side open auction.",
            "IAS Papyrus, August 6, 2026: nearly 25 times the clicks on a named cluster, which is not 29 percent of US in-app impressions."
          ]
        },
        {
          "type": "quote",
          "quote": "The app row in the quarterly table is a surface, the cluster study is one operation on phones, and a CTV rate will not stand in for either.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the in-app VAST tag the rate never opens",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so media files and verification nodes are present. Nothing is stored. This does not classify in-app traffic.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Q4 2025 North America IVT and Ad Fraud Benchmarks",
              "href": "https://www.globenewswire.com/news-release/2026/03/09/3251883/0/en/Pixalate-Releases-Q4-2025-North-America-Invalid-Traffic-IVT-Ad-Fraud-Benchmarks-Connected-TV-CTV-IVT-Rate-in-United-States-at-19.html",
              "description": "March 9, 2026. US mobile app at 29 percent, global mobile app at 36 percent, US CTV at 19 percent.",
              "source": "Pixalate"
            },
            {
              "label": "Papyrus: Inside a Mobile Scheme Built to Fake Clicks, Scrolls, and Attention",
              "href": "https://integralads.com/insider/papyrus-inside-a-mobile-scheme-built-to-fake-clicks-scrolls-and-attention/",
              "description": "IAS Threat Lab, August 6, 2026. A named cluster, not the quarterly app share.",
              "source": "Integral Ad Science"
            },
            {
              "label": "A normal CTV IVT rate lines up several logs and no single benchmark",
              "href": "/blog/what-is-a-normal-ctv-ivt-rate/",
              "description": "The CTV cell from the same table, which this note does not let stand for apps.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ssai-spoofing",
      "title": "SSAI Spoofing Is a Falsified Measurement Event, and a Legitimate Stitcher Also Fires Beacons from a Server",
      "description": "SSAI spoofing, CTV spoofing, and server-side ad insertion fraud. The MRC's IVT addendum lists SSAI spoofing among falsified measurement events in the sophisticated category, which is encouraged rather than required. A real stitcher also emits beacons from a server, so a data-center IP on the impression is not, by itself, the spoof. Pre-bid fields and the post-bid beacon can disagree even when a person watched.",
      "seoTitle": "SSAI spoofing lines up a server beacon and a falsified measurement event",
      "seoDescription": "MRC lists SSAI spoofing as sophisticated invalid traffic, which is encouraged rather than required. A legitimate stitcher also fires beacons from a server, so a data-center IP is not itself the proof.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "IVT",
      "tags": [
        "IVT",
        "CTV",
        "SSAI",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A standards category, a server-side beacon, and an impression rate sit together here and do not share a scale.",
          "columns": [
            "Source",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "MRC",
                "SSAI spoofing is falsified measurement",
                "SIVT example",
                "Encouraged, not the required GIVT list",
                "CTV and video",
                "June 2020"
              ]
            },
            {
              "cells": [
                "MRC",
                "GIVT filtration is required",
                "List checks",
                "Data centers, crawlers, prefetch",
                "All measured impressions",
                "June 2020"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "APAC violations 98% data-center",
                "Mix of violations",
                "What was flagged, not all impressions",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/ssai-spoofing.png?v=2",
          "alt": "A legitimate SSAI stitcher fires the impression beacon from a server. SSAI spoofing, in the MRC addendum, is a falsified measurement event in the sophisticated category. A data-center IP alone does not separate the two.",
          "width": 1440,
          "height": 820,
          "caption": "The server beacon is how stitching works. Spoofing is the falsified event that imitates it.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "SSAI spoofing is the search for a CTV failure that looks like ordinary stitching. People also type server-side ad insertion fraud, CTV spoofing, and whether a data-center IP on a CTV impression is bots. The Media Rating Council's June 2020 IVT addendum puts SSAI spoofing among falsified measurement events, in the sophisticated category, alongside falsified viewability, clicks, and location. Sophisticated detection is encouraged. It is not the required general list. General invalid traffic is the shared floor: known data-center ranges, declared crawlers, prefetch, placements that cannot have been a real opportunity.",
            "The awkward fact is that legitimate server-side insertion also emits the impression from a server. The stitcher, not the television, often fires the beacon. A post-bid check that treats every data-center IP as general invalid traffic will flag the architecture. A pre-bid check that trusts the device fields in the request will miss a stitch that never had that device. The MRC category exists because those two honest signals can describe a fraud, and they can describe a person watching a stitched stream. Telling them apart is the sophisticated judgment. It is not a row in the data-center list.",
            "vastlint does not decide which beacon was spoofed. It checks the VAST 2.0–4.4 tag the stitcher will parse: media files, tracking events, wrapper depth, and whether a verification node is present for whatever post-bid judgment comes later."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the category is asking you to separate",
          "paragraphs": [
            "Falsified measurement, in the addendum's examples, is an event that claims something that did not happen: a view, a click, a place, a completed play, a device that was not there. SSAI spoofing is that claim dressed as a stitch. The stream may not have contained the ad. The app may not have been the app in the request. The beacon still arrives from a server, which is what a real stitch also does. The proof is corroboration, which is why the addendum puts it on the sophisticated side and why two accredited firms can disagree. Their general lists should be close. Their SSAI judgments need not be.",
            "DoubleVerify's regional mix is easy to misuse here. In the May 7, 2026 release, data-center traffic was 98 percent of APAC violations, 91 percent in LATAM, and 66 percent in EMEA, while North American violations were 82 percent bot fraud. Those are mixes of what was flagged, not impression rates, and data-center traffic in that sentence is not a synonym for SSAI spoofing. A violation tagged data-center might be the general list doing its job on a non-stitch impression. A stitched impression a person watched can carry a server IP and not be in the violation set at all. Reading 98 percent as the share of APAC CTV that is spoofed stitches three units into one."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What pre-bid and post-bid each fail to finish",
          "paragraphs": [
            "Pre-bid sees the request: bundle, device, IP, supply chain. A spoofed app id is on the sophisticated list because the request can lie about where the ad will land. The stitch has not happened. The model is predicting. HUMAN's MediaGuard is this hop, and the MRC says the platform decides whether the suggestion becomes a drop. A drop avoids the invoice. It does not inspect the beacon that would have fired.",
            "Post-bid sees the beacon and, when a client player is involved, the render. If the only beacon is the stitcher's, the device context the fraud model wanted is the one the server asserted. Pixalate's 19 percent US CTV figure is a classification of impressions in an open-auction quarter, not a count of spoofed stitches. An impression rate cannot tell you how many of its invalid rows were SSAI spoofing versus bots versus data-center lists, unless the release breaks that out. The March 9 benchmark does not break SSAI spoofing out as its own percent.",
            "The architecture note, SSAI versus CSAI, is about where the ad is inserted. This note is about a fraud category that imitates the server-side path. A campaign can be legitimately stitched and still be spoofed, and it can be stitched and clean. The tag is the piece both paths share. A wrapper that arrives without media files, or without the tracking events the stitcher is supposed to fire, fails before anyone has to decide whether the beacon was a person."
          ]
        },
        {
          "type": "list",
          "heading": "SSAI sentences that are not an impression rate",
          "items": [
            "MRC, June 2020: SSAI spoofing is a falsified measurement event, in the sophisticated category, which is encouraged rather than required.",
            "A legitimate stitcher fires impression beacons from a server. A data-center IP is the architecture and the suspect list.",
            "Pre-bid judges the request. Post-bid judges the beacon. They can disagree on one opportunity a person watched.",
            "DoubleVerify, May 7, 2026: data-center share of violations by region is not an SSAI spoofing rate.",
            "Pixalate, March 9, 2026: 19 percent of US CTV impressions invalid is not a published SSAI-spoofing share.",
            "SSAI versus client-side insertion is where the ad is stitched. Spoofing is whether the measurement event was real."
          ]
        },
        {
          "type": "quote",
          "quote": "Server-side beacons are how a stitch reports, and spoofing is the case where that report describes an ad the viewer did not get.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag the stitcher has to parse",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so media files, tracking events, and verification nodes are present. Nothing is stored. This does not detect SSAI spoofing.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Invalid Traffic Detection and Filtration Standards Addendum, June 2020 update",
              "href": "https://www.mediaratingcouncil.org/sites/default/files/Standards/IVT%20Addendum%20Update%20062520.pdf",
              "description": "SSAI spoofing among falsified measurement events. SIVT is encouraged. GIVT filtration is required.",
              "source": "Media Rating Council"
            },
            {
              "label": "Pre-bid vs post-bid IVT compares a decision before the bid with a label after the impression",
              "href": "/blog/pre-bid-vs-post-bid-ivt/",
              "description": "Why a request and a server beacon can disagree on one stitched impression.",
              "source": "vastlint"
            },
            {
              "label": "SSAI vs CSAI",
              "href": "/blog/ssai-vs-csai/",
              "description": "Where the ad is inserted, which is the architecture this fraud category imitates.",
              "source": "vastlint"
            },
            {
              "label": "GIVT vs SIVT lines up a required list and an investigation",
              "href": "/blog/givt-vs-sivt/",
              "description": "Why a data-center list and an SSAI judgment are different categories.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ctv-ivt-by-device",
      "title": "CTV IVT by Device Puts a 14 Percent Fire TV Rate Next to a 28 Percent Samsung Rate, and Neither Is a Spend Share",
      "description": "CTV IVT by device, Samsung Smart TV ad fraud, and Fire TV invalid traffic land on one Pixalate quarter: Fire TV at 14 percent global device IVT and Samsung Smart TV at 28 percent. Fire TV is also 30 percent of large-screen open spend in a later study, which is not an IVT rate. Roku at 18 percent of that spend has no IVT row in the device table.",
      "seoTitle": "CTV IVT by device lines up Fire TV at 14% and Samsung at 28%",
      "seoDescription": "Pixalate's Q4 2025 device IVT is Fire TV at 14% and Samsung Smart TV at 28%. A June 2026 spend split puts Fire at 30% and Roku at 18% of large-screen open spend, which is not an IVT rate.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A device IVT rate, a spend share, and a regional mix of violations sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "Pixalate",
                "Fire TV 14% IVT",
                "Device impression share",
                "Q4 2025 global open-programmatic CTV",
                "Fire TV",
                "March 26, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "Samsung Smart TV 28% IVT",
                "Device impression share",
                "Same quarter, same method",
                "Samsung",
                "March 26, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "Fire 30%, Roku 18%",
                "Share of large-screen spend",
                "US open programmatic CTV, large screens",
                "Spend",
                "June 2026 study"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "57% large screen, 43% small screen",
                "Spend split",
                "US open programmatic CTV",
                "Spend",
                "June 2026 study"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "NA 82% of violations were bots",
                "Mix of violations",
                "What was flagged, not all impressions",
                "Region",
                "May 7, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/ctv-ivt-by-device.png?v=2",
          "alt": "Fire TV at 14 percent device IVT and Samsung Smart TV at 28 percent are one Pixalate quarter. Fire at 30 percent and Roku at 18 percent are shares of large-screen spend, not IVT rates.",
          "width": 1440,
          "height": 820,
          "caption": "A device IVT rate and a device spend share answer different questions about the same brand of television.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "CTV IVT by device is the search that starts from a television brand. People also type Samsung Smart TV ad fraud, Fire TV invalid traffic, Roku ad fraud, and CTV fraud by region. The numbers that match those words are not one table. On March 26, 2026, Pixalate put Amazon Fire TV at 14 percent global device IVT and Samsung Smart TV at 28 percent, both inside Q4 2025 open-programmatic CTV. MediaPost, on August 5, 2026, reported a June 2026 Pixalate spend study: large screens are 57 percent of US open programmatic CTV spend, small screens 43 percent, and within the large-screen half Fire is 30 percent and Roku is 18 percent. DoubleVerify's May 7, 2026 release describes regions as a mix of violations: in North America, bot fraud was 82 percent of violations, and data-center traffic was 98 percent in APAC, 66 percent in EMEA, and 91 percent in LATAM.",
            "Fourteen and twenty-eight are impression classifications on two device populations in one quarter. Thirty and eighteen are shares of spend. Eighty-two is a share of the violations a firm already flagged, not a share of impressions served in that region. Pasting Fire's spend weight next to Fire's IVT rate produces a sentence the studies did not publish: that the device which takes the most large-screen money is the device with the fraud problem. The IVT table says Samsung's rate is higher. The spend table says Fire's share of large-screen money is larger. Both can be true, and neither tells you Roku's invalid-traffic rate, because that row is not in the device IVT table.",
            "vastlint does not classify a device as invalid. It checks whether a VAST 2.0–4.4 tag can actually play on the stacks in the spend map, including MediaFiles a television will select. A tag that only survives a phone will not explain a Fire TV IVT row."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the device IVT rows measure",
          "paragraphs": [
            "The March 26 note is a supply-chain cut of open programmatic CTV. Global open programmatic CTV invalid traffic is 21 percent on more than 7 billion transactions, which is a different base from the March 9 benchmark of more than 103 billion impressions across web, app, and CTV. Inside that supply-chain note, the device changes the rate without changing the firm or the quarter. Fire TV at 14 percent and Samsung Smart TV at 28 percent differ by fourteen points because the population changed. A national US CTV figure of 19 percent, from the March 9 release, is a third population again: predominantly buy-side open auction, United States, not one operating system.",
            "Someone managing a Samsung-heavy buy who uses 19 percent as the target is using the country. Someone using 14 percent is using Fire TV. The gap is the device mix, which is also why a campaign that shifts from one OEM to another can move its IVT line without any vendor changing a model. The shortlist habit is to treat that move as a change in fraud. It can be a change in which rows of this table the campaign sits on."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the spend shares measure, including Roku",
          "paragraphs": [
            "The June 2026 study, as MediaPost reported it, is where the money went. Fifty-seven percent of US open programmatic CTV spend on large screens, 43 percent on phones and tablets. Fire at 30 percent and Roku at 18 percent of the large-screen portion. Genre and daypart skew with the surface, which matters for which MediaFile the player will pick. None of those sentences is an invalid-traffic rate. Roku ad fraud, as a query, does not get an answer from 18 percent. Eighteen percent is Roku's share of large-screen open spend in that study. A Roku IVT rate would be a classification of Roku impressions, and this note does not have one.",
            "Fire is the brand that shows up in both files, which is the trap. Fourteen percent IVT and 30 percent of large-screen spend are both about Fire TV and they do not multiply into a fraud-weighted spend figure unless you compute one yourself and label it as yours. Pixalate did not publish that product in the sentences cited here. A buyer who weights the 14 percent by the 30 percent has built a new number. It should not be cited back as Pixalate's Fire TV fraud share of the market."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why a regional mix is a third unit",
          "paragraphs": [
            "DoubleVerify's regional lines are easy to read as CTV fraud by country. North America, 82 percent bot fraud. APAC, 98 percent data-center. Those are compositions of violations, the character of what was flagged, not the percent of impressions in the region that were invalid. A region can have a low impression IVT rate and still have almost all of its violations be data-center traffic. A region can have a high impression rate made mostly of bots. The fix for data-center traffic is closer to the general-invalid list. The fix for bots that imitate users is the sophisticated investigation. Averaging 82 and 98 produces neither an impression rate nor a plan.",
            "Put the device IVT row, the spend share, and the violation mix in different columns before any of them is called the CTV rate. The 19 percent US figure remains the open-auction country rate. It is not the Samsung rate, the Fire spend share, or the North American violation mix."
          ]
        },
        {
          "type": "list",
          "heading": "Device and region sentences that use different units",
          "items": [
            "Pixalate, Q4 2025, open-programmatic CTV, March 26, 2026: Fire TV 14 percent global device IVT, Samsung Smart TV 28 percent.",
            "Pixalate, March 9, 2026: US CTV 19 percent, a country rate, not a device rate.",
            "Pixalate, June 2026 spend study, as MediaPost reported it: large screens 57 percent of US open programmatic CTV spend, Fire 30 percent and Roku 18 percent of the large-screen half. Spend, not IVT.",
            "Roku's 18 percent does not say what share of Roku impressions were invalid.",
            "DoubleVerify, May 7, 2026: 82 percent of North American violations were bot fraud, and 98 percent of APAC violations were data-center traffic. That is the mix of what was flagged."
          ]
        },
        {
          "type": "quote",
          "quote": "A television brand can have a high IVT rate, a large share of spend, or both, and those are two measurements even when the logo on the bezel is the same.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag against the stacks in the spend map",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so MediaFiles and verification nodes are present for the players you actually buy. Nothing is stored. This does not produce a device IVT rate.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Q4 2025 CTV Ad Supply Chain Trends Report",
              "href": "https://www.pixalate.com/blog/q4-2025-ctv-ad-supply-chain-trends-report",
              "description": "March 26, 2026. Fire TV at 14 percent and Samsung Smart TV at 28 percent.",
              "source": "Pixalate"
            },
            {
              "label": "Study Finds More Than Half Of CTV Programmatic Served On Large Screens",
              "href": "https://www.mediapost.com/publications/article/416951/study-finds-more-than-half-of-ctv-programmatic-ser.html",
              "description": "MediaPost, August 5, 2026, on Pixalate's June 2026 spend split, including Fire and Roku shares of large-screen spend.",
              "source": "MediaPost"
            },
            {
              "label": "Open programmatic CTV is two playback surfaces",
              "href": "/blog/open-programmatic-ctv-two-playback-surfaces/",
              "description": "What the spend split means for the tag, separate from the IVT rows.",
              "source": "vastlint"
            },
            {
              "label": "A normal CTV IVT rate lines up several logs and no single benchmark",
              "href": "/blog/what-is-a-normal-ctv-ivt-rate/",
              "description": "Why 19 percent, 14 percent, and 28 percent are not one normal.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "is-direct-ctv-free-of-fraud",
      "title": "A Direct CTV Buy Is Not a Fraud Rate of Zero, and the Open Auction Is Not the Direct Market",
      "description": "Is direct CTV free of fraud, and is programmatic worse than direct. DoubleVerify's May 2026 release describes two direct campaigns, 34 percent and 25 percent of impressions to bots, and those are single deals. Pixalate's 19 percent is predominantly open auction. A private marketplace sits outside that sentence.",
      "seoTitle": "Is direct CTV free of fraud lines up two deals beside an open-auction share",
      "seoDescription": "Direct CTV is not a fraud rate of zero. DoubleVerify cited 34% and 25% of impressions to bots on two direct deals. Pixalate's 19% is open-auction US CTV, not the direct market.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "Two single direct deals, an open-auction quarter, and a protected rate sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "DoubleVerify",
                "34% of impressions to bots",
                "One campaign",
                "A consumer healthcare buy, direct",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "25% of impressions to bots",
                "One campaign",
                "A major CPG buy, direct",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud nearly 9%",
                "Impression share",
                "Controls off",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/is-direct-ctv-free-of-fraud.png?v=2",
          "alt": "Two direct CTV campaigns in DoubleVerify's May 2026 release sent 34 percent and 25 percent of impressions to bots. The 19 percent open-auction figure is a different population, and under 1 percent is a protected cell.",
          "width": 1440,
          "height": 820,
          "caption": "Direct is a deal path. It is not a fraud rate, and it is not a promise of zero.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Is direct CTV free of fraud is the question buyers ask when they move budget out of the open auction. People also type programmatic versus direct ad fraud, private marketplace IVT, and whether a programmatic guaranteed deal is clean. The public figures do not contain a direct-market rate. They contain two named campaigns, an open-auction quarter, and a protected cell.",
            "On May 7, 2026, DoubleVerify said bot activity showed up in multiple direct CTV buys, including 34 percent of impressions in one consumer healthcare campaign and 25 percent in a major CPG campaign. The same release put fraud under 1 percent on DV-protected CTV campaigns and nearly 9 percent where controls were not applied. On March 9, 2026, Pixalate put US CTV invalid traffic at 19 percent inside a set of more than 103 billion impressions that are predominantly buy-side open auction. A private marketplace or a programmatic guaranteed buy sits outside the population that 19 percent describes, which is not the same thing as sitting at zero.",
            "vastlint does not know whether a tag was sold direct. It checks VAST 2.0–4.4 structure. A direct deal can still arrive as a wrapper that drops the verification node, and then the path is direct while the measurement is missing."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the two direct deals are",
          "paragraphs": [
            "They are examples inside a release, not a sample designed to estimate all direct CTV. DoubleVerify said bot activity showed up in multiple direct buys, and then named two. Thirty-four and twenty-five are shares of impressions on those campaigns. They are not the average of direct, not the median, and not a ceiling. A third direct campaign can be quieter. Using 34 percent as the direct IVT rate repeats the mistake of using 19 percent as every CTV rate: the denominator in the sentence got dropped.",
            "The protected under-1-percent cell is also not the direct market. It is campaigns where DV controls were on, whatever the deal path. A direct buy with those controls off is closer to the unprotected test, or to one of the named deals, and the release does not say the two healthcare and CPG examples were the unprotected cell. They are additional rows. Leaving them in the 9 percent cell, or in the 19 percent cell, hides the fact that the path was direct."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What open auction, PMP, and direct each fail to prove",
          "paragraphs": [
            "Open auction, in Pixalate's March 9 wording, is the predominant source of the benchmark. Programmatic, as buyers use the word, also includes private marketplaces and programmatic guaranteed. Those paths are not automatically inside the 19 percent, and they are not automatically outside fraud. The direct examples are the evidence that a one-to-one buy can still send a quarter or a third of its impressions to bots in a case the vendor chose to name.",
            "Programmatic versus direct is a path comparison only when both sides are impression shares of stated populations. A scheme count, 140 percent more CTV schemes in the first quarter of 2026 than in the first quarter of 2025, does not say schemes prefer the open auction. Schemes can show up in a direct IO. The healthcare and CPG rows are that appearance, on a campaign scale.",
            "If your buy is mostly deals, the planning number is not 19 percent, and it is not zero. It is whatever your own log shows after you label the path, plus the warning that a single direct campaign in this release reached 34 percent. If your buy is mostly open auction with a control already on, your remainder is a third number, closer to a protected rate than to either headline."
          ]
        },
        {
          "type": "list",
          "heading": "Path sentences that are not a direct-market rate",
          "items": [
            "DoubleVerify, one direct healthcare CTV campaign, May 7, 2026: 34 percent of impressions to bots.",
            "DoubleVerify, one direct CPG CTV campaign, same release: 25 percent of impressions to bots.",
            "Those two rows are examples. They are not the average of direct CTV.",
            "DoubleVerify, controls on: fraud under 1 percent. That cell is the control, not the deal path.",
            "Pixalate, Q4 2025 US CTV, predominantly open auction: 19 percent. A private marketplace is outside that sentence, which is not a rate of zero.",
            "A direct tag can still omit AdVerifications. The path and the measurement node are different facts."
          ]
        },
        {
          "type": "quote",
          "quote": "Direct is a way the impression was bought, and the two campaigns in the May 2026 release are evidence that the path alone did not keep bots out.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag on the direct deal the same way",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification nodes are present whether the IO was direct or the auction was open. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Global Study: Fueled by AI, CTV Fraud Schemes Surge 140% Globally",
              "href": "https://doubleverify.com/company/newsroom/global-study-ctv-fraud-schemes-surge-140-globally",
              "description": "DoubleVerify, May 7, 2026. The two direct-deal examples and the protected and unprotected rates.",
              "source": "DoubleVerify"
            },
            {
              "label": "Q4 2025 North America IVT and Ad Fraud Benchmarks",
              "href": "https://www.globenewswire.com/news-release/2026/03/09/3251883/0/en/Pixalate-Releases-Q4-2025-North-America-Invalid-Traffic-IVT-Ad-Fraud-Benchmarks-Connected-TV-CTV-IVT-Rate-in-United-States-at-19.html",
              "description": "March 9, 2026. US CTV at 19 percent in a predominantly open-auction set.",
              "source": "Pixalate"
            },
            {
              "label": "A normal CTV IVT rate lines up several logs and no single benchmark",
              "href": "/blog/what-is-a-normal-ctv-ivt-rate/",
              "description": "Why none of these percents is the normal, including the direct examples.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "why-ias-and-doubleverify-disagree",
      "title": "When IAS and DoubleVerify Disagree, the Two Reports Are Often About Different Objects on the Same Campaign Name",
      "description": "Why IAS and DoubleVerify numbers do not match, and why two verification tags disagree. General invalid traffic is a shared list. Sophisticated methods are not. One firm may have scored a pre-bid suggestion, the other a post-bid label, and a wrapper may have dropped one of the nodes so one report never saw the impression.",
      "seoTitle": "Why IAS and DoubleVerify disagree lines up two logs and a missing node",
      "seoDescription": "IAS and DoubleVerify can disagree because SIVT methods differ, the hop differs, or one verification node never arrived. GIVT is the shared list. A missing AdVerifications entry manufactures a gap. vastlint checks whether both verification nodes are in the tag. It does not decide which label was right.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each reason the exports diverge, in one row",
          "caption": "A category split, a hop split, and a missing node sit together here and do not share a scale.",
          "columns": [
            "Source",
            "Figure",
            "Unit",
            "What diverges",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "MRC",
                "GIVT required, SIVT encouraged",
                "Category",
                "The sophisticated slice need not match",
                "Measurement",
                "June 2020"
              ]
            },
            {
              "cells": [
                "IAS",
                "Nearly 25× clicks",
                "Cluster lift",
                "A named mobile scheme, after identification",
                "Mobile",
                "August 6, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on, a later CTV cell",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "MRC",
                "The firm supplies a signal",
                "Who decides",
                "The platform or the client drops the request",
                "Pre-bid",
                "April 11, 2025"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/why-ias-and-doubleverify-disagree.png?v=2",
          "alt": "Two verification reports diverge when the category differs, the hop differs, or a wrapper drops one AdVerifications node so one firm never saw the impression.",
          "width": 1440,
          "height": 820,
          "caption": "A discrepancy is a finding only after the two columns are the same object.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Why IAS and DoubleVerify disagree is the search that starts from a spreadsheet you already have. People also type verification discrepancy, two verification tags with different IVT, and DoubleVerify and IAS reporting different numbers on the same campaign. The versus notes compare public studies. This one is about two exports with your campaign name on them. vastlint does not decide which label was right. It checks whether a VAST 2.0–4.4 tag still carries both verification nodes, and it does not classify invalid traffic.",
            "Some of that gap is required by the standard. The MRC's June 2020 addendum makes general invalid traffic a shared list: data centers, declared crawlers, prefetch, tiny placements. Accredited measurers must apply it, so the general slice should be close. Sophisticated invalid traffic is encouraged, not required, and the methods differ, so two firms can agree on the list and disagree on hijacked devices, hidden ads, and spoofed apps. A buyer who bought both in order to get one number bought a second opinion on the slice the standard refused to standardize.",
            "The rest of the gap is often the document. If a wrapper keeps one Verification node and drops the other, one firm is labeling impressions the other never received. vastlint checks whether those nodes are structurally present in VAST 2.0–4.4. It does not decide which sophisticated label was right."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The gap that is a category",
          "paragraphs": [
            "Read the column header before the percent. If one export says GIVT and the other says total IVT, they are not the same subtraction. General filtration removes the shared list. Total IVT adds whatever sophisticated work that firm did. A jump when you switch vendors, or when you turn a second vendor on, can be the sophisticated scope turning on. The addendum says that difference is expected. It is not, by itself, evidence that one firm is loose.",
            "Papyrus is what the sophisticated side looks like in a published case. IAS, on August 6, 2026, described hidden webviews in novel-reading apps, with nearly 25 times the click success rate versus other traffic it had already separated. A GIVT filter that strips known crawlers would leave that cluster in the log, because the devices are real phones. A second firm that did not name the cluster can report a quiet general rate on the same apps. The disagreement is the investigation, not a broken pixel, until you have checked the pixel."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The gap that is a hop or a population",
          "paragraphs": [
            "A pre-bid flag and a post-bid rate are different moments. The MRC's April 11, 2025 memorandum says the measurement firm supplies a signal and the platform, or the client's configuration, decides the block. DoubleVerify's under-1-percent figure is what remained on CTV campaigns with controls on, published May 7, 2026. That is not IAS's opinion of the same impressions, and IAS's Papyrus ratios are not a CTV impression share. If your two exports are a block rate and a post-bid IVT rate, they disagree because one counts requests that never became impressions.",
            "Population does the same work inside one campaign name. One firm may have scored the tagged impressions. The other may have scored a bid-stream sample, or a list of apps it already identified. The campaign name matches. The denominator does not. Write the denominator in the cell: tagged impressions, bid requests, named apps, open auction, controls on. Two percents with those labels filled in are allowed to differ. Two percents with the labels blank look like a vendor failure."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The gap that is a missing node",
          "paragraphs": [
            "This is the discrepancy you can see without either firm's dashboard. Count Verification entries in the tag that served, not in the tag that was trafficked. A wrapper can keep the impression pixel and drop AdVerifications for one vendor. The campaign report then shows delivery, one firm shows measurement, and the other shows a hole that gets interpreted as a lower IVT rate or as a broken integration. It is a hole. The impressions were not classified. They were absent.",
            "Duplicate vendor identifiers are a separate structural fault: the same vendor declared twice. Two different vendors in two nodes can both be legitimate. After the nodes are both present, a remaining sophisticated gap is the opinion you paid for. Before the nodes are both present, the gap is the tag. The how-to for that check is the AdVerifications note. The validator runs the same rules on the XML you paste."
          ]
        },
        {
          "type": "list",
          "heading": "Checks before you call it a vendor discrepancy",
          "items": [
            "Are both columns GIVT, both SIVT, or one of each. Only the general list is required to be shared.",
            "Are both columns the same hop: pre-bid suggestion, post-bid label, or a study after a scheme was named.",
            "Are both columns the same denominator: tagged impressions, bid requests, or a named app list.",
            "Did both Verification nodes survive the wrapper that actually served.",
            "IAS Papyrus, August 6, 2026, and DoubleVerify's under-1-percent CTV cell, May 7, 2026, are public studies of different objects. They are not your campaign's discrepancy until the columns match."
          ]
        },
        {
          "type": "quote",
          "quote": "A discrepancy is a claim that two firms saw the same impressions and subtracted different ones, and a missing verification node means one of them did not see the impressions at all.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "See which verification node the wrapper kept",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so each Verification entry is present. Nothing is stored. This does not reconcile two IVT rates.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Invalid Traffic Detection and Filtration Standards Addendum, June 2020 update",
              "href": "https://www.mediaratingcouncil.org/sites/default/files/Standards/IVT%20Addendum%20Update%20062520.pdf",
              "description": "GIVT is required and shared. SIVT is encouraged, and the methods can differ.",
              "source": "Media Rating Council"
            },
            {
              "label": "IAS and DoubleVerify together lines up two logs on one impression",
              "href": "/blog/ias-and-doubleverify-together/",
              "description": "The buying question. This note is the report you have after you bought both.",
              "source": "vastlint"
            },
            {
              "label": "How to validate AdVerifications in VAST tags",
              "href": "/blog/how-to-validate-adverifications-in-vast-tags/",
              "description": "What a dropped verification node does to the measurement.",
              "source": "vastlint"
            },
            {
              "label": "GIVT vs SIVT lines up a required list and an investigation",
              "href": "/blog/givt-vs-sivt/",
              "description": "The category split inside a single firm's IVT number.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "brand-safety-vs-ivt",
      "title": "Brand Safety and Invalid Traffic Are Different Subtractions, and a Clean Fraud Rate Does Not Mean the Page Was Suitable",
      "description": "Brand safety versus ad fraud, MFA versus IVT, and brand suitability versus invalid traffic. DoubleVerify's February 2024 made-for-advertising categories are a suitability control with three tiers. IAS describes contextual avoidance. An IVT rate classifies the traffic, not the adjacency of the content.",
      "seoTitle": "Brand safety vs IVT lines up a suitability tier and a fraud rate",
      "seoDescription": "Brand safety and IVT are different jobs. DoubleVerify's MFA tiers, announced February 27, 2024, are suitability. A protected CTV fraud rate under 1% does not say the content was suitable. vastlint does not classify either job. It checks the VAST verification node.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "Brand safety",
        "CTV",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A suitability product, a fraud rate, and a content-avoidance control sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "DoubleVerify",
                "Three MFA suitability tiers",
                "Content category",
                "Pre-bid avoidance and post-bid measurement",
                "Brand suitability",
                "February 27, 2024"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV IVT",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "IAS",
                "Pre-bid and post-bid content avoidance",
                "Suitability control",
                "Content outside brand guidelines",
                "Context",
                "Verification page"
              ]
            },
            {
              "cells": [
                "MRC",
                "IVT is validity, not a content judgment",
                "Category",
                "GIVT required, SIVT encouraged",
                "Invalid traffic",
                "June 2020"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/brand-safety-vs-ivt.png?v=2",
          "alt": "Brand suitability sorts content, including made-for-advertising tiers. Invalid traffic sorts whether the impression was a valid opportunity. A low fraud rate does not certify the adjacency.",
          "width": 1440,
          "height": 820,
          "caption": "A page can be suitable and still be invalid traffic, and a clean fraud cell can sit beside an unsuitable page.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Brand safety versus IVT is the search that treats two products as one badge. People also type brand safety versus ad fraud, MFA versus invalid traffic, made-for-advertising DoubleVerify, and brand suitability versus fraud. On February 27, 2024, DoubleVerify announced tiered made-for-advertising categories for pre-bid avoidance inside Authentic Brand Suitability, next to a post-bid measure of the same issue, and it described sites landing in one of three suitability tiers. IAS's verification page describes a different suitability control: contextual segments for content avoidance, with pre-bid filtering and post-bid blocking when the content falls outside brand guidelines. Neither announcement is an invalid-traffic rate. vastlint does not classify brand safety or IVT. It checks whether a VAST 2.0–4.4 tag carries the verification node either vendor would read.",
            "The IVT figures live in other sentences. DoubleVerify's May 7, 2026 CTV release puts fraud under 1 percent where its controls were on. Pixalate's March 9, 2026 benchmark puts US CTV at 19 percent in a predominantly open-auction set. The MRC's IVT addendum is about whether the opportunity was valid: lists for general invalid traffic, and an encouraged investigation for sophisticated invalid traffic. It does not score whether the article next to the ad matched a brand's content rules. A human on a made-for-advertising page can be valid traffic in an unsuitable place. A bot on a prestige publisher can be invalid traffic in a suitable place.",
            "vastlint does not classify either one. It checks whether a VAST 2.0–4.4 tag carries the verification node a suitability vendor or an IVT vendor would read. The node does not say which job the vendor was hired for."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What a suitability tier actually sorts",
          "paragraphs": [
            "DoubleVerify's February 2024 release is about content-creation practices on sites, sorted into tiers so a buyer can avoid made-for-advertising inventory before the bid and measure it after. That is adjacency and page quality, in the firm's framing. It is not a statement that the impression was served to a person. Turning the MFA control on can shrink a campaign's suitable scale without changing the IVT rate of what remains, and it can leave the IVT rate untouched while the suitability report moves.",
            "IAS's public verification page puts the same job in its own words: context control, segments for avoidance, pre-bid filtering and post-bid blocking for content outside the brand's guidelines. Papyrus, the August 6, 2026 mobile scheme, is not that product. Papyrus is a fraud study about hidden webviews and inflated clicks. Using a Papyrus headline to answer an MFA question, or an MFA tier to answer a Papyrus question, swaps the contract.",
            "Attention is a third column, already separated from viewability in another note. A pixel-and-time viewability threshold, an attention model, a suitability tier, and an IVT rate can all be sold by one company. They remain four instruments. DoubleVerify described Authentic Attention as MRC-accredited when it announced pre-bid attention segments on May 4, 2023. That accreditation sentence is about attention measurement as DV described it then. It is not an accreditation of the 2026 CTV fraud rate, and it is not an accreditation of the MFA tiers."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What an IVT rate refuses to say about the page",
          "paragraphs": [
            "Under 1 percent fraud on a protected CTV campaign means the invalid-traffic cell, with controls on, came back under 1 percent. It does not mean the content was suitable, the attention score was high, or the ad was viewable under the pixel threshold. A buyer who reports one green number to cover brand safety and fraud has collapsed the February 2024 product into the May 2026 product.",
            "The reverse collapse is as common. A site blocked for made-for-advertising can be full of real people. Blocking it is a suitability decision. Calling the blocked impressions IVT misstates the MRC category. General invalid traffic is data centers, crawlers, prefetch, and placements that were never a legitimate opportunity. A low-quality article farm is a content judgment unless and until a measurer shows the traffic itself was invalid. The words in the dashboard often say brand safety and IVT in one module. The standard keeps them apart so a content block is not laundered into a fraud rate, and a fraud rate is not laundered into a content approval.",
            "Pre-bid makes the mix worse if the segment file combines both. A trader avoiding a segment may be avoiding MFA, IVT, or both, and the block rate will not say which rule fired unless the log splits them. The MRC's April 2025 memorandum already says the platform decides whether to drop a request flagged for IVT. A suitability avoid is a further rule in the same seat. Two avoids in one bid log are two policies."
          ]
        },
        {
          "type": "list",
          "heading": "Jobs that a single green rate cannot cover",
          "items": [
            "Invalid traffic: was this a valid opportunity. GIVT is the required list. SIVT is the further investigation.",
            "Brand suitability: was the content inside the brand's rules. DoubleVerify's MFA tiers, February 27, 2024, are this job, with pre-bid avoidance and post-bid measurement.",
            "IAS context control: pre-bid filtering and post-bid blocking for content outside brand guidelines, which is suitability, not Papyrus.",
            "A protected CTV fraud rate under 1 percent, May 7, 2026, does not certify suitability.",
            "A blocked MFA site is not automatically invalid traffic. A bot on a suitable publisher is not automatically a brand-safety pass.",
            "Attention and viewability are further instruments. They are not this comparison."
          ]
        },
        {
          "type": "quote",
          "quote": "A fraud rate says what kind of traffic arrived, and a suitability tier says what kind of page it arrived on, and a campaign can fail one while passing the other.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check that the tag can carry whichever job you bought",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so the verification node is present. Nothing is stored. The check does not know whether the node was hired for IVT or for suitability.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Pre-bid made-for-advertising categories",
              "href": "https://doubleverify.com/company/newsroom/doubleverify-launches-pre-bid-made-for-advertising-mfa-tiered-categories-for-elevated-brand-suitability",
              "description": "DoubleVerify, February 27, 2024. Three suitability tiers, pre-bid avoidance and post-bid measurement.",
              "source": "DoubleVerify"
            },
            {
              "label": "Ad verification",
              "href": "https://integralads.com/apac/solutions/ad-verification/",
              "description": "IAS's description of contextual avoidance, separate from an IVT study.",
              "source": "Integral Ad Science"
            },
            {
              "label": "Viewability vs attention compares a pixel threshold with a score built on interaction",
              "href": "/blog/viewability-vs-attention/",
              "description": "The third and fourth instruments people fold into the same badge.",
              "source": "vastlint"
            },
            {
              "label": "A DoubleVerify alternative is a job inside the suite",
              "href": "/blog/doubleverify-alternative/",
              "description": "Why suitability, attention, and a fraud rate do not swap as one replacement.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "what-is-a-normal-ctv-ivt-rate",
      "title": "A Normal CTV IVT Rate Does Not Exist in the Public Record, Because the Published Numbers Do Not Share a Population",
      "description": "What is a normal CTV IVT rate, an average CTV fraud rate, or an acceptable IVT percentage. The figures people treat as the answer are 19 percent, 21 percent, under 1 percent, nearly 9 percent, 14 percent, and 28 percent. Each one names a different log.",
      "seoTitle": "A normal CTV IVT rate lines up several logs and no single benchmark",
      "seoDescription": "There is no normal CTV IVT rate in the public figures. Pixalate's open-auction US CTV share is 19%. DoubleVerify's protected rate is under 1%, and the unprotected test is nearly 9%.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "An open-auction share, a protected rate, an unprotected test, and two device rows sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "21% invalid",
                "Impression share",
                "Q4 2025 global CTV",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "Fire TV 14%, Samsung 28%",
                "Device share",
                "Q4 2025 global open-programmatic CTV",
                "CTV devices",
                "March 26, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud nearly 9%",
                "Impression share",
                "Controls off",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "34% and 25% to bots",
                "Single campaigns",
                "Two direct CTV buys",
                "CTV",
                "May 7, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/what-is-a-normal-ctv-ivt-rate.png?v=2",
          "alt": "Published CTV invalid-traffic figures sit on different populations: 19 percent open-auction US CTV, under 1 percent with controls on, nearly 9 percent with controls off, and device rows at 14 and 28 percent.",
          "width": 1440,
          "height": 820,
          "caption": "A normal rate would be one population. These sentences are several populations.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "What is a normal CTV IVT rate is the search behind the vendor shortlists. People also type it as an average CTV fraud rate, an acceptable IVT percentage, a good invalid-traffic rate, and whether 19 percent is high. The public record does not contain a normal. It contains a set of rates that look like answers because each one is a percent of impressions.",
            "On March 9, 2026, Pixalate put Q4 2025 US CTV invalid traffic at 19 percent and global CTV at 21 percent, from more than 103 billion programmatic impressions that are predominantly buy-side open auction. On March 26, 2026, the same firm put Amazon Fire TV at 14 percent global device IVT and Samsung Smart TV at 28 percent, inside open-programmatic CTV. On May 7, 2026, DoubleVerify said fraud on DV-protected CTV campaigns was under 1 percent, and nearly 9 percent in controlled tests where those controls were off. Two direct deals in that release, 34 percent and 25 percent of impressions to bots, are single campaigns.",
            "An average of those percents is not an average of the market. Nineteen and one do not share a denominator. A buyer who picks the lower number as the acceptable rate has chosen the protected cell, which is the rate after a control. A buyer who picks 19 percent as the benchmark has chosen a predominantly open-auction quarter. Both can be careful measurements. Neither is what CTV does in general."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why a single acceptable rate keeps failing",
          "paragraphs": [
            "Acceptable is a contract word. It means the threshold in the insertion order, or the cell where a control was on. DoubleVerify's under-1-percent figure is that kind of sentence: fraud remained under 1 percent where DV controls were applied. Using it as the industry normal drops the condition. The nearly-9-percent figure is the closer neighbor to an unprotected log, and it is still a test DoubleVerify defined, not a census.",
            "Inside one Pixalate quarter the device rows already refuse a single normal. Fire TV at 14 percent and Samsung Smart TV at 28 percent are both open-programmatic CTV in Q4 2025. Fourteen points of spread from a change of device, inside one firm and one method, is larger than the gap people argue about between vendors once the populations are allowed to differ. A shortlist that cannot tolerate that spread should not treat 19 and 1 as a ranking of companies, or as a target to manage toward.",
            "Scheme counts make a third fake normal. DoubleVerify's 140 percent more CTV fraud schemes and variants, first quarter of 2026 versus first quarter of 2025, is a count of operations. A year in which schemes proliferate and a protected impression rate stays under 1 percent is compatible with the same release. Someone searching for the average fraud rate and landing on 140 percent has changed the unit from impressions to operations."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to use instead of a normal",
          "paragraphs": [
            "Pick the sentence that matches the buy. Open auction, predominantly, is the 19 percent US CTV share and the 21 percent global share. A campaign with a named control on is the under-1-percent cell. A test with that control off is the nearly-9-percent cell. A direct deal is its own row, and the two examples in the May 2026 release are 34 percent and 25 percent, which is a warning that direct is not a rate of zero. A device mix can move the open-auction number without any vendor changing its mind.",
            "If the question is whether your own log is high, the denominator has to be your log. A pre-bid filter already on will push the remainder toward a protected rate. A mostly open-auction buy with no control will sit closer to the quarterly share. Comparing your remainder to 19 percent, after you have already filtered, makes a working control look like a dirty market. Comparing an unfiltered open-auction buy to the under-1-percent cell makes the market look like a failure of the control you did not buy.",
            "The tag is still outside every one of these rates. Server-side stitching can fire beacons without the device context a fraud model expects, and a wrapper can omit the verification node. vastlint does not publish an IVT rate and it does not decide what acceptable means. It checks whether a VAST 2.0–4.4 tag can carry the media, the trackers, and the verification the rate is supposed to describe."
          ]
        },
        {
          "type": "list",
          "heading": "Rates people paste in as the normal",
          "items": [
            "Pixalate, Q4 2025, US CTV, predominantly open auction, March 9, 2026: 19 percent of impressions.",
            "Pixalate, same release, global CTV: 21 percent. A March 26 cut repeats 21 percent on more than 7 billion CTV transactions.",
            "Pixalate, same quarter, devices: Fire TV 14 percent global IVT, Samsung Smart TV 28 percent.",
            "DoubleVerify, controls on, May 7, 2026: CTV fraud under 1 percent.",
            "DoubleVerify, controls off, same release: CTV fraud near 9 percent.",
            "DoubleVerify, two named direct deals: 34 percent and 25 percent of impressions to bots.",
            "DoubleVerify, Q1 2026 versus Q1 2025: 140 percent more schemes, which is a count, not a rate you can call normal."
          ]
        },
        {
          "type": "quote",
          "quote": "A normal rate would be one population measured one way, and every famous CTV percent in this market is a different population.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag those rates never open",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification nodes and impression events are present. Nothing is stored. This does not produce an IVT rate.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Q4 2025 North America IVT and Ad Fraud Benchmarks",
              "href": "https://www.globenewswire.com/news-release/2026/03/09/3251883/0/en/Pixalate-Releases-Q4-2025-North-America-Invalid-Traffic-IVT-Ad-Fraud-Benchmarks-Connected-TV-CTV-IVT-Rate-in-United-States-at-19.html",
              "description": "March 9, 2026. US CTV at 19 percent, global CTV at 21 percent, predominantly open auction.",
              "source": "Pixalate"
            },
            {
              "label": "Q4 2025 CTV Ad Supply Chain Trends Report",
              "href": "https://www.pixalate.com/blog/q4-2025-ctv-ad-supply-chain-trends-report",
              "description": "March 26, 2026. Fire TV at 14 percent and Samsung Smart TV at 28 percent.",
              "source": "Pixalate"
            },
            {
              "label": "Global Study: Fueled by AI, CTV Fraud Schemes Surge 140% Globally",
              "href": "https://doubleverify.com/company/newsroom/global-study-ctv-fraud-schemes-surge-140-globally",
              "description": "DoubleVerify, May 7, 2026. Protected, unprotected, and single-deal figures.",
              "source": "DoubleVerify"
            },
            {
              "label": "Pixalate vs DoubleVerify lines up 19% with a protected rate",
              "href": "/blog/pixalate-vs-doubleverify/",
              "description": "The pair that produces the two numbers most often called the normal.",
              "source": "vastlint"
            },
            {
              "label": "CTV IVT by device lines up Fire TV at 14% and Samsung at 28%",
              "href": "/blog/ctv-ivt-by-device/",
              "description": "The device and spend cuts people paste in as the normal rate.",
              "source": "vastlint"
            },
            {
              "label": "Mobile app IVT rate lines up 29% in the US and 36% globally",
              "href": "/blog/mobile-app-ivt-rate/",
              "description": "The app cell in the same quarterly table.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "is-doubleverify-better-than-ias",
      "title": "Is DoubleVerify Better Than IAS Depends on Which Job the Word Better Is Allowed to Mean",
      "description": "Is DoubleVerify better than IAS, and the reverse, which is better, and the CTV versions of the same question against Pixalate and HUMAN. Better is a protected rate, a named cluster, a pre-bid seat, or an open-auction share. Those are different wins.",
      "seoTitle": "Is DoubleVerify better than IAS lines up a job and no winner",
      "seoDescription": "DoubleVerify is not better than IAS until the job is named. Papyrus is a 25× click lift on a mobile cluster. DV's protected CTV rate is under 1%. Pixalate's open-auction US CTV share is 19%. vastlint does not pick the winner. It checks the VAST tag and does not classify invalid traffic.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each question, in one row",
          "caption": "Each better-question collapses a different pair of units. The pair notes keep the figures.",
          "columns": [
            "Question people type",
            "What would have to be true",
            "Where the figures are"
          ],
          "rows": [
            {
              "href": "/blog/ias-vs-doubleverify/",
              "cells": [
                "Is DoubleVerify better than IAS",
                "A protected CTV rate and a named mobile cluster would have to be the same object",
                "IAS vs DoubleVerify"
              ]
            },
            {
              "href": "/blog/pixalate-vs-doubleverify/",
              "cells": [
                "Is Pixalate better than DoubleVerify for CTV",
                "An open-auction share and a protected rate would have to be the same log",
                "Pixalate vs DoubleVerify"
              ]
            },
            {
              "href": "/blog/doubleverify-vs-human/",
              "cells": [
                "Is HUMAN better than DoubleVerify",
                "A suggestion on the bid and a campaign rate would have to be the same hop",
                "DoubleVerify vs HUMAN"
              ]
            },
            {
              "href": "/blog/ias-vs-pixalate/",
              "cells": [
                "Is Pixalate better than Integral Ad Science",
                "A quarterly impression share and a cluster lift would have to be the same study",
                "IAS vs Pixalate"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/is-doubleverify-better-than-ias.png?v=2",
          "alt": "Four buyer questions, each pairing a different unit: a protected CTV rate, a named mobile cluster, an open-auction share, and a pre-bid suggestion. None of them crowns a vendor.",
          "width": 1440,
          "height": 820,
          "caption": "Better is the job you name before you name the firm.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Is DoubleVerify better than IAS is the question form of a shortlist the pair notes already separate. People also type which is better, DoubleVerify or IAS, should I switch from IAS to DoubleVerify, and IAS or DoubleVerify for CTV. The same shape shows up as is Pixalate better than DoubleVerify, is HUMAN better than DoubleVerify, and is Pixalate better than Integral Ad Science. Each one asks for a winner. The public figures ask for a job. vastlint does not pick a winner between DoubleVerify and IAS. It checks whether a VAST 2.0–4.4 tag still carries the verification node the hire would have to read, and it does not classify invalid traffic.",
            "IAS's traveling number is Papyrus, August 6, 2026: a named mobile cluster with nearly 25 times the click success rate, roughly 4 times the eCPM, and about 13 percent higher attention than other traffic IAS had already separated. DoubleVerify's traveling number is May 7, 2026: CTV fraud under 1 percent with its controls on, nearly 9 percent with them off, and 140 percent more schemes year over year, which is a count. Pixalate's is March 9, 2026: 19 percent of US CTV impressions invalid in a predominantly open-auction set. HUMAN's is a suggestion on the OpenRTB request, and the MRC's April 11, 2025 memorandum says the platform decides whether that suggestion becomes a drop.",
            "A firm can be the right hire for one of those sentences and a mismatch for the next. vastlint does not pick the winner. It checks whether the VAST 2.0–4.4 tag still contains the verification node the hire would have to read."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Is DoubleVerify better than IAS",
          "paragraphs": [
            "Only if the job is the protected CTV cell, and only as a description of that cell. Under 1 percent is what remained after DV controls. It is not a statement that DV would have produced a smaller Papyrus, because Papyrus is a mobile cluster IAS had already split out of its own observation, scored on clicks, price, and attention. IAS's follow-on is a list of apps, domains, and hostnames filtered after identification. That list is a different artifact from a pre-bid segment DV supplies to DSPs and, through them, to advertisers.",
            "The reverse question, is IAS better than DoubleVerify, has the same shape. Papyrus is evidence about a scheme that was found. It is not a CTV impression share, and it is not the rate on a campaign with controls off. IAS's verification page also describes suitability controls, pre-bid filtering and post-bid blocking for content outside brand guidelines. If the contract is suitability, Papyrus is the wrong scoreboard, and so is the May 2026 fraud rate. The pair note keeps the figures. This paragraph only says which question they can answer."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Is Pixalate better than DoubleVerify for CTV",
          "paragraphs": [
            "People type this when 19 percent and something under 10 percent are sitting in one slide. Pixalate's 19 percent is a classification of predominantly open-auction US CTV. DoubleVerify's under 1 percent is a protected campaign, and the nearly 9 percent is the test with controls off. A lower rate after a control is the control. Calling Pixalate better because 19 is closer to an unfiltered market, or DoubleVerify better because 1 is smaller, ranks the filter, not the firm.",
            "Device rows inside Pixalate make the same point without a second logo. Fire TV at 14 percent and Samsung Smart TV at 28 percent are one quarter. A method that moves fourteen points when the device changes does not become a vendor ranking when the next number comes from a different firm and a different filter. For a protected buy, the open-auction share is the wrong target. For a picture of the open auction, the protected rate is the wrong target."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Is HUMAN better than DoubleVerify, and is Pixalate better than Integral Ad Science",
          "paragraphs": [
            "Is HUMAN better than DoubleVerify compares a pre-bid suggestion with a campaign rate. MediaGuard returns an IVT prediction on the request, before the impression exists. FraudSensor is required beside it. The MRC says HUMAN's suggestion goes to DSPs and SSPs, not to advertisers, and that HUMAN does not itself drop the request. DV's segments, on the same memorandum, can reach advertisers through DSPs, and DV's under-1-percent figure is a later measurement of campaigns that ran. Better at blocking the next bid and better at labeling a served campaign are both real procurements. They are not one ranking.",
            "Is Pixalate better than Integral Ad Science, which is also typed Pixalate vs IAS, compares the 19 percent open-auction share with Papyrus's click multiple. A quarterly impression benchmark does not say whether the reading-app cluster was in the set. The cluster's lift does not say what share of US CTV Pixalate would have called invalid. The full figures are on the pair pages. The decision is to stop averaging them."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the question",
          "paragraphs": [
            "Write the job in the cell where the winner was going to go. Protected CTV rate, named-scheme study, open-auction benchmark, pre-bid suggestion, suitability, attention. Is DoubleVerify better than IAS becomes answerable inside one of those rows, and it stays unanswered across them. If you need both a pre-bid seat and a post-bid label, the next note is whether to run the firms together, which is a tag question, not a winner.",
            "Keep the pair pages for the numbers. This page is the map of the question. vastlint still does not classify invalid traffic. After the job is chosen, the tag either carries that firm's verification node or the measurement is a claim about a document that omitted it."
          ]
        },
        {
          "type": "list",
          "heading": "Answers that stay inside one job",
          "items": [
            "Is DoubleVerify better than IAS: only for the job you named. Papyrus is a 25-times click lift on a named mobile cluster. The under-1-percent figure is protected CTV.",
            "Is Pixalate better than DoubleVerify for CTV: 19 percent is an open-auction share. Under 1 percent is a protected rate. Nearly 9 percent is the control turned off.",
            "Is HUMAN better than DoubleVerify: a suggestion on the bid, acted on by the platform, is a different hop from a rate on impressions that already ran.",
            "Is Pixalate better than Integral Ad Science: a quarterly impression share and a cluster study do not order each other.",
            "Which verification vendor should I use: the one whose public artifact matches the job. The tag still has to carry the node."
          ]
        },
        {
          "type": "quote",
          "quote": "A winner exists inside one job, and a shortlist that asks which firm is better has usually skipped the job.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag after the job is chosen",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so the verification node is present. Nothing is stored. This does not choose a vendor.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAS vs DoubleVerify lines up nearly 25× clicks and a scheme count",
              "href": "/blog/ias-vs-doubleverify/",
              "description": "The figures behind is DoubleVerify better than IAS.",
              "source": "vastlint"
            },
            {
              "label": "Pixalate vs DoubleVerify lines up 19% with a protected rate",
              "href": "/blog/pixalate-vs-doubleverify/",
              "description": "The figures behind the CTV version of the question.",
              "source": "vastlint"
            },
            {
              "label": "DoubleVerify vs HUMAN lines up a protected rate and a pre-bid suggestion",
              "href": "/blog/doubleverify-vs-human/",
              "description": "The figures behind is HUMAN better than DoubleVerify.",
              "source": "vastlint"
            },
            {
              "label": "IAS and DoubleVerify together lines up two logs on one impression",
              "href": "/blog/ias-and-doubleverify-together/",
              "description": "What changes when the answer is both, rather than a winner.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ias-and-doubleverify-together",
      "title": "IAS and DoubleVerify Together Produce Two Logs on One Impression, and the Logs Do Not Have to Agree",
      "description": "Using both IAS and DoubleVerify, or DoubleVerify and IAS on the same campaign, means two signals and often two verification nodes. The MRC does not require those signals to print the same IVT rate. Sophisticated detection is encouraged, not a shared list. The tag has to carry both nodes or one firm is measuring a document that omitted it.",
      "seoTitle": "IAS and DoubleVerify together lines up two logs on one impression",
      "seoDescription": "Running IAS and DoubleVerify together does not merge their rates. Papyrus is a named mobile cluster. DV's protected CTV rate is under 1%. Both nodes still have to be in the VAST tag. vastlint checks that both verification nodes survived. It does not reconcile the logs.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "Two firms on one campaign still publish different objects. The tag is where both would have to be present.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "IAS",
                "Nearly 25× clicks, about 4× eCPM, 13% higher attention",
                "Cluster lift",
                "Papyrus vs other IAS traffic",
                "Mobile",
                "August 6, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Segments toward advertisers",
                "Who can query",
                "DSPs, SSPs, and advertisers through DSPs",
                "Programmatic",
                "April 11, 2025"
              ]
            },
            {
              "cells": [
                "MRC",
                "SIVT methods need not match",
                "Category",
                "Sophisticated filtration is encouraged, not the required floor",
                "Measurement",
                "June 2020"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/ias-and-doubleverify-together.png?v=2",
          "alt": "One impression can carry an IAS verification node and a DoubleVerify verification node. The two firms still publish different objects, and sophisticated IVT methods are not required to match.",
          "width": 1440,
          "height": 820,
          "caption": "Both on the plan is two logs. Both in the tag is a separate check.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "IAS and DoubleVerify together is the search that shows up when the versus question will not settle. People also type use both IAS and DoubleVerify, DoubleVerify and IAS overlap, two verification vendors, and whether a second firm is wasted spend. The versus notes compare published studies. This one is about one impression that both firms are asked to label. vastlint does not reconcile the two logs. It checks whether a VAST 2.0–4.4 tag still carries the verification nodes you think you bought, and it does not classify invalid traffic.",
            "The studies still do not merge. IAS's Papyrus note, August 6, 2026, is a lift on a named mobile cluster: nearly 25 times the clicks against other traffic IAS had separated. DoubleVerify's May 7, 2026 CTV release is fraud under 1 percent with controls on and nearly 9 percent with them off. Putting both contracts on one campaign does not average those into a shared rate. It buys two instruments. If they disagree, the MRC's June 2020 addendum already said they might. General invalid traffic is a shared list and is required. Sophisticated invalid traffic is encouraged, and the methods differ by vendor, so two accredited firms can agree on the general slice and disagree on the sophisticated one.",
            "vastlint does not reconcile the disagreement. It checks whether a VAST 2.0–4.4 tag structurally contains the verification nodes you think you bought, including a duplicate vendor identifier if the same vendor is declared twice. Two different vendors can both be present. A missing node means one of the two logs was never going to exist."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What you actually double",
          "paragraphs": [
            "You can double the pre-bid seat, the post-bid label, or both. The MRC's April 11, 2025 memorandum says DoubleVerify supplies pre-bid segments to DSPs, SSPs, and advertisers through DSPs, and does not itself drop the request. IAS's Papyrus note describes a list applied after a scheme is identified. Those can run on the same campaign and still refer to different moments: a segment queried before the bid, and a hostname filtered after someone named the scheme. Overlap in the contract is not overlap in the hop.",
            "You can also double the post-bid tag. Each firm wants a Verification node, or an extension that reaches its host, on the impression that served. VAST allows more than one verification entry. If a wrapper keeps one and drops the other, the campaign is double-covered in the spreadsheet and single-covered in the player. The firm that was dropped will not print a rate for that impression. The firm that remained will. A gap between their reported IVT is then partly a gap in the document, which looks like a methodology fight.",
            "Disagreement on the sophisticated slice is still expected when both nodes survive. The addendum's point in splitting general from sophisticated was to keep the list-based floor comparable and to stop pretending the advanced slice is. A buyer who runs both firms in order to get the truth has bought a second opinion, and the standard does not say the second opinion must match. Use the disagreement as a flag to inspect the impression, not as proof that one logo failed."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with two contracts",
          "paragraphs": [
            "Assign each firm a job before you compare their dashboards. If IAS is on the plan for a named-scheme list and suitability, and DoubleVerify is on the plan for a protected CTV rate, the dashboards are allowed to move differently. If both are on the plan for the same post-bid IVT number, read the category. A general-invalid gap is a list problem and should be small. A sophisticated gap can be the product.",
            "Then open the tag. Count verification nodes, hosts, and vendor identifiers against the contracts. A node that still names a discontinued host, such as Moat after September 30, 2024, is not a third opinion. It is a dead URL beside the two living ones. vastlint will tell you the nodes are present and whether a vendor identifier is duplicated. It will not tell you which firm's sophisticated label was right."
          ]
        },
        {
          "type": "list",
          "heading": "What running both does not do",
          "items": [
            "It does not average Papyrus's 25-times click lift with a protected CTV rate under 1 percent.",
            "It does not force the sophisticated slices to match. The MRC addendum encourages that work and does not make it one shared list.",
            "It does not put both firms in the same seat. DV's pre-bid segments can reach advertisers through DSPs. A post-identification list is a later object.",
            "It does not survive a wrapper that keeps one Verification node and drops the other.",
            "A duplicate of the same vendor identifier is a structural problem. Two different vendors in two nodes can both be legitimate."
          ]
        },
        {
          "type": "quote",
          "quote": "Two contracts on one impression buy two logs, and the tag is the only place you can see whether both logs had a node to read.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "See whether both verification nodes survived",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so each Verification entry is structurally present. Nothing is stored. This does not decide which firm is right.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Invalid Traffic Detection and Filtration Standards Addendum, June 2020 update",
              "href": "https://www.mediaratingcouncil.org/sites/default/files/Standards/IVT%20Addendum%20Update%20062520.pdf",
              "description": "GIVT is the shared required floor. SIVT methods can differ.",
              "source": "Media Rating Council"
            },
            {
              "label": "MRC statement on pre-bid IVT requirements, April 11, 2025",
              "href": "https://mediaratingcouncil.org/sites/default/files/News/MRC%20Statement%20on%20pre%20bid%20IVT%20requirements%20and%20processes.pdf",
              "description": "Who receives a pre-bid signal, and who decides to filter.",
              "source": "Media Rating Council"
            },
            {
              "label": "Is DoubleVerify better than IAS lines up a job and no winner",
              "href": "/blog/is-doubleverify-better-than-ias/",
              "description": "The question this note answers with both, instead of a winner.",
              "source": "vastlint"
            },
            {
              "label": "How to validate AdVerifications in VAST tags",
              "href": "/blog/how-to-validate-adverifications-in-vast-tags/",
              "description": "What a missing verification node does to the measurement, whoever the vendor is.",
              "source": "vastlint"
            },
            {
              "label": "Why IAS and DoubleVerify disagree lines up two logs and a missing node",
              "href": "/blog/why-ias-and-doubleverify-disagree/",
              "description": "What to do with the two exports after both firms are on the plan.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "white-ops-vs-doubleverify",
      "title": "White Ops vs DoubleVerify Compares a Company Name That Changed in 2021 With a Rate Published in 2026",
      "description": "White Ops reintroduced itself as HUMAN on March 30, 2021. The products people still search, MediaGuard and FraudSensor, are the names in the current docs. A White Ops alternative, or White Ops vs IAS, is a HUMAN comparison plus a retired company name. DoubleVerify's under-1-percent CTV rate is a 2026 figure about a different firm.",
      "seoTitle": "White Ops vs DoubleVerify lines up a 2021 rename and a later rate",
      "seoDescription": "White Ops became HUMAN on March 30, 2021. White Ops vs DoubleVerify is that rename plus DV's 2026 CTV rate, fraud under 1% with controls on. MediaGuard is still the name in the current docs. vastlint checks the VAST tag. It does not classify invalid traffic.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "Programmatic",
        "CTV",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A company rename, a product-name sentence from the same season, and a later fraud rate sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "White Ops",
                "Company name becomes HUMAN",
                "Rename",
                "The firm, not a measurement",
                "Corporate",
                "March 30, 2021"
              ]
            },
            {
              "cells": [
                "White Ops",
                "Post-bid accredited since 2016, pre-bid claimed in this release",
                "Accreditation announcement",
                "Desktop, mobile web, in-app, CTV",
                "SIVT",
                "January 27, 2021"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "Docs still say MediaGuard and FraudSensor",
                "Product names",
                "Current integration docs",
                "Pre-bid and post-bid",
                "Current docs"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/white-ops-vs-doubleverify.png?v=2",
          "alt": "White Ops reintroduced itself as HUMAN on March 30, 2021. Current docs still use the names MediaGuard and FraudSensor. DoubleVerify's under 1 percent CTV figure is a 2026 rate about a different company.",
          "width": 1440,
          "height": 820,
          "caption": "The query still uses the 2021 company name. The product names in the docs did not stay retired.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "White Ops vs DoubleVerify is a comparison query that kept the old company name. People also type White Ops vs IAS, White Ops alternative, WhiteOps now HUMAN, and HUMAN Security formerly White Ops. On March 30, 2021, White Ops reintroduced itself as HUMAN. Tamer Hassan, then CEO, said the company had officially changed its name. A 2026 shortlist that still says White Ops is asking about HUMAN, and then comparing that firm to a DoubleVerify rate from May 7, 2026. vastlint does not choose between HUMAN and DoubleVerify. It checks whether a VAST 2.0–4.4 tag still carries the verification node, and it does not classify invalid traffic.",
            "The product names are a second trap in the same season. On January 27, 2021, White Ops announced MRC accreditation for pre-bid and post-bid sophisticated invalid traffic detection and mitigation across desktop, mobile web, in-app, and CTV. The release described the advertising product as the solution formerly known as MediaGuard, and post-bid detection as previously known as FraudSensor, and it said post-bid detection had been accredited since 2016. White Ops said it was the first company with that end-to-end accreditation. The integration docs HUMAN publishes now still title the pre-bid product MediaGuard and the post-bid tag FraudSensor. A search for the retired company and a search for MediaGuard can land on the same living product, or on a sentence that said the product name had already moved.",
            "vastlint has no relationship to White Ops or to HUMAN. It does not know that a vendor string in a tag was a company name in 2021. It checks whether the verification node is structurally present in VAST 2.0–4.4."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the rename did, and what it did not",
          "paragraphs": [
            "The March 30, 2021 announcement is a company name. Business Wire carried it. Hassan said the name represented the mission of protecting the integrity of the internet from bot attacks. He also said a new identity had been in the works since October 2020. Nothing in that announcement rescores historical White Ops impressions under the HUMAN name, and nothing in it is a fraud rate that can be set beside DoubleVerify's 2026 CTV study.",
            "The January accreditation release is a claim about audit scope, made while the company was still called White Ops. Pre-bid and post-bid, desktop through CTV, sophisticated invalid traffic. The word first is the company's word. A later reader who treats that release as proof that HUMAN's current model blocks more than DoubleVerify has jumped from a 2021 accreditation sentence to a 2026 impression share. Accreditation is a process audit. The under-1-percent figure is a protected-campaign rate. They do not rank each other.",
            "MediaGuard, in the current docs, is still the pre-bid prediction on the OpenRTB bid, and FraudSensor is still required beside it. The MRC's April 11, 2025 memorandum describes HUMAN, not White Ops: suggestions go to DSPs and SSPs, and HUMAN does not itself drop the request. If a trafficking sheet says White Ops, the firm to call is HUMAN. If a tag says MediaGuard, read the current docs before you delete it as a legacy string. The company name aged out. The product name in the docs came back, or never fully left."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What White Ops vs IAS and a White Ops alternative actually are",
          "paragraphs": [
            "White Ops vs IAS is the same rename sitting on a different pair. IAS's public 2026 artifact is Papyrus, a named mobile cluster, not a rebuttal of a 2021 accreditation press release. The comparison that can be had is HUMAN vs IAS: a pre-bid suggestion against a post-identification study. That note already exists. Adding White Ops to the title does not create a third firm.",
            "A White Ops alternative is a HUMAN alternative, unless the template is so old that the job was only the company as it existed before March 30, 2021. The jobs that survived are the pre-bid suggestion, the post-bid tag, and whatever accreditation scope a buyer still needs a current letter for. DoubleVerify is a candidate for some of those jobs and not for the seat. The MRC says DV's segments can reach advertisers through DSPs. HUMAN's suggestions, in that memorandum, stop at platforms. Replacing a White Ops contract with a DV campaign rate does not put a millisecond flag on the next bid.",
            "Moat is the other retired name in these templates, and it is not this situation. Oracle ended Moat Analytics on September 30, 2024. White Ops changed its name and kept operating. A Moat host in a tag is a dead measurement. A White Ops string in a tag might be a stale label on a living vendor, or a host that was updated when the company renamed. The string alone does not tell you which."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the old name",
          "paragraphs": [
            "Replace White Ops with HUMAN in the matrix, then ask the HUMAN question: suggestion on the bid, or a rate on served impressions. The DoubleVerify comparison is the pair note for the second reading, and it is a different hop from the first. The January 2021 release is history of an accreditation claim. It is not this quarter's block rate.",
            "In the tag, keep MediaGuard and FraudSensor as names to look up, and treat a bare White Ops vendor key as a string to confirm with whoever owns the contract. vastlint will see a verification node. It will not translate a 2021 company name into a 2026 host."
          ]
        },
        {
          "type": "list",
          "heading": "Names that the query collapses",
          "items": [
            "March 30, 2021: White Ops reintroduces itself as HUMAN. That is a company name.",
            "January 27, 2021: White Ops announces pre-bid and post-bid SIVT accreditation and describes MediaGuard and FraudSensor with the words formerly and previously. Post-bid accreditation is dated to 2016 in that release. The word first is White Ops's.",
            "Current HUMAN docs: the pre-bid product is still titled MediaGuard, and the post-bid tag is still FraudSensor.",
            "MRC, April 11, 2025: the firm in the memorandum is HUMAN. Suggestions go to platforms. HUMAN does not itself drop the request.",
            "DoubleVerify, May 7, 2026: CTV fraud under 1 percent with controls on. That is not a rescore of White Ops.",
            "A White Ops alternative in 2026 is a HUMAN question. A Moat alternative is an end-of-life question. They are not the same retirement."
          ]
        },
        {
          "type": "quote",
          "quote": "The company name changed in 2021, the product names in the docs are still MediaGuard and FraudSensor, and a 2026 fraud rate from another firm is not a verdict on either.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the verification node, whatever the vendor string says",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so AdVerifications are present. Nothing is stored. The check does not know that White Ops is now HUMAN.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "White Ops reintroduces itself as HUMAN",
              "href": "https://www.businesswire.com/news/home/20210330005240/en/White-Ops-Reintroduces-Itself-as-HUMAN-Signaling-Cybersecurity-Companys-Dedication-to-Protecting-Enterprises-from-Bot-Attacks",
              "description": "Business Wire, March 30, 2021. The company-name change.",
              "source": "Business Wire"
            },
            {
              "label": "White Ops MRC accreditation announcement, January 27, 2021",
              "href": "https://www.humansecurity.com/newsroom/white-ops-is-the-first-company-to-receive-mrc-accreditation-for-both-pre-bid-and-post-bid-invalid-traffic-detection-and-mitigation-across-desktop-mobile/",
              "description": "The accreditation claim, and the formerly MediaGuard and previously FraudSensor wording.",
              "source": "HUMAN"
            },
            {
              "label": "MediaGuard overview",
              "href": "https://docs.humansecurity.com/advertising/mediaguard-overview.mdx",
              "description": "Current docs still use the MediaGuard name for the pre-bid product.",
              "source": "HUMAN"
            },
            {
              "label": "DoubleVerify vs HUMAN lines up a protected rate and a pre-bid suggestion",
              "href": "/blog/doubleverify-vs-human/",
              "description": "The living comparison once White Ops is read as HUMAN.",
              "source": "vastlint"
            },
            {
              "label": "A HUMAN alternative has to replace a suggestion on the bid",
              "href": "/blog/human-security-alternative/",
              "description": "What a White Ops alternative means after the rename.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "doubleverify-alternative",
      "title": "A DoubleVerify Alternative Is a Job Inside the Suite, and the Public Numbers Do Not Share a Scale",
      "description": "People search for a DoubleVerify alternative when a contract is up for review. The suite covers a protected CTV rate, a count of schemes, pre-bid segments, a post-serve block the client configured, attention, and brand suitability. IAS, HUMAN, and Pixalate publish different objects, and Moat is no longer on the shelf.",
      "seoTitle": "DoubleVerify alternative lines up a job and no single swap",
      "seoDescription": "A DoubleVerify alternative depends on the job. Protected CTV fraud is under 1% with DV controls on. HUMAN suggests on the bid. Pixalate's open-auction US CTV share is 19%. vastlint is not that alternative. It checks the VAST tag and does not classify invalid traffic.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A protected rate, a pre-bid suggestion, an open-auction share, and an end-of-life date sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud nearly 9%",
                "Impression share",
                "Controls off",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Segments to the buyer, the platform still decides",
                "Who drops the request",
                "DSPs, SSPs, and advertisers through DSPs",
                "Programmatic",
                "April 11, 2025"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "A suggestion, and the platform still decides",
                "Who drops the request",
                "DSPs and SSPs, not advertisers",
                "Programmatic",
                "April 11, 2025"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Moat",
                "End of service",
                "Product",
                "Oracle advertising products, including Moat Analytics",
                "Measurement",
                "September 30, 2024"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/doubleverify-alternative.png?v=2",
          "alt": "Four jobs inside a DoubleVerify contract: a protected CTV rate, pre-bid segments, attention, and brand suitability. IAS, HUMAN, Pixalate, and a discontinued Moat product answer different jobs.",
          "width": 1440,
          "height": 820,
          "caption": "A replacement exists inside one job. The suite does not swap as a single score.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "DoubleVerify alternative is the search that shows up when a verification contract is up for review. The phrase treats the company as one product with one score, and the public record does not. On May 7, 2026, DoubleVerify said fraud on DV-protected CTV campaigns was under 1 percent, and nearly 9 percent in controlled tests where those controls were off. On April 11, 2025, the Media Rating Council described a different object: DV supplies pre-bid segments and IVT classifications, and DV does not itself drop the bid request. On March 9, 2026, Pixalate published a third object, 19 percent of US CTV impressions invalid inside a predominantly open-auction set. Oracle had already ended Moat Analytics on September 30, 2024. vastlint is not a DoubleVerify alternative. It checks whether a VAST 2.0–4.4 tag still carries the verification node a replacement vendor would have to read, and it does not classify invalid traffic.",
            "A buyer can hire another firm. The hire only replaces the job that firm actually publishes. A protected-campaign rate, a suggestion on the OpenRTB request, a quarterly open-auction share, an attention segment, and a brand-suitability category are five decisions. Search collapses them into one column labeled alternative.",
            "vastlint is not that alternative. It is independent of DoubleVerify, IAS, Pixalate, and HUMAN. It checks whether a VAST 2.0–4.4 tag still carries the verification node and the impression events a measurement firm would have to read. It does not classify invalid traffic, and it does not score attention."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What sits inside the DoubleVerify name",
          "paragraphs": [
            "The May 7, 2026 CTV release is the number people paste into a spreadsheet. Protected campaigns, controls on, fraud under 1 percent. Unprotected tests, controls off, nearly 9 percent. The same release counts 140 percent more CTV fraud schemes and variants in the first quarter of 2026 than in the first quarter of 2025. A scheme count and an impression share are different units, and both are DoubleVerify's. About $1.8 million per billion impressions is an estimated cost on unprotected campaigns, not a rate. Two direct deals, 34 percent of impressions to bots in one healthcare buy and 25 percent in a CPG buy, are single campaigns.",
            "Pre-bid is a second job, and the MRC's April 11, 2025 memorandum is specific about who acts. DV provides pre-bid segments and IVT classifications to DSPs, SSPs, and advertisers through DSPs, by API or by flat file. The memorandum says DV does not directly filter requests or prevent ad serving. It says DV enables blocking after the impression only where the client has configured that block. A segment the buyer can query, and a block the buyer turned on, are both real. Neither one is the under-1-percent campaign rate, which is what remained in a measured cell after controls were on.",
            "Attention and brand suitability are further jobs, with their own dates. On May 4, 2023, DoubleVerify announced pre-bid attention segments built from Authentic Attention, and it described that measurement product as MRC-accredited at the time of the announcement. On February 27, 2024, it announced tiered made-for-advertising categories for pre-bid avoidance inside Authentic Brand Suitability, next to a post-bid measure of the same issue. An RFP that says replace DoubleVerify has to say which of these the contract actually uses. A fraud rate will not stand in for an attention segment, and an attention segment will not stand in for a suitability category."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Which public artifact can stand in for which job",
          "paragraphs": [
            "IAS is the name that usually shares the RFP. The public research that travels with the name is Papyrus, published August 6, 2026: a named mobile cluster in novel-reading apps, nearly 25 times the click success rate, roughly 4 times the eCPM, and about 13 percent higher attention than other traffic IAS had already separated. IAS says clients on IVT avoidance are filtered against the apps, domains, and hostnames once that scheme is identified. That is a list after identification. IAS's verification page also describes pre-bid filtering and post-bid blocking for content that falls outside brand guidelines, which is a suitability control. Papyrus does not say what fraction of a CTV campaign would have remained after an IAS control, and the suitability page does not publish the May 2026 CTV rates.",
            "HUMAN is the name that shares the pre-bid conversation. MediaGuard, in HUMAN's own docs, returns an IVT prediction on the OpenRTB bid in time to decide whether to bid, and FraudSensor is required alongside it so the post-bid tag can check the prediction. The MRC memorandum says HUMAN provides that suggestion to DSPs and SSPs, not to advertisers or agencies, and that HUMAN does not directly filter the request, prevent serving, or enable the block. The decision sits at the platform. HUMAN's package page uses the word filtration and says the analysis of a bid request is built to return in 12 milliseconds or less. The package sentence and the MRC sentence can both be true: one describes the product's speed and intent, and the other says who is allowed to drop the request. A buyer who wanted DV segments inside an advertiser seat is not looking at the same distribution.",
            "Pixalate is the name that shares the CTV benchmark conversation. The March 9, 2026 table puts US CTV invalid traffic at 19 percent and global CTV at 21 percent, from more than 103 billion programmatic impressions that are predominantly buy-side open auction. Pixalate's product page names three products: pre-bid blocking, post-bid analytics, and a Media Ratings Terminal. Its metrics note says designations in those products, including the blocking lists, reflect Pixalate's opinions and are neither facts nor guarantees. A 19 percent open-auction share is a classification of a log. It is not the rate left after DoubleVerify's controls, and a blocking list sold as an opinion is not a protected-campaign study.",
            "Moat is the name that still appears in old templates. Oracle ended Moat Analytics with the rest of that advertising business on September 30, 2024. AdExchanger reported that DoubleVerify won 70 percent of the former Moat advertiser RFPs it entered, in a window of about six weeks. That figure is a share of pitches, not a re-measurement of impressions, and it is not evidence that a 2026 fraud rate replaced a Moat attention score. A tag that still names Moat is a host, not a living alternative."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Write the job before you write the vendor. Protected CTV impression rate, scheme count, pre-bid segment, post-serve block, attention segment, brand suitability, open-auction benchmark, post-identification list. A DoubleVerify alternative is legitimate inside one of those rows. It is a category error across the row.",
            "Ask who is allowed to act. The MRC's point, for both DV and HUMAN, is that the measurement firm is not the party that drops the bid. If the contract you are replacing is a segment your traders query, the replacement has to show up in that seat. If the contract is a post-bid label on served CTV, the replacement has to read the impression, which means the VAST tag still has to carry the verification node.",
            "Keep the tag check separate from the vendor decision. Server-side stitching can fire beacons without the device context a fraud model expects, and a wrapper can omit AdVerifications while the impression still counts. vastlint checks that structure for VAST 2.0–4.4. It will not tell you whether IAS, HUMAN, or Pixalate should hold the contract."
          ]
        },
        {
          "type": "list",
          "heading": "Jobs a single alternative cannot cover",
          "items": [
            "DoubleVerify, DV-protected CTV campaigns, May 7, 2026: fraud under 1 percent.",
            "DoubleVerify, controls not applied, same release: fraud near 9 percent.",
            "DoubleVerify, Q1 2026 versus Q1 2025: 140 percent more CTV schemes and variants, which is a count, not an impression share.",
            "MRC, April 11, 2025: DV supplies pre-bid segments and does not itself filter the bid request. Post-serve blocking is the client's configuration.",
            "MRC, same memorandum: HUMAN suggests IVT to DSPs and SSPs and does not itself filter the request.",
            "Pixalate, Q4 2025, US CTV, predominantly open auction: 19 percent of impressions.",
            "Moat Analytics: access ended September 30, 2024. A leftover verification host is not a score."
          ]
        },
        {
          "type": "quote",
          "quote": "A replacement is real inside one job, and a shortlist that swaps the whole suite for one rival rate has changed the question.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag the next vendor would have to read",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so AdVerifications and impression events are present. Nothing is stored. This does not choose a verification vendor.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "MRC statement on pre-bid IVT requirements, April 11, 2025",
              "href": "https://mediaratingcouncil.org/sites/default/files/News/MRC%20Statement%20on%20pre%20bid%20IVT%20requirements%20and%20processes.pdf",
              "description": "Who supplies a pre-bid signal, and who actually decides to filter the request, for DoubleVerify and for HUMAN.",
              "source": "Media Rating Council"
            },
            {
              "label": "Global Study: Fueled by AI, CTV Fraud Schemes Surge 140% Globally",
              "href": "https://doubleverify.com/company/newsroom/global-study-ctv-fraud-schemes-surge-140-globally",
              "description": "DoubleVerify, May 7, 2026. Protected and unprotected CTV rates, and the scheme count.",
              "source": "DoubleVerify"
            },
            {
              "label": "Pre-bid made-for-advertising categories",
              "href": "https://doubleverify.com/company/newsroom/doubleverify-launches-pre-bid-made-for-advertising-mfa-tiered-categories-for-elevated-brand-suitability",
              "description": "DoubleVerify, February 27, 2024. Brand suitability as its own pre-bid and post-bid job.",
              "source": "DoubleVerify"
            },
            {
              "label": "Q4 2025 North America IVT and Ad Fraud Benchmarks",
              "href": "https://www.globenewswire.com/news-release/2026/03/09/3251883/0/en/Pixalate-Releases-Q4-2025-North-America-Invalid-Traffic-IVT-Ad-Fraud-Benchmarks-Connected-TV-CTV-IVT-Rate-in-United-States-at-19.html",
              "description": "Pixalate, March 9, 2026. US CTV at 19 percent in a predominantly open-auction set.",
              "source": "Pixalate"
            },
            {
              "label": "DoubleVerify vs HUMAN lines up a protected rate and a pre-bid suggestion",
              "href": "/blog/doubleverify-vs-human/",
              "description": "The pair the alternative search usually collapses.",
              "source": "vastlint"
            },
            {
              "label": "IVT filtration lines up a required back-end removal and an optional block",
              "href": "/blog/ivt-filtration/",
              "description": "Why a filtered campaign rate and an open-auction share are different subtractions.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "doubleverify-vs-human",
      "title": "DoubleVerify vs HUMAN Compares a Protected Campaign Rate With a Suggestion on the Bid",
      "description": "DoubleVerify's May 2026 CTV report puts fraud under 1 percent when its controls are on, and near 9 percent when they are off. HUMAN MediaGuard returns an IVT prediction on the OpenRTB request before the impression exists. The MRC says neither firm drops the bid itself.",
      "seoTitle": "DoubleVerify vs HUMAN lines up a protected rate and a pre-bid suggestion",
      "seoDescription": "DoubleVerify reports CTV fraud under 1% with controls on and nearly 9% with them off. HUMAN returns an IVT suggestion on the bid. The MRC says the platform decides. vastlint checks the VAST tag. It does not classify invalid traffic.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A protected-campaign rate and a pre-bid suggestion sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud nearly 9%",
                "Impression share",
                "Controls off",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "140% more schemes than Q1 2025",
                "Scheme count",
                "CTV schemes and variants",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "IVT suggestion before the bid",
                "Pre-bid decision input",
                "One OpenRTB request",
                "Programmatic",
                "MediaGuard docs"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "0.5% SIVT and 0.05% GIVT passed through",
                "Sampling valve",
                "Flagged traffic, so FraudSensor can rescan",
                "Programmatic",
                "HUMAN docs"
              ]
            },
            {
              "cells": [
                "MRC",
                "Neither firm drops the request itself",
                "Who decides",
                "DSP or SSP, from what the firm supplied",
                "Programmatic",
                "April 11, 2025"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/doubleverify-vs-human.png?v=2",
          "alt": "DoubleVerify's under 1 percent and nearly 9 percent are protected and unprotected CTV tests. HUMAN MediaGuard is an IVT suggestion on the OpenRTB request, and the MRC says the platform decides whether to drop it.",
          "width": 1440,
          "height": 820,
          "caption": "A rate on impressions that already ran, and a suggestion on a request that has not become an impression, are different hops.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "DoubleVerify vs HUMAN, and the reverse search HUMAN vs DoubleVerify, is the shortlist for two firms buyers call when they want invalid traffic kept off a campaign. The public artifacts are not the same artifact. On May 7, 2026, DoubleVerify said fraud rates on DV-protected CTV campaigns were under 1 percent, and nearly 9 percent where protection controls were not applied. HUMAN's MediaGuard documentation describes a prediction, made from the OpenRTB bid, of whether that opportunity is likely invalid, returned before the impression exists. On April 11, 2025, the Media Rating Council described both firms and then said the same structural thing about each: the firm supplies a signal, and the platform decides whether to act. vastlint does not choose between a protected campaign rate and a pre-bid suggestion. It checks whether a VAST 2.0–4.4 tag still carries the verification node, and it does not classify invalid traffic.",
            "One sentence is about impressions that were bought and then measured, split by whether a control was on. The other is about a request that has not been bought. A buyer who treats the under-1-percent rate as HUMAN's block rate, or treats a MediaGuard flag as a statement about a CTV campaign, has changed the hop and the unit in one move.",
            "Both firms will take a fee to reduce invalid traffic. The research release and the integration docs do not say they are reducing the same thing at the same moment. Remove the names and a protected-campaign rate still does not rank a suggestion on a bid request."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the DoubleVerify figures measure",
          "paragraphs": [
            "The May 7 release is explicit about two CTV populations. Protected campaigns, verification controls applied, showed fraud under 1 percent. Unprotected campaigns, controlled tests where those controls were not applied, showed nearly 9 percent. The measurement spans billions of impressions. The unprotected cell is the cell where DV says the controls were off. It is not a census of CTV.",
            "Other lines in that release do not belong in the same cell. One hundred forty percent more CTV fraud schemes and variants, first quarter of 2026 versus first quarter of 2025, is a count of operations. About $1.8 million per billion impressions is an estimated cost on unprotected campaigns. Direct deals have their own rows: 34 percent of impressions to bots in one healthcare campaign, 25 percent in a CPG campaign. North America violations were 82 percent bot fraud. APAC violations were 98 percent data-center traffic.",
            "The pre-bid product is a further object, described by the MRC rather than by the CTV release. The April 11, 2025 memorandum says DV provides pre-bid segments and IVT classifications to DSPs, SSPs, and advertisers and agencies through DSPs, by API or by flat file, built from back-end detection. It says DV does not directly filter requests or prevent ad serving. It says DV can enable blocking after the serve, only where the client configured it, and that this configuration is part of what an audit looks at. A trader querying a segment, and a campaign whose post-bid rate came in under 1 percent, are both DoubleVerify. They are not one number."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the HUMAN figures measure",
          "paragraphs": [
            "MediaGuard sits between bid requests received and bids made. The caller sends fields from the bid, or the OpenRTB BidRequest. MediaGuard returns a prediction, including an IVT flag the caller can use to drop the request, and it sorts flagged requests into categories. HUMAN's docs call it a predictive model based on reputation data, and they say FraudSensor, the post-bid tag, is required so those predictions can be checked and the model updated.",
            "The pass-through is a valve, not a market rate. HUMAN's closing-the-loop note says MediaGuard lets 0.5 percent of traffic it has flagged as sophisticated invalid traffic through, so FraudSensor can rescan it, and lets 0.05 percent of general invalid traffic through for the same reason. A brochure claim of 20 trillion transactions a week, and of more than 85 percent of global programmatic impressions running through MediaGuard, is a coverage claim. Coverage is how often the model is asked. It is not how often anyone says no.",
            "The MRC memorandum draws the institutional line. HUMAN provides suggestions on whether a request is IVT, based on back-end detection, through an API. Those suggestions go to DSPs and SSPs, not to advertisers or agencies. HUMAN does not directly filter requests, prevent ad serving, or enable blocking. The decision to bid sits at the platform, outside the audit of HUMAN's suggestion. HUMAN's package page still says pre-bid filtration, and it says analysis of each bid request is built to return in 12 milliseconds or less. Read next to the memorandum, filtration on that page is the product's description of the signal. The drop, if it happens, is the platform's act."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why a campaign rate and a bid suggestion do not rank each other",
          "paragraphs": [
            "The moment differs. DoubleVerify's under-1-percent figure is computed on campaigns that ran with controls applied. MediaGuard's flag is computed before the impression, from what the bid contains. A scheme that hides in the creative, or in a stitched stream the bid fields do not describe, can be invisible to the request and visible to the post-bid tag. A request the platform drops never becomes the impression the CTV rate is about.",
            "The seat differs. DV's segments, on the MRC's account, can reach advertisers through their DSPs. HUMAN's suggestions, on the same account, stop at the DSP and the SSP. An advertiser comparing the two names in an RFP may be comparing a tool their traders can query with a tool their supply platform queries. Those are both pre-bid. They are not the same contract.",
            "The unit differs. A fraud rate on a protected cell, a count of schemes, a boolean flag, a 0.5 percent sampling valve, and an 85 percent coverage claim cannot be averaged. You can buy both. The pre-bid model can refuse requests that already match a reputation, and the post-bid label can describe what got through. Using one document to answer the other question is how a millisecond flag becomes a pretend CTV fraud rate, or a protected-campaign rate becomes a pretend block rate on the next bid.",
            "The MRC's shared sentence is the part the shortlist skips. Neither firm, in that memorandum, is the party that filters the request. A comparison of whose filter is stricter is a comparison of parties the standard says are not holding the filter. The stricter question is what signal arrived, who was allowed to see it, and whether the impression that served still carried a verification node."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Put the hop in the column header. Pre-bid suggestion, platform decision, post-serve block the client configured, protected campaign rate, unprotected test, scheme count. DoubleVerify versus HUMAN is legible once those are separate. It is a ranking if you leave them in one cell.",
            "If the risk you care about is bidding on requests that already look invalid, read the integration: who receives the flag, and who is allowed to drop the request. If the risk you care about is the fraud rate on CTV you already bought, read the population: controls on, controls off, or a single direct deal. A campaign can need both documents.",
            "The VAST tag is downstream of the bid. A request the platform allowed can still carry a wrapper that drops verification, and a request it blocked never produces a tag to lint. vastlint is independent of DoubleVerify and of HUMAN. It checks the tag that remains, for VAST 2.0–4.4 structure. It does not predict IVT on the bid, and it does not reproduce a campaign fraud rate."
          ]
        },
        {
          "type": "list",
          "heading": "Hops the shortlist collapses",
          "items": [
            "DoubleVerify, controls on, May 7, 2026: CTV fraud under 1 percent of impressions.",
            "DoubleVerify, controls off, same release: CTV fraud near 9 percent.",
            "DoubleVerify, same release: 140 percent more schemes and variants, which is not an impression share.",
            "HUMAN MediaGuard: an IVT prediction on one OpenRTB request, before the impression exists.",
            "HUMAN, training valve: 0.5 percent of flagged sophisticated traffic and 0.05 percent of general invalid traffic let through for a rescan.",
            "MRC, April 11, 2025: HUMAN suggests to DSPs and SSPs. DV also supplies segments toward advertisers. Neither firm drops the request itself."
          ]
        },
        {
          "type": "quote",
          "quote": "A suggestion on the next bid and a fraud rate on campaigns that already ran are two moments, and the platform, not the logo, decides whether the request dies.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the tag that survives the bid",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification companions and impression events are present. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "MRC statement on pre-bid IVT requirements, April 11, 2025",
              "href": "https://mediaratingcouncil.org/sites/default/files/News/MRC%20Statement%20on%20pre%20bid%20IVT%20requirements%20and%20processes.pdf",
              "description": "How the MRC describes DoubleVerify's segments and HUMAN's suggestions, and who decides to filter.",
              "source": "Media Rating Council"
            },
            {
              "label": "Global Study: Fueled by AI, CTV Fraud Schemes Surge 140% Globally",
              "href": "https://doubleverify.com/company/newsroom/global-study-ctv-fraud-schemes-surge-140-globally",
              "description": "DoubleVerify, May 7, 2026. Protected and unprotected CTV fraud rates.",
              "source": "DoubleVerify"
            },
            {
              "label": "MediaGuard overview",
              "href": "https://docs.humansecurity.com/advertising/mediaguard-overview.mdx",
              "description": "HUMAN's description of pre-bid prediction on the OpenRTB bid, paired with FraudSensor.",
              "source": "HUMAN"
            },
            {
              "label": "Closing the loop: MediaGuard and FraudSensor",
              "href": "https://docs.humansecurity.com/advertising/closing-the-loop-mediaguard-and-fraudsensor.mdx",
              "description": "The 0.5 percent SIVT and 0.05 percent GIVT pass-through used to retrain the pre-bid model.",
              "source": "HUMAN"
            },
            {
              "label": "Package plans",
              "href": "https://human.security/platform/package-plans",
              "description": "HUMAN's own use of the word filtration, and the 12 millisecond claim on bid-request analysis.",
              "source": "HUMAN"
            },
            {
              "label": "A DoubleVerify alternative is a job inside the suite",
              "href": "/blog/doubleverify-alternative/",
              "description": "Why this pair is one row in a replacement, not the whole replacement.",
              "source": "vastlint"
            },
            {
              "label": "White Ops vs DoubleVerify lines up a 2021 rename and a later rate",
              "href": "/blog/white-ops-vs-doubleverify/",
              "description": "The same pair under the company name HUMAN stopped using in 2021.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ivt-filtration",
      "title": "IVT Filtration Is the Removal From the Count, and a Pre-Bid Block Is a Separate Decision",
      "description": "The Media Rating Council requires accredited measurers to remove general invalid traffic on the back end, impression by impression. It does not require a pre-bid block, and it warns that blocking telegraphs the method. A filtered campaign rate and an open-auction benchmark are different subtractions.",
      "seoTitle": "IVT filtration lines up a required removal and an optional block",
      "seoDescription": "MRC accreditation requires back-end IVT filtration of general invalid traffic. Pre-bid blocking is not required. Pixalate's open-auction US CTV share is 19%. A DV-protected rate is under 1%. vastlint does not filter invalid traffic. It checks whether the VAST tag still carries the verification node.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "IVT",
      "tags": [
        "IVT",
        "GIVT",
        "SIVT",
        "Programmatic"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A required back-end removal and an optional pre-bid block sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "MRC",
                "Back-end GIVT filtration required",
                "Removal from the count",
                "Every accredited measurer, impression by impression",
                "Post-serve",
                "April 11, 2025"
              ]
            },
            {
              "cells": [
                "MRC",
                "Pre-bid filtration not required",
                "Block before the bid",
                "Standards caution that blocking telegraphs the method",
                "Pre-serve",
                "April 11, 2025"
              ]
            },
            {
              "cells": [
                "MRC",
                "Back-end still required if pre-bid is used",
                "Both hops",
                "Up-front techniques must sit on required back-end filtration",
                "Programmatic",
                "April 11, 2025"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/ivt-filtration.png?v=2",
          "alt": "IVT filtration on the back end is required for MRC accreditation. A pre-bid block is optional, and the standard warns that it telegraphs the method. A 19 percent open-auction share and a sub-1 percent protected rate are different subtractions.",
          "width": 1440,
          "height": 820,
          "caption": "Filtration removes traffic from the counted metrics. A block decides whether the impression is bought.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "IVT filtration is the phrase buyers use when they want a campaign cleaned. The Media Rating Council uses it for a narrower act. In the April 11, 2025 memorandum on pre-bid requirements, the MRC says accredited digital vendors must apply back-end, post-serve filtration of general invalid traffic, impression by impression, including known spiders and bots and known data-center addresses. The same memorandum says the MRC does not require pre-bid filtration, and that the standards caution against it in several places, because a block is visible to the traffic source and the method gets weaker as that source tests against it. vastlint does not filter invalid traffic. It checks whether a VAST 2.0–4.4 tag still carries the impression events and the verification node a filtration rule would have to read.",
            "The June 2020 Invalid Traffic Detection and Filtration Standards Addendum is the taxonomy under that sentence. General invalid traffic is what lists and parameter checks can catch, and accredited measurers must apply it. Sophisticated invalid traffic is the remainder that takes more than a list, and the addendum encourages it without requiring it. Filtration, in both documents, is removal from the metrics that get reported. It is not a synonym for a trader hitting decline on a bid.",
            "That is why two famous rates refuse to rank each other. Pixalate's March 9, 2026 benchmark puts 19 percent of US CTV impressions invalid inside a predominantly open-auction set of more than 103 billion impressions. DoubleVerify's May 7, 2026 release puts fraud under 1 percent on campaigns with its controls on. One figure is a classification of a log. The other is what remained after a control. Calling both of them filtration, and then sorting the companies by the number, sorts the subtraction, not the market."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the required filtration actually removes",
          "paragraphs": [
            "The June 2020 addendum's general category is the shared floor. Known invalid data-center traffic, with a carve-out for routing artifacts of legitimate users. Bots, spiders, and crawlers, except the ones that masquerade as people and therefore sit in the sophisticated category. Non-browser user agents. Pre-fetch and pre-render where the ad was never then accessed. Invalid placements such as 0x0 and 1x1. Sessions whose device information says they cannot render an image, when the counted activity is a rendered impression. The addendum says this floor exists so discrepancies between measurers stay small. If every audited firm strips the same ranges and the same declared crawlers, the residual logs can be compared.",
            "The April 2025 memorandum says the audits test that floor in production. They test application of the IAB spiders and bots list, and of industry data-center lists such as the TAG data-center IP list, on measured and reported impressions. The memorandum says this is not a sample, and it is not dependent on a DSP or SSP passing an IP address, a user agent, or a device identifier to the vendor in order to build the pre-bid file. Back-end filtration has to be able to see the impression the vendor measured.",
            "Sophisticated filtration is the other subtraction, and it is not the floor. Hijacked devices, hidden ads, spoofed apps, falsified measurement events, and server-side ad insertion spoofing are the addendum's examples of traffic that survives a list. Two accredited firms can agree on the general removal and disagree on the sophisticated slice. A report that says IVT filtered, with no category, has collapsed a mandatory list and an optional investigation."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why a pre-bid block is not the same filtration",
          "paragraphs": [
            "The memorandum quotes the standard on up-front techniques. A bid request that is not fulfilled, or is otherwise blocked, because of IVT must be used with caution. The block is apparent to the source. The technique gets less effective unless the detection keeps changing. Application on an up-front basis is not required. Back-end detection is harder for the source to see, and it leaves invalid transactions inside the data until a later stage removes them from the reported metrics. Where a firm does filter up front, the memorandum says back-end filtration is still required, and the back-end observations have to inform the pre-bid files.",
            "The same note says who is allowed to make the block. The decision to present a bid request, or to serve an ad, rests with DSPs and SSPs, and it depends on what those platforms choose to compare against the pre-bid product. HUMAN, the memorandum says, provides suggestions through an API to DSPs and SSPs, not to advertisers, and does not directly filter, prevent serving, or enable blocking. DoubleVerify provides segments and classifications to platforms and, through DSPs, to advertisers, and does not directly filter the request either. DV can enable a post-serve block only where the client configured it. IVT filtration in an RFP often means the vendor stopped the bad impression. On the MRC's account, the vendor removed it from the count, and someone else decided whether it was bought.",
            "HUMAN's package page and DoubleVerify's product language still say filtration and avoidance. Those words describe the commercial product. They do not override the institutional sentence about who drops the request. A 12 millisecond response, which is HUMAN's claim for bid-request analysis, is a latency budget for a suggestion. It is not, by itself, a removal from a reported impression count."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with a filtered rate",
          "paragraphs": [
            "Label the subtraction before you quote the rate. Back-end GIVT removal, back-end SIVT removal, pre-bid segment the platform applied, post-serve block the client configured, open-auction classification with no control in the sentence. Pixalate's 19 percent and DoubleVerify's under 1 percent can both be careful measurements and still describe different logs. The gap is the control and the population, which is what filtration is doing when it does anything.",
            "Ask the report for the category. General invalid traffic is the required list. Sophisticated invalid traffic is the investigation the addendum does not force. A clean general rate can leave hijacked devices and hidden ads in the log, which is the traffic that moves clicks and attention. IAS's Papyrus note is that pattern on mobile: nearly 25 times the click success rate on a cluster that was not a declared crawler.",
            "On the tag, back-end filtration of a video impression needs something to read. A wrapper that drops AdVerifications, or a stitched stream that fires beacons without the device context the model expects, is a document the post-serve check cannot see. vastlint does not filter IVT. It checks whether impression events and verification nodes are structurally present in VAST 2.0–4.4, so the removal the standard requires has a tag to attach to."
          ]
        },
        {
          "type": "list",
          "heading": "Filtration sentences that do not belong in one column",
          "items": [
            "MRC, April 11, 2025: back-end GIVT filtration is required, impression by impression, for accredited measurers.",
            "MRC, same memorandum: pre-bid filtration is not required, and the standards caution that a block telegraphs the method.",
            "MRC, June 2020 addendum: sophisticated invalid traffic filtration is encouraged, and it is not the required floor.",
            "Pixalate, Q4 2025, US CTV, predominantly open auction: 19 percent of impressions classified invalid.",
            "DoubleVerify, controls on, May 7, 2026: CTV fraud under 1 percent, which is a rate after a control.",
            "MRC, on both HUMAN and DoubleVerify: the firm supplies a signal. The platform, or the client's configuration, decides the block."
          ]
        },
        {
          "type": "quote",
          "quote": "Filtration is a removal from the count the buyer is shown, and a block is a decision about whether the impression is bought at all.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag a back-end filter would have to read",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so impression events and verification nodes are present. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "MRC statement on pre-bid IVT requirements, April 11, 2025",
              "href": "https://mediaratingcouncil.org/sites/default/files/News/MRC%20Statement%20on%20pre%20bid%20IVT%20requirements%20and%20processes.pdf",
              "description": "Back-end GIVT filtration is required. Pre-bid filtration is not. The memorandum also says who decides to block.",
              "source": "Media Rating Council"
            },
            {
              "label": "Invalid Traffic Detection and Filtration Standards Addendum, June 2020 update",
              "href": "https://www.mediaratingcouncil.org/sites/default/files/Standards/IVT%20Addendum%20Update%20062520.pdf",
              "description": "GIVT and SIVT definitions, and the requirement that accredited measurers apply general filtration.",
              "source": "Media Rating Council"
            },
            {
              "label": "GIVT vs SIVT lines up a required list and an investigation",
              "href": "/blog/givt-vs-sivt/",
              "description": "The category split inside the word invalid, which filtration then applies.",
              "source": "vastlint"
            },
            {
              "label": "Pixalate vs DoubleVerify lines up 19% with a protected rate",
              "href": "/blog/pixalate-vs-doubleverify/",
              "description": "The two rates people paste together once both have been called filtration.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "integral-ad-science-alternative",
      "title": "An Integral Ad Science Alternative Depends on Whether You Needed the Cluster Study or the Avoidance List",
      "description": "Integral Ad Science alternative, the same search as IAS alternative, usually wants a replacement for a verification contract. The public IAS artifacts are a named mobile cluster, a block list built after that cluster was identified, and a brand-suitability control. DoubleVerify, HUMAN, and Pixalate publish different objects.",
      "seoTitle": "Integral Ad Science alternative lines up a named cluster and no single swap",
      "seoDescription": "An IAS alternative depends on the job. Papyrus shows nearly 25× the clicks on a named mobile cluster. That study is not DoubleVerify's protected CTV rate or Pixalate's 19% open-auction share. vastlint is not that alternative. It checks the VAST tag and does not classify invalid traffic.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Mobile fraud",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A named-scheme study, a protected-campaign rate, and an open-auction share sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "IAS",
                "Nearly 25× clicks, about 4× eCPM, 13% higher attention",
                "Cluster lift",
                "Papyrus vs other IAS traffic",
                "Mobile reading apps",
                "August 6, 2026"
              ]
            },
            {
              "cells": [
                "IAS",
                "Apps, domains, and hostnames filtered after identification",
                "Avoidance list",
                "Supply IAS has named for this scheme",
                "Mobile",
                "August 6, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "IVT suggestion before the bid",
                "Pre-bid decision input",
                "One OpenRTB request, acted on by the platform",
                "Programmatic",
                "MRC, April 11, 2025"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/integral-ad-science-alternative.png?v=2",
          "alt": "Integral Ad Science's public Papyrus note is a click, price, and attention lift on a named mobile cluster, plus a list built after identification. A protected CTV rate, an open-auction share, and a pre-bid suggestion are different jobs.",
          "width": 1440,
          "height": 820,
          "caption": "Replacing IAS means naming which of those jobs the contract was doing.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Integral Ad Science alternative is the same search as IAS alternative, and it is the search people type when they also type Pixalate vs Integral Ad Science. The company name in the query is a contract. The public documents attached to that name are more specific. On August 6, 2026, IAS Threat Lab described Papyrus, a mobile scheme in novel-reading apps: hidden webviews, taps passed through as clicks, scrolls on remote instruction. Against other traffic IAS had already separated, that cluster showed nearly 25 times the click success rate, roughly 4 times the eCPM, and about 13 percent higher attention. IAS says clients on IVT avoidance are then filtered against the associated apps, domains, and hostnames. vastlint is not an Integral Ad Science alternative. It checks whether a VAST 2.0–4.4 verification node survived the wrapper, and it does not classify invalid traffic.",
            "That is a study of a scheme, and a list built after the scheme had a name. It is not a quarterly share of US CTV, which is Pixalate's March 9, 2026 figure of 19 percent inside a predominantly open-auction set. It is not DoubleVerify's May 7, 2026 figure of fraud under 1 percent on campaigns with DV controls on. An alternative that swaps those rates in for Papyrus has changed the question from a named cluster to a different log.",
            "vastlint is not an Integral Ad Science alternative. It is independent of IAS, DoubleVerify, Pixalate, and HUMAN. It checks VAST 2.0–4.4 structure, including whether verification nodes survived the wrapper. It does not reproduce a scheme study, and it does not classify invalid traffic."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the IAS documents actually cover",
          "paragraphs": [
            "Papyrus is built for long reading sessions. The visible app is the novel. BootNova, the layer IAS names, takes remote instructions for which URLs load and how hidden webviews interact with those pages. IAS reports more than 800 domains and nearly 8,000 unique host values. The monetization estimate, close to $1 million a month at the peak, applies an eCPM from supply IAS directly observed to a broader impression footprint. The comparison group is whatever IAS left outside the Papyrus bucket. A residual defined that way is not an open-auction census, and it is not an unprotected CTV test.",
            "The avoidance sentence is a second artifact. Once the apps, domains, and hostnames are named, IAS says they are filtered for clients using IVT avoidance. A list with a date on it protects against supply that has been tied to this operation. It does not say what a pre-bid model would have done on the bids before anyone had named the scheme, and it does not publish a CTV fraud rate.",
            "Brand suitability is a third job, on IAS's own verification page: pre-bid filtering and post-bid blocking for content that falls outside brand guidelines, described there as context control rather than as a fraud rate. A buyer whose IAS contract is mostly suitability is not shopping for a replacement for Papyrus. A buyer whose contract is mostly IVT avoidance is not shopping for a contextual segment. The alternative search hides that split."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What can stand in for which job",
          "paragraphs": [
            "If the job is a post-identification list of apps and domains, another firm's list is a real candidate, and the candidate has to be dated. DoubleVerify's May 2026 release is not that list. It is a CTV scheme count, up 140 percent in the first quarter of 2026 versus the first quarter of 2025, plus impression rates split by whether DV controls were on. Using the under-1-percent rate as proof that a replacement would have caught Papyrus compares a protected CTV cell with a mobile cluster that had already been separated.",
            "If the job is a decision on the next bid, HUMAN's MediaGuard is the public artifact that says it returns an IVT prediction on the OpenRTB request before the impression exists. The MRC's April 11, 2025 memorandum says that suggestion goes to DSPs and SSPs, not to advertisers, and that HUMAN does not itself drop the request. IAS's Papyrus list is applied after identification, to supply that has a name. A flag on an unnamed request and a list of a named scheme happen at different times. Both can be worth buying. They do not substitute by default.",
            "If the job is a picture of open-auction CTV, Pixalate's benchmark is the public artifact, and the query Pixalate vs Integral Ad Science is where people paste it against IAS. Nineteen percent of US CTV impressions, 21 percent of global CTV, more than 103 billion impressions, predominantly buy-side open auction. Papyrus does not contain those denominators. A quarterly share will not tell you whether the reading-app cluster was in the set, and the cluster's click multiple will not tell you the open-auction rate.",
            "Moat is still typed as an older alternative to IAS, and it is not available. Oracle ended Moat Analytics on September 30, 2024. A discontinued attention product does not replace a 2026 scheme study, and a 2026 scheme study does not replace a viewability history a buyer remembers from Moat."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Name the IAS surface you pay for before you name the replacement. A cluster study and the list that followed it, a suitability control, a measurement seat on served impressions. Integral Ad Science alternative is a coherent search inside one of those. Across them, it is three procurements.",
            "Keep the comparison queries as comparisons, not as substitutes. IAS vs DoubleVerify lines up the Papyrus lift with a scheme count and a protected rate. IAS vs Pixalate lines up the same lift with the 19 percent open-auction share. IAS vs HUMAN lines up the study with a flag on the bid. Each of those notes is the argument. This note is the map of which argument you are in.",
            "The tag is still downstream. An avoidance list can block an app and never see the wrapper. A request that is allowed can still drop AdVerifications before the impression is measured. vastlint checks that document. It does not decide whether IAS should keep the contract."
          ]
        },
        {
          "type": "list",
          "heading": "IAS artifacts that do not swap one for one",
          "items": [
            "IAS Papyrus, August 6, 2026: nearly 25 times the clicks, about 4 times the eCPM, and 13 percent higher attention, versus other traffic IAS had separated.",
            "IAS, same note: more than 800 domains and nearly 8,000 host values, then an avoidance list of the supply it named.",
            "IAS verification page: pre-bid filtering and post-bid blocking for content outside brand guidelines, which is a suitability job.",
            "DoubleVerify, May 7, 2026: CTV fraud under 1 percent with controls on, nearly 9 percent with them off, and 140 percent more schemes, which is a count.",
            "Pixalate, Q4 2025, US CTV, predominantly open auction: 19 percent of impressions.",
            "HUMAN: an IVT suggestion on the bid. The MRC says the platform decides whether to drop the request."
          ]
        },
        {
          "type": "quote",
          "quote": "A named cluster, the list built after it, and a suitability control are three contracts, and a rival's CTV rate replaces none of them by itself.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag an avoidance list never sees",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification nodes and impression events are present. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Papyrus: Inside a Mobile Scheme Built to Fake Clicks, Scrolls, and Attention",
              "href": "https://integralads.com/insider/papyrus-inside-a-mobile-scheme-built-to-fake-clicks-scrolls-and-attention/",
              "description": "IAS Threat Lab, August 6, 2026. The cluster ratios and the avoidance list that followed identification.",
              "source": "Integral Ad Science"
            },
            {
              "label": "Ad verification",
              "href": "https://integralads.com/apac/solutions/ad-verification/",
              "description": "IAS's description of pre-bid filtering and post-bid blocking for brand suitability.",
              "source": "Integral Ad Science"
            },
            {
              "label": "IAS vs DoubleVerify lines up nearly 25× clicks and a scheme count",
              "href": "/blog/ias-vs-doubleverify/",
              "description": "The pair behind one common reading of an IAS alternative.",
              "source": "vastlint"
            },
            {
              "label": "IAS vs Pixalate lines up nearly 25× clicks and a 19% share",
              "href": "/blog/ias-vs-pixalate/",
              "description": "The pair behind Pixalate vs Integral Ad Science.",
              "source": "vastlint"
            },
            {
              "label": "A DoubleVerify alternative is a job inside the suite",
              "href": "/blog/doubleverify-alternative/",
              "description": "The mirror of this note, from the other contract.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "pixalate-alternative",
      "title": "A Pixalate Alternative Has to Say Whether You Wanted the Benchmark, the Block List, or the Post-Bid Log",
      "description": "Pixalate alternative usually wants a replacement for a CTV fraud number. Pixalate's March 2026 benchmark is 19 percent of US CTV in a predominantly open-auction set. Its product page also sells pre-bid blocking and post-bid analytics, and it says those designations are opinions. A protected-campaign rate is a different log.",
      "seoTitle": "Pixalate alternative lines up an open-auction share and no single swap",
      "seoDescription": "A Pixalate alternative depends on the job. Q4 2025 US CTV invalid traffic is 19% in open auction. That share is not a DoubleVerify protected rate under 1%, and blocking lists are labeled as opinions. vastlint is not that alternative. It checks the VAST tag and does not classify invalid traffic.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "An open-auction share, a blocking product, and a protected-campaign rate sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "21% invalid",
                "Impression share",
                "Q4 2025 global CTV",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "Blocking, analytics, and a ratings terminal",
                "Three products",
                "Designations described as opinions",
                "CTV, app, web",
                "Product page"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "IAS",
                "Nearly 25× clicks",
                "Cluster lift",
                "Papyrus vs other IAS traffic",
                "Mobile",
                "August 6, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/pixalate-alternative.png?v=2",
          "alt": "Pixalate publishes an open-auction impression share, pre-bid blocking lists it describes as opinions, and post-bid analytics. A protected campaign rate is a different object.",
          "width": 1440,
          "height": 820,
          "caption": "Replacing the benchmark, replacing the block list, and replacing the post-bid log are three procurements.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Pixalate alternative is the search that follows Pixalate vs DoubleVerify and Pixalate vs Integral Ad Science, once someone decides the benchmark should have a rival. The benchmark people are actually holding is dated. On March 9, 2026, Pixalate put Q4 2025 invalid traffic at 19 percent of US CTV impressions and 21 percent of global CTV, from more than 103 billion programmatic impressions that are predominantly buy-side open auction. A second cut, on March 26, 2026, puts global open-programmatic CTV at 21 percent again, this time on more than 7 billion transactions. Seven billion CTV transactions and 103 billion impressions across web, app, and CTV are different bases. vastlint is not a Pixalate alternative. It checks whether a VAST 2.0–4.4 tag can carry media files, trackers, and verification, and it does not classify invalid traffic.",
            "The product page names three products, not one rate: pre-bid blocking, post-bid analytics, and a Media Ratings Terminal. The metrics note says invalid-traffic and viewability designations in those products, including the pre-bid blocking lists, reflect Pixalate's opinions and are neither facts nor guarantees. A buyer who wanted the quarterly share, a buyer who wanted a block list, and a buyer who wanted a post-bid log of their own impressions are not looking for the same replacement.",
            "vastlint is not a Pixalate alternative. It does not classify invalid traffic and it does not sell a block list. It checks whether a VAST 2.0–4.4 tag is structurally able to carry media files, trackers, and verification. A stitched impression can be invalid for reasons the tag's shape will not prove, and a broken tag can be unmeasurable for reasons a fraud model will not see."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the 19 percent is, and what it is not",
          "paragraphs": [
            "The March 9 table is a set of shares for the fourth quarter of 2025. United States: desktop and mobile web 25 percent, mobile app 29 percent, CTV 19 percent. Global: web 23 percent, mobile app 36 percent, CTV 21 percent. Open auction is the source Pixalate names as predominant. A private marketplace, a programmatic guaranteed buy, and a log that already passed someone else's pre-bid filter sit outside the population that sentence describes, or they sit in it only to the extent the set actually contained them. The release does not say it measured DoubleVerify's protected cell.",
            "Inside the March 26 supply-chain note, the device rows move without leaving Pixalate. Amazon Fire TV is at 14 percent global device IVT and Samsung Smart TV is at 28 percent, both in open-programmatic CTV for that quarter. Fourteen points of spread inside one firm, from a change of device, is a warning against treating 19 percent and some other firm's 1 percent as a ranking of companies.",
            "Pixalate says it is MRC-accredited for sophisticated invalid traffic detection and filtration across desktop, mobile web, in-app, and CTV, and its pages have quoted different counts of accredited areas as renewals accumulated. The durable claim is the scope of that accreditation, including SSAI metrics, not a single headcount. Accreditation for detection and filtration is not a promise that a blocking-list designation is a fact. The metrics note says the opposite about those designations."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What people try to swap in",
          "paragraphs": [
            "DoubleVerify is the usual swap for the CTV number. The May 7, 2026 release puts fraud under 1 percent on DV-protected campaigns and nearly 9 percent where controls were off, and it counts 140 percent more schemes year over year. The under-1-percent figure is what remained after a control. Pixalate's 19 percent is a classification of a predominantly open-auction log. Hiring DoubleVerify to obtain a lower headline replaces a benchmark with a protected-campaign rate. That can be the right procurement if you wanted the control. It is the wrong procurement if you wanted a quarterly picture of the open auction, because the control is designed to move the rate.",
            "IAS is the usual swap in the Integral Ad Science query. Papyrus, August 6, 2026, is a lift on a named mobile cluster: nearly 25 times the clicks against other traffic IAS had separated. That study does not contain a US CTV impression share. An IAS alternative to Pixalate's benchmark would have to be a benchmark. The cluster note is not one.",
            "HUMAN is the usual swap for the blocking product. MediaGuard returns a prediction on one bid request. Pixalate's blocking product, on its own page, is lists at user, publisher, and network level, and the metrics note calls the designations opinions. A per-request suggestion and a list are both pre-bid inputs. The MRC says HUMAN does not itself drop the request. Pixalate's note says the list is an opinion the client can use. Neither sentence is the 19 percent.",
            "A post-bid analytics seat is the third product, and it is the one that needs the tag. Pixalate's integration overview describes post-bid IVT measurement on the client's impressions, and it points at the blocking feeds as a complement rather than as the same feed. Replacing analytics means replacing a log of what served. Replacing the benchmark means replacing a published quarter. Those files do not have the same rows."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Decide which Pixalate object the contract is. Open-auction benchmark, pre-bid blocking list, post-bid analytics, ratings terminal. A Pixalate alternative is coherent inside one of those. The 19 percent is the wrong success metric for a blocking-list renewal, and a block rate is the wrong success metric for someone who wanted the quarterly share left intact.",
            "If you buy mostly deals, the open-auction denominator is the wrong one for your own log, which is the same caution the Pixalate vs DoubleVerify note already makes. If you buy mostly open auction with a filter already on, your remaining IVT is a third number, closer to a protected rate than to the published 19 percent.",
            "Keep verification placement in the tag if the replacement is post-bid. vastlint checks that placement. It will not tell you whether to keep Pixalate's benchmark as the quarterly reference."
          ]
        },
        {
          "type": "list",
          "heading": "Pixalate objects that do not replace each other",
          "items": [
            "Pixalate, Q4 2025, US CTV, predominantly open auction, published March 9, 2026: 19 percent of impressions.",
            "Pixalate, same release, global CTV: 21 percent. A March 26 cut repeats 21 percent on a base of more than 7 billion CTV transactions.",
            "Pixalate, same quarter, open-programmatic devices: Fire TV at 14 percent global IVT, Samsung Smart TV at 28 percent.",
            "Pixalate product page: pre-bid blocking, post-bid analytics, and a Media Ratings Terminal. The metrics note calls designations in those products opinions.",
            "DoubleVerify, controls on: fraud under 1 percent. That is a protected cell, not this benchmark.",
            "IAS Papyrus: a click multiple on a named mobile cluster, not a CTV impression share."
          ]
        },
        {
          "type": "quote",
          "quote": "A quarterly open-auction share, a blocking list the publisher calls an opinion, and a log of your own impressions are three files, and only one of them is the 19 percent.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag a post-bid log would have to read",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so media files, trackers, and verification nodes are present. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Q4 2025 North America IVT and Ad Fraud Benchmarks",
              "href": "https://www.globenewswire.com/news-release/2026/03/09/3251883/0/en/Pixalate-Releases-Q4-2025-North-America-Invalid-Traffic-IVT-Ad-Fraud-Benchmarks-Connected-TV-CTV-IVT-Rate-in-United-States-at-19.html",
              "description": "March 9, 2026. US CTV at 19 percent, global CTV at 21 percent, predominantly buy-side open auction.",
              "source": "Pixalate"
            },
            {
              "label": "Ad fraud protection",
              "href": "https://www.pixalate.com/ad-fraud-protection-solution",
              "description": "Pixalate's three-product description: pre-bid blocking, post-bid analytics, and the Media Ratings Terminal.",
              "source": "Pixalate"
            },
            {
              "label": "MRC accredited metrics",
              "href": "https://www.pixalate.com/knowledgebase/mrc-accredited-metrics",
              "description": "Pixalate's note that designations in analytics, blocking lists, and the ratings terminal are opinions.",
              "source": "Pixalate"
            },
            {
              "label": "Pixalate vs DoubleVerify lines up 19% with a protected rate",
              "href": "/blog/pixalate-vs-doubleverify/",
              "description": "Why the open-auction share and the protected rate are the pair this alternative search collapses.",
              "source": "vastlint"
            },
            {
              "label": "IVT filtration lines up a required removal and an optional block",
              "href": "/blog/ivt-filtration/",
              "description": "Why a lower rate after a control is the control, not a better benchmark.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "human-security-alternative",
      "title": "A HUMAN Alternative Has to Replace a Suggestion on the Bid, Not a Campaign Fraud Rate",
      "description": "HUMAN alternative, and MediaGuard alternative, usually wants another pre-bid decision. MediaGuard predicts IVT from the OpenRTB request, FraudSensor is required beside it, and the MRC says the suggestion goes to DSPs and SSPs, who decide whether to drop the request. A protected CTV rate is a later hop.",
      "seoTitle": "HUMAN alternative lines up a pre-bid suggestion and no single swap",
      "seoDescription": "A HUMAN Security alternative replaces a pre-bid suggestion, not a campaign rate. MediaGuard flags the OpenRTB request. The MRC says DSPs and SSPs decide. DoubleVerify's protected CTV rate is under 1%. vastlint is not that alternative. It checks the VAST tag and does not classify invalid traffic.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "Programmatic",
        "CTV",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A pre-bid suggestion, a sampling valve, and a protected-campaign rate sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "HUMAN",
                "IVT suggestion before the bid",
                "Pre-bid decision input",
                "OpenRTB request, sent to DSPs and SSPs",
                "Programmatic",
                "MRC, April 11, 2025"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "0.5% SIVT and 0.05% GIVT passed through",
                "Sampling valve",
                "Flagged traffic, for a FraudSensor rescan",
                "Programmatic",
                "HUMAN docs"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "Analysis aimed at 12 milliseconds or less",
                "Latency claim",
                "Each bid request, on the package page",
                "Programmatic",
                "Package page"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/human-security-alternative.png?v=2",
          "alt": "HUMAN MediaGuard returns an IVT suggestion on the bid. The MRC says the DSP or SSP decides whether to drop the request. A protected campaign rate and an open-auction share happen later, on impressions.",
          "width": 1440,
          "height": 820,
          "caption": "Replacing HUMAN means replacing the suggestion and the seat that is allowed to act on it.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "HUMAN alternative, which is also the search for a HUMAN Security alternative and a MediaGuard alternative, wants another way to keep invalid traffic out before the bid. The public object is narrow. MediaGuard, in HUMAN's docs, predicts from the OpenRTB bid whether the opportunity is likely invalid, and it returns that prediction in time to decide whether to bid. FraudSensor, the post-bid tag, is required beside it. The information from the tag trains the pre-bid model, and HUMAN says you must include FraudSensor in the integration. vastlint is not a HUMAN alternative. It does not see the bid request. It checks the VAST 2.0–4.4 document that exists after a bid is won, and it does not classify invalid traffic.",
            "The MRC's April 11, 2025 memorandum places that prediction in a seat. Suggestions go to DSPs and SSPs, not to advertisers or agencies. HUMAN does not directly filter the request, prevent serving, or enable the block. The platform decides. A replacement that shows up only in an advertiser dashboard has not replaced the integration the memorandum describes, even if the dashboard prints a fraud rate.",
            "vastlint is not a HUMAN alternative. It does not see the bid request and it does not return an IVT flag. It checks the VAST document that exists after a bid is won, for version 2.0–4.4 structure. A request the platform dropped never becomes a tag. A request it allowed can still lose its verification node on the way to the player."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What you would actually be replacing",
          "paragraphs": [
            "The integration sits between requests received and bids made. The caller sends selected fields, or the whole BidRequest. MediaGuard returns a prediction and categories. HUMAN's best-practice note says those predictions should not be exposed back to the site or device that sent the request, because the point of the flag is lost if the traffic can test against it. That operational constraint is part of the product. A replacement that writes the decision into a pixel the device can see is a different design.",
            "The pass-through is part of the design too. MediaGuard lets 0.5 percent of traffic flagged as sophisticated invalid traffic through, and 0.05 percent of general invalid traffic, so FraudSensor can rescan and the model can be updated. Those percentages are a valve on the block, not a market IVT rate. An alternative that blocks 100 percent of what it flags has removed the training loop HUMAN documents. That may be what a buyer wants. It is not a like-for-like MediaGuard install.",
            "Scale claims do not specify the alternative. A brochure figure of 20 trillion transactions a week, and of more than 85 percent of programmatic impressions running through MediaGuard, says how widely the model is asked. It does not say how often the answer is no. Coverage is not a block rate, and it is not something another firm inherits by winning the logo."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What can stand in the same hop",
          "paragraphs": [
            "DoubleVerify is the name that shares the pre-bid shortlist. The MRC memorandum says DV supplies segments and IVT classifications to DSPs, SSPs, and also to advertisers through DSPs, by API or flat file, and that DV does not itself filter the request. Post-serve blocking exists only where the client configured it. The seat is wider than HUMAN's, on that account, because advertisers are in the distribution. The May 7, 2026 CTV rates, under 1 percent with controls on and nearly 9 percent with them off, are not the segment. They are a later measurement of campaigns. Buying DV to obtain those rates does not, by itself, put a millisecond flag on the next OpenRTB request.",
            "Pixalate's pre-bid product is lists, at user, publisher, and network level, and Pixalate says designations on those lists are opinions rather than guarantees. A list and a per-request model can both run before the bid. They fail differently. A list misses what has not been listed. A request model misses what is not in the fields it is documented to consume. Neither is Pixalate's 19 percent US CTV share, which is a quarterly classification of impressions that were available to classify.",
            "IAS's public pre-buy artifact in the Papyrus note is a list after identification: apps, domains, and hostnames filtered once the scheme has a name. That protects against a cluster someone has already described. It is not a prediction on an arbitrary bid that has never been tied to the cluster. IAS's verification page also describes suitability controls, which are a content decision, not an IVT flag.",
            "HUMAN's own package page uses the word filtration and says bid-request analysis is built to return in 12 milliseconds or less. Hold that next to the MRC sentence. The package describes the signal's speed. The memorandum says the platform is who acts. An alternative should be scored on both: how fast the suggestion is, and whether your seat is one the suggestion is even sold to."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Replace the hop you have. If traders at the advertiser query a segment, HUMAN's distribution, as the MRC describes it, was never that seat, and DoubleVerify's was. If the SSP drops requests from an API before the bid, the replacement has to be an API the SSP will call, with the same rule about not leaking the decision to the device.",
            "Keep FraudSensor's job in the plan. The pre-bid model is documented as dependent on the post-bid tag. Dropping the tag to save a pixel, and keeping only the pre-bid call, removes the loop HUMAN says the prediction is trained on. The VAST verification node is where that post-bid tag has to live if the creative is video.",
            "Do not grade the replacement by Pixalate's 19 percent or by DV's under 1 percent. Those are impression shares on named populations. MediaGuard's public number, where it has one, is a valve and a latency budget and a coverage claim. vastlint will not grade it either. It will tell you whether the tag that survived the bid still has a place for the post-bid check."
          ]
        },
        {
          "type": "list",
          "heading": "What a MediaGuard alternative has to match or deliberately drop",
          "items": [
            "A prediction on one OpenRTB request, before an impression exists.",
            "A required post-bid tag, FraudSensor, which HUMAN says trains that prediction.",
            "A sampling valve: 0.5 percent of flagged sophisticated traffic and 0.05 percent of general invalid traffic let through for a rescan.",
            "MRC, April 11, 2025: suggestions to DSPs and SSPs, not to advertisers. HUMAN does not itself drop the request.",
            "DoubleVerify's under-1-percent CTV rate is a protected campaign, not this prediction.",
            "Pixalate's 19 percent is an open-auction impression share, not this prediction."
          ]
        },
        {
          "type": "quote",
          "quote": "The thing being replaced is a suggestion in a platform seat, and a campaign rate from another firm is evidence about a later hop.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag the post-bid half would have to read",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification nodes are present for the impression that was allowed to serve. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "MediaGuard overview",
              "href": "https://docs.humansecurity.com/advertising/mediaguard-overview.mdx",
              "description": "Pre-bid prediction on the OpenRTB bid, and the requirement to include FraudSensor.",
              "source": "HUMAN"
            },
            {
              "label": "Closing the loop: MediaGuard and FraudSensor",
              "href": "https://docs.humansecurity.com/advertising/closing-the-loop-mediaguard-and-fraudsensor.mdx",
              "description": "The pass-through used to rescan flagged traffic and retrain the model.",
              "source": "HUMAN"
            },
            {
              "label": "MRC statement on pre-bid IVT requirements, April 11, 2025",
              "href": "https://mediaratingcouncil.org/sites/default/files/News/MRC%20Statement%20on%20pre%20bid%20IVT%20requirements%20and%20processes.pdf",
              "description": "Who receives HUMAN's suggestion, and who decides to filter.",
              "source": "Media Rating Council"
            },
            {
              "label": "DoubleVerify vs HUMAN lines up a protected rate and a pre-bid suggestion",
              "href": "/blog/doubleverify-vs-human/",
              "description": "The pair this alternative search usually flattens.",
              "source": "vastlint"
            },
            {
              "label": "Pre-bid vs post-bid IVT compares a decision before the bid with a label after the impression",
              "href": "/blog/pre-bid-vs-post-bid-ivt/",
              "description": "The hop split, independent of which logo holds the contract.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "moat-alternative",
      "title": "A Moat Alternative Has to Replace a Score Oracle Stopped Publishing on September 30, 2024",
      "description": "Moat alternative, and Moat replacement, still reads like a feature bake-off. Oracle ended Moat Analytics with the rest of its advertising products on September 30, 2024. DoubleVerify's 70 percent is a share of RFPs it entered, not a re-measurement of impressions. Viewability, attention, and a fraud rate are different instruments.",
      "seoTitle": "Moat alternative lines up a discontinued score and no single swap",
      "seoDescription": "A Moat alternative replaces a product Oracle ended on September 30, 2024. DoubleVerify won 70% of the former Moat RFPs it entered. That is a sales result, not a shared impression score. vastlint is not that alternative. It checks the verification node and does not score viewability.",
      "publishedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "Viewability",
        "Attention",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "An end-of-life date, an RFP win rate, and a later fraud rate sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "Moat",
                "End of service",
                "Product",
                "Oracle advertising products, including Moat Analytics",
                "Measurement",
                "September 30, 2024"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "70% of former Moat RFPs it entered",
                "Pitch win rate",
                "Advertiser RFPs in a window of about six weeks",
                "Sales",
                "AdExchanger"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "IAS",
                "Nearly 25× clicks",
                "Cluster lift",
                "Papyrus vs other IAS traffic",
                "Mobile",
                "August 6, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/moat-alternative.png?v=2",
          "alt": "Moat Analytics ended on September 30, 2024. A 70 percent RFP win rate is a share of pitches DoubleVerify entered. Viewability, attention, and a 2026 fraud rate are different instruments.",
          "width": 1440,
          "height": 820,
          "caption": "The replacement depends on which Moat score the template still names.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Moat alternative, and the twin search Moat replacement, outlived the product. Oracle stopped supporting its advertising products on September 30, 2024, and Moat Analytics was on that list. After that date there is no current Moat score to beat, match, or migrate pixel for pixel. What remains is a job the old contract was doing, and a tag that may still name the host. vastlint is not a Moat alternative. It checks whether a VAST 2.0–4.4 verification node is present, and it does not score viewability or attention.",
            "The number that filled the vacuum is a sales result. AdExchanger reported that DoubleVerify won 70 percent of the former Moat advertiser RFPs it participated in, across roughly six weeks between the announcement and the shutdown. The denominator is pitches DoubleVerify entered. It is not every former Moat advertiser, it is not 70 percent of Moat spend, and it is not a count of impressions rescored under two methodologies. IAS was in the same market for the same accounts. The 70 percent does not say IAS won the rest.",
            "vastlint is not a Moat alternative. It has no measurement history to continue, and it does not score viewability or attention. It can tell you whether a VAST 2.0–4.4 verification node is present. It cannot tell you whether the host inside that node still answers, which is the question a leftover Moat URL is asking."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Which job the template still means",
          "paragraphs": [
            "Viewability, in the MRC sense the industry argued about for years, is a pixel-and-time threshold: for video, 50 percent of pixels in view for two continuous seconds. That definition did not leave the market when Moat did. A replacement for a viewability seat is another measurer applying that threshold, or a measurer you have audited against it. The RFP win records who signed. It does not record that the new vendor's viewable decision would have matched Moat's on a held-out impression, because that study is not what the 70 percent is.",
            "Attention is the metric buyers attached to the Moat name, and it is a model on top of interaction, duration, and sometimes sound. AdExchanger reported DoubleVerify's CEO saying Moat did not do social and did not have a robust dynamic pre-bid suitability product, and that the nearer goal was to be more than a like-for-like replacement. That is a scope claim from the firm that won the RFPs, made after the shutdown. DoubleVerify has its own attention products, including the pre-bid segments it announced in May 2023 from Authentic Attention. A buyer who points a Moat attention history at a DV attention score has changed instruments. The contract moved. The unit did not automatically follow.",
            "A fraud rate is a third instrument, and it is the one 2026 press is full of. DoubleVerify's May 7, 2026 CTV release, fraud under 1 percent with controls on, is a real measurement of a named population. It is not a Moat viewability series and it is not a Moat attention series. Putting it in the Moat replacement column because the same company won the RFPs repeats the unit error the DoubleVerify vs Moat note is about. IAS's Papyrus figures, nearly 25 times the clicks on a named mobile cluster, are a 2026 scheme study. They are not a reconstructed Moat score either."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the shutdown did to the tag",
          "paragraphs": [
            "Existing orders ran to the end-of-life date. New agreements were not the path Oracle described. A Verification or Extension that still names Moat, or an OMID vendor string that pointed at that stack, calls a host that no longer operates the product. The player may request a URL that does not answer. The impression can still count. The attention number the trafficking sheet promised does not come back.",
            "Leaving the node in place makes the tag look measured. A structural check sees a verification element and can call the document well formed. It will not invent a living vendor behind a dead host. Removing the node, or pointing it at the firm that actually holds the 2026 contract, is a trafficking change. Which firm that should be depends on the job in the previous section, not on who won the most RFPs in a six-week window.",
            "The accounts that moved are a list of advertisers with a deadline. AdExchanger named P&G, BlackRock, Dish Network, Charter, Inspire Brands, Kellogg's, and Google among the wins DoubleVerify described. A list of logos is not a panel of impressions. One of those advertisers signing a new verification contract does not tell you whether a 2023 Moat decision and a 2026 decision would have agreed on one CTV impression."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Retire Moat as a column in a 2026 matrix. If the template says Moat alternative, replace the word Moat with the job: viewability under the pixel threshold, an attention model, pre-bid suitability, or a fraud label. Then pick the firm that publishes that job this quarter. The 70 percent is history of who could contract before September 30, 2024.",
            "Audit tags for the dead host separately from the commercial decision. A Moat URL in a VAST verification block is a defect whether or not you have chosen the replacement, because it reports a measurement that is not happening.",
            "vastlint will flag structure, not the business status of a vendor. Pair the structural pass with an end-of-life list your trafficking team actually maintains. The check tells you the node is there. The date tells you the host is not."
          ]
        },
        {
          "type": "list",
          "heading": "Moat replacement sentences that stay in separate columns",
          "items": [
            "End of service: Oracle advertising products, including Moat Analytics, stopped on September 30, 2024.",
            "RFP win rate: 70 percent of former Moat advertiser RFPs DoubleVerify entered, not 70 percent of spend and not a rescored log.",
            "Viewability: a pixel-and-time threshold another measurer can still apply. The win rate does not prove the decisions match.",
            "Attention: a model. DoubleVerify's own attention product is a different instrument from the one Moat published.",
            "A 2026 CTV fraud rate, under 1 percent with controls on, is not a reconstructed Moat score.",
            "A verification node that still names Moat is a host, not a measurement."
          ]
        },
        {
          "type": "quote",
          "quote": "The product ended, so the alternative is whichever living instrument matches the job the template still names, and an RFP win rate is not that instrument.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check whether a dead verification host is still in the tag",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so AdVerifications are present and consistent. The check will not know if the host is out of business. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Oracle to shut down advertising products and services by September 2024",
              "href": "https://ppc.land/oracle-announces-end-of-life-for-advertising-products-and-services/",
              "description": "Client-notice reporting that Moat Analytics was on the September 30, 2024 end-of-life list.",
              "source": "PPC Land"
            },
            {
              "label": "DoubleVerify Won 70% Of The Former Moat Advertisers It Courted",
              "href": "https://www.adexchanger.com/marketers/doubleverify-won-70-of-the-former-moat-advertisers-it-courted/",
              "description": "AdExchanger on the RFP win rate, the six-week window, and what DoubleVerify said Moat did not cover.",
              "source": "AdExchanger"
            },
            {
              "label": "DoubleVerify vs Moat compares a live suite with a product Oracle shut down",
              "href": "/blog/doubleverify-vs-moat/",
              "description": "The pair note. This page is the replacement question that pair leaves open.",
              "source": "vastlint"
            },
            {
              "label": "Viewability vs attention compares a pixel threshold with a score built on interaction",
              "href": "/blog/viewability-vs-attention/",
              "description": "The metric split buyers still attach to the Moat name.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ias-vs-doubleverify",
      "title": "IAS vs DoubleVerify Compares a Named Mobile Cluster With a Count of CTV Schemes",
      "description": "IAS Threat Lab's Papyrus note is a named cluster against other traffic it already separated: nearly 25 times the click success rate, roughly 4 times the eCPM, and about 13 percent higher attention. DoubleVerify's May 2026 CTV report counts schemes and variants, up 140 percent in Q1 2026 versus Q1 2025, and splits fraud rates by whether its controls were on: under 1 percent protected, nearly 9 percent unprotected.",
      "seoTitle": "IAS vs DoubleVerify lines up nearly 25× clicks and a scheme count",
      "seoDescription": "IAS Papyrus shows nearly 25× the clicks on a named mobile cluster. DoubleVerify counts 140% more CTV schemes, and fraud under 1% with its controls on. vastlint checks the VAST tag those figures never see. It does not rank the firms or classify invalid traffic.",
      "publishedAt": "2026-09-25",
      "updatedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Mobile fraud",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A cluster lift, a scheme count, and a protected-campaign rate sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "IAS",
                "Nearly 25× clicks, about 4× eCPM, 13% higher attention",
                "Cluster lift",
                "Papyrus vs other IAS traffic",
                "Mobile reading apps",
                "August 6, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "140% more schemes than Q1 2025",
                "Scheme count",
                "CTV schemes and variants",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud nearly 9%",
                "Impression share",
                "Controls off",
                "CTV",
                "May 7, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/ias-vs-doubleverify.png?v=2",
          "alt": "Three cards. IAS Papyrus is a click, eCPM, and attention lift on a named cluster. DoubleVerify's 140 percent is a count of CTV schemes. The under 1 percent and nearly 9 percent rates are protected and unprotected campaign tests.",
          "width": 1440,
          "height": 820,
          "caption": "The shortlist puts a cluster lift, a scheme count, and a protected-campaign rate in one row. They do not share a scale.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "The search IAS vs DoubleVerify is a verification shortlist. The headlines that travel with the two names are not one measurement. On August 6, 2026, IAS Threat Lab described Papyrus, a mobile scheme in novel-reading apps: hidden webviews load other sites, taps on the reading interface are passed through as clicks, and pages scroll on remote instruction. In IAS analysis that cluster showed nearly 25 times the click success rate, roughly 4 times the eCPM, and about 13 percent higher attention scores than non-Papyrus traffic. On May 7, 2026, DoubleVerify released its CTV report, Must-CTV, and said it detected 140 percent more CTV fraud schemes and variants in the first quarter of 2026 than in the first quarter of 2025. The same release said fraud rates on DV-protected CTV campaigns were less than 1 percent, and nearly 9 percent where protection controls were not applied. vastlint does not rank IAS against DoubleVerify. It checks whether a VAST 2.0–4.4 tag still carries the verification node either firm would have to read, and it does not classify invalid traffic.",
            "Three different objects are sitting in that paragraph. Papyrus is a lift on clicks, price, and attention for a cluster IAS had already separated from the rest of its observation. The 140 percent is a count of schemes and variants, year over year, not a share of impressions. The 1 percent and the 9 percent are impression fraud rates on two populations DoubleVerify defined by whether its own controls were on. A shortlist that puts 25 times next to 140 percent next to 9 percent has joined a ratio, a scheme census, and a rate.",
            "Both companies sell media verification, and buyers compare them because both will say whether an impression should count. The public research does not settle the contract. Strip the company names off and the claim remains: a post-identification cluster study, a year-over-year count of schemes, and a protected-versus-unprotected impression rate do not order one another."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the IAS figures measure",
          "paragraphs": [
            "Papyrus is built for long reading sessions. The visible app is the novel. BootNova, the layer IAS names, takes remote instructions for which URLs load and how hidden webviews interact with those pages. IAS reports more than 800 domains and nearly 8,000 unique host values, skewed toward gaming, blog, news-style, and generative-AI destinations. The performance figures are Papyrus-associated supply compared with non-Papyrus traffic in IAS observation. IAS estimates close to $1 million a month in monetization impact at the peak, by applying an eCPM from supply it directly observed to a broader impression footprint from supply-path data.",
            "IAS also says clients on IVT avoidance are already protected, because the associated apps, domains, and hostnames are filtered after identification. That is a block list with a date on it. It is a statement about supply IAS has named. A share of all mobile impressions in a quarter, a CTV rate, and another firm's label on the same apps are outside what this note contains.",
            "The surface is mobile, and the unit is engagement and price for one named operation. The comparison group is whatever IAS left outside the Papyrus bucket. That residual is the traffic that was not placed in this cluster. It is not DoubleVerify's unprotected CTV test, and it is not an open-auction census of connected TV."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the DoubleVerify figures measure",
          "paragraphs": [
            "DoubleVerify's May 7, 2026 release describes the base in one sentence: proprietary measurement spanning billions of impressions from DV-protected campaigns, plus controlled tests where protection controls were not applied. Surveys of more than 2,000 marketers and 22,000 consumers in more than 20 markets sit in the same report and are a separate instrument. A survey of marketers is not an impression log. The fraud rates and the scheme counts come from the measurement data.",
            "The 140 percent is schemes and variants, the first quarter of 2026 against the first quarter of 2025. DoubleVerify also says it uncovered more than 50 distinct CTV bot attacks and variants in 2025, and identified 10 times more fraudulent CTV apps in 2025 than in 2024. A scheme count can rise because detection got finer, because operators split one operation into more variants, or because more operations exist. The release does not decompose those causes. What the sentence reports is a count of schemes, not a claim that 140 percent more CTV impressions were invalid.",
            "The impression rates are the other cut. On DV-protected CTV campaigns, fraud rates were less than 1 percent. On unprotected campaigns, nearly 9 percent. DoubleVerify estimates that fraud in unprotected campaigns can cost about $1.8 million per billion CTV impressions served, and calls that a conservative estimate. Those two rates are a with-and-without on DV's own controls. They are not the share of all CTV impressions in the open auction, and they are not the share inside private marketplace deals as a class.",
            "The release also breaks the character of what it flagged. In North America, bot fraud made up 82 percent of violations, while data-center traffic dominated in APAC at 98 percent, EMEA at 66 percent, and LATAM at 91 percent. Direct buys were not treated as a clean room: in one consumer healthcare campaign bought direct, 34 percent of impressions went to bots, and in a major CPG campaign, also direct, 25 percent did. Twenty-one percent of advertisers measure CTV performance with IVT or fraud detection as a KPI. Each of those sentences has its own denominator: violations by region, a single campaign, a survey of advertisers."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the two headlines have no shared scale",
          "paragraphs": [
            "The units do not match. Nearly 25 times the click success rate is a ratio of two engagement rates inside one firm's observation. One hundred forty percent more schemes is a count of operations. Less than 1 percent and nearly 9 percent are shares of impressions. There is no arithmetic that turns a click multiple on a mobile cluster into a CTV scheme count, or a scheme count into the fraud rate on a protected campaign.",
            "The populations do not match. Papyrus ratios exist because IAS identified the scheme and split the log. DoubleVerify's under-1-percent figure exists because the campaigns in that cell had DV controls applied. The nearly-9-percent figure exists because a controlled test left those controls off. Quoting the 9 percent as the CTV fraud rate drops the condition in the sentence. Quoting the 1 percent as how much fraud is left in the market drops it the other way.",
            "The surfaces do not match. Papyrus is mobile reading apps and hidden webviews. The DoubleVerify figures buyers paste into this shortlist are CTV. DoubleVerify's own regional split says the CTV violations are not one thing either: bots in North America, data-center traffic in APAC. A mobile webview cluster and a CTV scheme count are different devices on top of different units."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Write the unit next to the number before it enters a spreadsheet. Cluster lift, scheme count, protected impression rate, unprotected impression rate, single-campaign bot share. Those are separate columns. IAS versus DoubleVerify becomes a readable comparison after that split, and even then it is a comparison of published studies, not a test of whose filter would have saved one campaign.",
            "If the question is a live line item, name the log. A campaign with a verification control on it is the protected population. A test that turns the control off is the other one. A named scheme found after the fact is a third. Movement between those states is a different incident from a new fraud variant.",
            "Neither report checks the VAST document. A wrapper can drop AdVerifications and still fire an impression, and then both firms are labeling a creative the player may not have measured. vastlint is independent of IAS and of DoubleVerify. It checks structural consistency for VAST 2.0–4.4, including tracker URLs and verification placement. It does not detect invalid traffic, and it does not choose between these firms."
          ]
        },
        {
          "type": "list",
          "heading": "Questions worth writing down before the comparison",
          "items": [
            "Is the figure a click or eCPM ratio, a count of schemes, or a share of impressions?",
            "Was the log a named cluster, a protected campaign, or a test with controls off?",
            "Is the surface mobile webview or CTV, and which region's violation mix is being quoted?",
            "Is a single direct-deal campaign being treated as the market rate?",
            "Are AdVerifications still in the tag the player received?"
          ]
        },
        {
          "type": "quote",
          "quote": "A cluster lift, a scheme count, and a protected-campaign rate can all be accurate, and they still cannot rank the firms that published them.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the tag the measurement is supposed to see",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification companions and impression events are present and consistent. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Papyrus: Inside a Mobile Scheme Built to Fake Clicks, Scrolls, and Attention",
              "href": "https://integralads.com/insider/papyrus-inside-a-mobile-scheme-built-to-fake-clicks-scrolls-and-attention/",
              "description": "IAS Threat Lab, August 6, 2026. Primary for the click, eCPM, attention, domain, host, and monthly impact figures.",
              "source": "Integral Ad Science"
            },
            {
              "label": "Global Study: Fueled by AI, CTV Fraud Schemes Surge 140% Globally",
              "href": "https://doubleverify.com/company/newsroom/global-study-ctv-fraud-schemes-surge-140-globally",
              "description": "DoubleVerify, May 7, 2026. Scheme counts, protected and unprotected CTV fraud rates, regional violation mix, and the direct-deal examples.",
              "source": "DoubleVerify"
            },
            {
              "label": "IAS vs Pixalate puts a named mobile cluster next to a quarterly open-auction share",
              "href": "/blog/ias-vs-pixalate/",
              "description": "Why Papyrus and Pixalate's Q4 2025 IVT shares are a different comparison from this one.",
              "source": "vastlint"
            },
            {
              "label": "An Integral Ad Science alternative depends on the job",
              "href": "/blog/integral-ad-science-alternative/",
              "description": "The replacement search behind this pair, including Pixalate vs Integral Ad Science.",
              "source": "vastlint"
            },
            {
              "label": "Is DoubleVerify better than IAS lines up a job and no winner",
              "href": "/blog/is-doubleverify-better-than-ias/",
              "description": "The question form of this pair, and the same shape against Pixalate and HUMAN.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "pixalate-vs-doubleverify",
      "title": "Pixalate vs DoubleVerify Lines Up an Open-Auction Share Against a Protected-Campaign Rate",
      "description": "Pixalate's Q4 2025 benchmark puts US CTV invalid traffic at 19 percent inside a predominantly buy-side open-auction set of more than 103 billion impressions. DoubleVerify's May 2026 CTV report puts fraud under 1 percent on campaigns with its controls on, and near 9 percent where those controls were off. The two rates describe different logs.",
      "seoTitle": "Pixalate vs DoubleVerify lines up 19% with a protected rate",
      "seoDescription": "Pixalate puts Q4 2025 US CTV invalid traffic at 19% in open auction. DoubleVerify reports fraud under 1% with its controls on, and nearly 9% with them off. vastlint checks the VAST tag. It does not decide which rate is the market or classify invalid traffic.",
      "publishedAt": "2026-09-25",
      "updatedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "An open-auction impression share and a protected-campaign rate sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "21% invalid",
                "Impression share",
                "Q4 2025 global CTV",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud under 1%",
                "Impression share",
                "Controls on",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "Fraud nearly 9%",
                "Impression share",
                "Controls off",
                "CTV",
                "May 7, 2026"
              ]
            },
            {
              "cells": [
                "DoubleVerify",
                "140% more schemes than Q1 2025",
                "Scheme count",
                "CTV schemes and variants",
                "CTV",
                "May 7, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/pixalate-vs-doubleverify.png?v=2",
          "alt": "Pixalate's 19 percent US CTV figure is an open-auction impression share. DoubleVerify's under 1 percent and nearly 9 percent are protected and unprotected tests. Scheme counts and single-deal bot shares sit in a third card.",
          "width": 1440,
          "height": 820,
          "caption": "A lower rate on a protected campaign is the control doing its job, not a ranking against an open-auction benchmark.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Pixalate vs DoubleVerify is the CTV shortlist. The numbers people paste side by side are 19 percent and something under 10 percent, and the paste treats them as rival readings of the same market. They are not. On March 9, 2026, Pixalate published Q4 2025 invalid-traffic benchmarks: 19 percent of US CTV impressions in its set, 21 percent of global CTV, from more than 103 billion programmatic impressions that are predominantly buy-side open auction. On May 7, 2026, DoubleVerify said fraud rates on DV-protected CTV campaigns were less than 1 percent, and nearly 9 percent in controlled tests where protection controls were not applied. vastlint does not decide which of those rates is the market. It checks whether a VAST 2.0–4.4 tag still carries the verification node a post-bid label would have to read, and it does not classify invalid traffic.",
            "The gap between 19 and 9, or between 19 and 1, is the temptation. A lower rate looks like a cleaner market or a stricter filter. The sentences do not say that. One rate is the share of impressions a firm classified invalid inside a predominantly open-auction log. The other two rates are a with-and-without on a second firm's own controls. Ordering them ranks the footnotes, not the vendors.",
            "Both firms sell CTV fraud detection, and a buyer can hire either one. The public tables do not say which hire would have blocked more of a given campaign. Remove the names and a quarterly open-auction share still does not compete with a protected-campaign rate."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the Pixalate figures measure",
          "paragraphs": [
            "The March 9, 2026 table is a set of invalid-traffic shares for the fourth quarter of 2025. United States: desktop and mobile web 25 percent, mobile app 29 percent, CTV 19 percent. Canada: web 20 percent, mobile app 27 percent, CTV 16 percent. Global: web 23 percent, mobile app 36 percent, CTV 21 percent. Pixalate says the data science team analyzed more than 103 billion global programmatic impressions, and that the datasets consist predominantly of buy-side open-auction traffic.",
            "The 19 percent is the share of US CTV impressions in that set which Pixalate classified as invalid. Open auction is the source it names as predominant. A campaign bought as a private marketplace or as programmatic guaranteed sits outside the population that sentence describes. A log that already passed a pre-bid filter is a further cut. The benchmark is the classification rate on the traffic Pixalate analyzed.",
            "A second Pixalate cut, published March 26, 2026, says 21 percent of global CTV open programmatic ad traffic was invalid, from more than 7 billion open programmatic transactions across 185,000 CTV devices, next to $6.9 billion in global open programmatic CTV ad spend. Seven billion CTV transactions and 103 billion impressions across web, app, and CTV are different bases, even where both writings print 21 percent for global CTV. Inside that supply-chain note, Amazon Fire TV is at 14 percent global device IVT and Samsung Smart TV is at 28 percent."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the DoubleVerify figures measure",
          "paragraphs": [
            "DoubleVerify's May 7 release is explicit about two CTV populations. Protected campaigns, with verification controls applied, showed fraud rates under 1 percent. Unprotected campaigns, controlled tests where those controls were not applied, showed nearly 9 percent. The measurement spans billions of impressions. The unprotected cell is not \"all CTV.\" It is the cell where DV says the controls were off.",
            "Other lines in the same release are easy to drop into the same cell and should not be. One hundred forty percent more CTV fraud schemes and variants, first quarter of 2026 versus first quarter of 2025, is a count of operations. More than 50 bot attacks and variants in 2025, and 10 times more fraudulent CTV apps than in 2024, are counts as well. About $1.8 million per billion impressions is an estimated cost on unprotected campaigns, not a rate.",
            "Direct deals have their own rows. DoubleVerify says bot activity showed up in multiple direct CTV buys, including 34 percent of impressions in one consumer healthcare campaign and 25 percent in a major CPG campaign. Those are single campaigns, not the 9 percent and not the 19 percent. North America violations were 82 percent bot fraud. APAC violations were 98 percent data-center traffic. A national open-auction average and a single direct-deal bot share are different objects again."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why 19 percent and 9 percent are not a ranking",
          "paragraphs": [
            "The filters differ before the rate is computed. Pixalate's 19 percent is a classification of impressions that were in a predominantly open-auction set. DoubleVerify's under-1-percent figure is what remained after DV controls. Comparing a pre-filter market share with a post-filter campaign rate will make the post-filter number look smaller every time the control does anything. That gap is the control, not a verdict on which company sees more fraud.",
            "The unprotected 9 percent is the closer neighbor, and it is still a different sample. It is a controlled test DoubleVerify ran with protection off, on the inventory that test included. Pixalate's 19 percent is a quarter of predominantly buy-side open auction across a stated impression base of more than 103 billion. Neither sentence says it measured the other's log. A test designed to show the effect of turning a control off is built to differ from a census-style benchmark of open auction.",
            "Scheme growth can move the opposite direction from either rate. DoubleVerify can report 140 percent more schemes while protected campaigns stay under 1 percent, because a scheme count and an impression share are different units. Pixalate can report 19 percent of US CTV impressions invalid without having published a count of named schemes. A quarter in which schemes proliferate and the open-auction impression share stays flat is compatible with both releases. So is the reverse.",
            "Device rows inside one Pixalate note make the same point without leaving the firm. Fire TV at 14 percent global IVT and Samsung Smart TV at 28 percent are both open-programmatic CTV in Q4 2025, and they differ by fourteen points because the device population changed. A shortlist that cannot tolerate that spread inside one report should not treat 19 percent and 9 percent, from two firms and two filters, as a ranking of the companies."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Label the cell before you quote it. Open-auction impression share, protected campaign, unprotected test, single direct deal, scheme count, device-level rate. Pixalate versus DoubleVerify is six comparisons if you keep the labels, and one false comparison if you do not.",
            "If you buy mostly deals, the open-auction 19 percent is the wrong denominator for your own log, and the direct-deal examples in the DoubleVerify release are a warning that \"direct\" is not a fraud rate of zero. If you buy mostly open auction with a pre-bid filter on, your remaining IVT is a third number, closer to a protected rate than to either headline.",
            "The tag is still a separate check. Server-side stitching can fire beacons without the device context a fraud model expects, and a wrapper can omit the verification node both firms want to see. vastlint is independent of Pixalate and of DoubleVerify. It checks VAST 2.0–4.4 structure, including MediaFiles, trackers, and verification placement. It does not classify invalid traffic."
          ]
        },
        {
          "type": "list",
          "heading": "Rates that do not belong in one column",
          "items": [
            "Pixalate, Q4 2025, US CTV, predominantly open auction: 19 percent of impressions.",
            "Pixalate, Q4 2025, global CTV, same benchmark release: 21 percent of impressions.",
            "DoubleVerify, DV-protected CTV campaigns: fraud under 1 percent.",
            "DoubleVerify, controls not applied: fraud near 9 percent.",
            "DoubleVerify, two named direct deals: 34 percent and 25 percent of impressions to bots.",
            "DoubleVerify, Q1 2026 versus Q1 2025: 140 percent more schemes and variants, which is not an impression share."
          ]
        },
        {
          "type": "quote",
          "quote": "A lower fraud rate on a protected campaign and a higher rate on an open-auction benchmark are different logs, and the gap between them is not a winner.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the tag before you trust either rate",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification companions, media files, and impression events are present. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Q4 2025 North America IVT and Ad Fraud Benchmarks",
              "href": "https://www.globenewswire.com/news-release/2026/03/09/3251883/0/en/Pixalate-Releases-Q4-2025-North-America-Invalid-Traffic-IVT-Ad-Fraud-Benchmarks-Connected-TV-CTV-IVT-Rate-in-United-States-at-19.html",
              "description": "March 9, 2026. US CTV at 19 percent, global CTV at 21 percent, more than 103 billion impressions, predominantly buy-side open auction.",
              "source": "Pixalate"
            },
            {
              "label": "Q4 2025 CTV Ad Supply Chain Trends Report",
              "href": "https://www.pixalate.com/blog/q4-2025-ctv-ad-supply-chain-trends-report",
              "description": "March 26, 2026. Global open programmatic CTV IVT at 21 percent on more than 7 billion transactions.",
              "source": "Pixalate"
            },
            {
              "label": "Global Study: Fueled by AI, CTV Fraud Schemes Surge 140% Globally",
              "href": "https://doubleverify.com/company/newsroom/global-study-ctv-fraud-schemes-surge-140-globally",
              "description": "DoubleVerify, May 7, 2026. Protected and unprotected CTV fraud rates, scheme counts, and direct-deal examples.",
              "source": "DoubleVerify"
            },
            {
              "label": "IAS vs Pixalate puts a named mobile cluster next to a quarterly open-auction share",
              "href": "/blog/ias-vs-pixalate/",
              "description": "The open-auction benchmark beside a named-scheme study, which is a third comparison.",
              "source": "vastlint"
            },
            {
              "label": "A DoubleVerify alternative is a job inside the suite",
              "href": "/blog/doubleverify-alternative/",
              "description": "What to open when the pair becomes a replacement search.",
              "source": "vastlint"
            },
            {
              "label": "IVT filtration lines up a required removal and an optional block",
              "href": "/blog/ivt-filtration/",
              "description": "Why a filtered campaign rate and an open-auction share are different subtractions.",
              "source": "vastlint"
            },
            {
              "label": "A normal CTV IVT rate lines up several logs and no single benchmark",
              "href": "/blog/what-is-a-normal-ctv-ivt-rate/",
              "description": "What people do with 19 percent and under 1 percent once they treat either as the normal.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "doubleverify-vs-moat",
      "title": "DoubleVerify vs Moat Compares a Live Verification Suite With a Product Oracle Shut Down",
      "description": "Oracle ended Moat Analytics with the rest of its advertising products on September 30, 2024. DoubleVerify later said it won 70 percent of the former Moat advertiser RFPs it entered. The comparison query still treats a discontinued measurement product and a current verification suite as alternatives on the same shelf. vastlint is not a Moat replacement. It checks whether the verification node is present and does not score viewability.",
      "publishedAt": "2026-09-25",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "Viewability",
        "Attention",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "DoubleVerify vs Moat is a comparison query that outlived the product on one side of it. Oracle told clients it would stop supporting its advertising products on September 30, 2024, and the list of what ended includes Moat Analytics. AdExchanger reported that DoubleVerify won 70 percent of the former Moat advertiser RFPs it participated in, in a window of roughly six weeks between Oracle's announcement and the shutdown. The query still reads like a feature bake-off between two current vendors. vastlint is not a Moat replacement and it does not score viewability. It checks whether a VAST 2.0–4.4 verification node is present, and it cannot tell you whether the host in that node still answers.",
            "The shelf is not current. One name is a measurement and verification product Oracle discontinued with the rest of that advertising business. The other is a company that spent the shutdown pitching the accounts. A win rate on RFPs DoubleVerify chose to enter is a sales result. It is not a measurement of whose viewability or fraud model was more accurate on the same impressions.",
            "Strip the names off and the claim remains. A discontinued product and a live suite do not share a scoreboard, and a share of RFPs entered is not a share of impressions re-measured."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/doubleverify-vs-moat.png?v=2",
          "alt": "Two cards. Moat Analytics ended with Oracle's advertising products on 30 September 2024. DoubleVerify's 70 percent is the share of former Moat advertiser RFPs it entered, not a re-measurement of impressions.",
          "width": 1440,
          "height": 820,
          "caption": "The comparison query still treats a discontinued measurement product and a live suite as alternatives on the same shelf.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What Moat was, and what ended",
          "paragraphs": [
            "Moat's public job was measurement: viewability, attention, and verification sitting on the ad. Oracle had bought it as part of a larger advertising business that also included audience data and contextual tools. When Oracle exited, the client notice covered that business, not a single dashboard. Trade reporting of the earnings call put the advertising business at about $300 million of revenue in fiscal 2024, down from a much larger ad operation in prior years. That figure is the business, not a Moat-only line.",
            "September 30, 2024 is the date access ended. Existing orders ran to that end-of-life date. New agreements were not the path Oracle described. After that date, a tag still labeled Moat in an old trafficking sheet is a name, not a service that is scoring the impression. Teams that kept the pixel in a VAST verification block past the shutdown were calling a host that no longer operated the product.",
            "Moat's reputation in the comparison query is attention and viewability, the metrics buyers had learned to put next to DoubleVerify and IAS. AdExchanger reported DoubleVerify's CEO saying Moat did not do social and did not have a robust dynamic pre-bid suitability product, and that the nearer-term goal was to be more than a like-for-like replacement. That is a product-scope claim from the firm that won the RFPs, made after the shutdown. It is not a side-by-side audit of historical Moat and DV logs."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the 70 percent actually counts",
          "paragraphs": [
            "The 70 percent is a share of advertiser RFPs DoubleVerify participated in, as DoubleVerify described it to AdExchanger. The named wins in that report include P&G, BlackRock, Dish Network, Charter, Inspire Brands, Kellogg's, and Google. A denominator of \"RFPs we entered\" is smaller than \"every former Moat advertiser,\" and it excludes pitches DoubleVerify did not join. IAS was in the same market for the same accounts. The 70 percent does not say IAS won the rest, and it does not say 70 percent of Moat spend moved.",
            "The clock was short. AdExchanger described roughly six weeks between Oracle's announcement and the date the products were pulled. An RFP in that window is a migration under a deadline. Win rate under a deadline measures who could contract in time. It does not measure whose post-bid viewability methodology matched Moat's on a held-out set of impressions, because that study is not what the figure is.",
            "Attention, which buyers associated with Moat, did not transfer as a unit. DoubleVerify has its own attention and performance products, and it has said expanding past verification is a priority. A buyer who replaces a Moat attention score with a DV attention score has changed instruments. The RFP win records that a contract moved. It does not record that the new score is the old score under a new logo."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the query still misleads",
          "paragraphs": [
            "Search still pairs the names because years of RFP templates did. The templates assumed two living verification vendors with overlapping tags. After September 30, 2024, one of those tags is a legacy string. Comparing feature lists from a 2023 Moat sheet with a 2026 DoubleVerify sheet compares a product that cannot be bought with one that can.",
            "The measurement question that survives is which events the replacement actually emits. Viewability under the MRC definition is a pixel-and-time threshold. An attention score is a model on top of interaction, duration, and sometimes sound. Moat was known for the second. DoubleVerify's CTV research in 2026, including fraud rates under 1 percent on protected campaigns, is a different publication from an attention methodology. Putting a 2026 fraud rate next to a memory of Moat attention repeats the unit error.",
            "Legacy verification nodes in VAST are where this shows up in the tag. A Verification or Extension that still names Moat, or a vendor identifier that was only ever a Moat host, will not start scoring again because the rest of the tag is valid. The player may fetch a URL that does not answer. The impression can still count. The attention number the trafficking sheet promised does not.",
            "The accounts that moved are also not a sample of the measurement. AdExchanger's list of RFP wins is a list of advertisers who had a deadline, not a panel of impressions re-scored under both methodologies. P&G signing a new verification contract does not tell you whether a 2023 Moat viewability decision and a 2026 DoubleVerify decision would have agreed on one CTV impression. That agreement was never the figure."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Treat Moat as an end-of-life name, not as a column in a 2026 vendor matrix. If a template still says DoubleVerify vs Moat, replace the second column with the vendor that actually holds the contract, and say what that vendor measures this quarter: viewability, IVT, attention, pre-bid, or some mix. The RFP statistic from 2024 is a history of who signed. It is not this quarter's methodology.",
            "Audit tags for dead verification hosts. A Moat URL, a Moat vendor key, or an OMID vendor string that pointed at Oracle's stack should be removed or replaced before the tag is treated as measured. Leaving it in produces a verification block that looks populated and does not return a score.",
            "vastlint is independent of DoubleVerify and has no relationship to the discontinued Moat service. It checks whether AdVerifications and related nodes are present and structurally consistent in VAST 2.0–4.4. It does not know whether a vendor host is still in business, and it does not score attention or invalid traffic. A present node with a dead host is a trafficking problem the structural check will not invent a replacement for. The check tells you the node is there. The end-of-life date tells you the host is not."
          ]
        },
        {
          "type": "list",
          "heading": "What to separate before using this comparison",
          "items": [
            "End of service: Oracle advertising products, including Moat Analytics, stopped on September 30, 2024.",
            "RFP win rate: 70 percent of former Moat advertiser RFPs DoubleVerify participated in, not 70 percent of all Moat spend.",
            "Product scope: viewability, attention, pre-bid suitability, and social were not one Moat feature.",
            "A 2026 fraud rate from a living vendor is a different publication from a discontinued attention product.",
            "A Verification node that still names Moat is a host, not a score."
          ]
        },
        {
          "type": "quote",
          "quote": "A share of RFPs entered during a shutdown is a sales result, and a discontinued measurement product has no current rate to lose by.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check whether verification nodes are still in the tag",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so AdVerifications and impression events are present and consistent. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Oracle to shut down advertising products and services by September 2024",
              "href": "https://ppc.land/oracle-announces-end-of-life-for-advertising-products-and-services/",
              "description": "Client-notice reporting that Moat Analytics Service was on the September 30, 2024 end-of-life list.",
              "source": "PPC Land"
            },
            {
              "label": "DoubleVerify Won 70% Of The Former Moat Advertisers It Courted",
              "href": "https://www.adexchanger.com/marketers/doubleverify-won-70-of-the-former-moat-advertisers-it-courted/",
              "description": "AdExchanger on the RFP win rate, the six-week window, and what DoubleVerify said Moat did not cover.",
              "source": "AdExchanger"
            },
            {
              "label": "Inside The Fall Of Oracle's Advertising Business",
              "href": "https://www.adexchanger.com/marketers/inside-the-fall-of-oracles-advertising-business/",
              "description": "AdExchanger on the earnings-call figure for the advertising business and the decision to exit.",
              "source": "AdExchanger"
            },
            {
              "label": "Viewability vs attention compares a pixel threshold with a score built on interaction",
              "href": "/blog/viewability-vs-attention/",
              "description": "The metric distinction buyers still attach to the Moat name.",
              "source": "vastlint"
            },
            {
              "label": "A Moat alternative has to replace a score Oracle stopped publishing",
              "href": "/blog/moat-alternative/",
              "description": "The replacement question this pair leaves open.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ias-vs-human",
      "title": "IAS vs HUMAN Compares a Named-Scheme Study With a Pre-Bid Decision on the Request",
      "description": "IAS Papyrus is a mobile cluster measured after identification: nearly 25 times the click success rate versus other traffic IAS had already separated. HUMAN MediaGuard is a pre-bid prediction on the OpenRTB bid, returned before the impression exists. One is a study of a scheme. The other is a decision on a request.",
      "seoTitle": "IAS vs HUMAN lines up nearly 25× clicks and a pre-bid flag",
      "seoDescription": "IAS Papyrus shows nearly 25× the clicks on a named mobile cluster. HUMAN MediaGuard returns an IVT flag on the OpenRTB request before the bid. vastlint checks the VAST tag. It does not see the bid request or classify invalid traffic.",
      "publishedAt": "2026-09-25",
      "updatedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "Programmatic",
        "Mobile fraud",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A named-scheme study and a pre-bid decision sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "IAS",
                "Nearly 25× clicks, about 4× eCPM, 13% higher attention",
                "Cluster lift",
                "Papyrus vs other IAS traffic",
                "Mobile reading apps",
                "August 6, 2026"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "IVT flag before the bid",
                "Pre-bid decision",
                "One OpenRTB request",
                "Programmatic",
                "MediaGuard docs"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "0.5% SIVT and 0.05% GIVT passed through",
                "Sampling valve",
                "Flagged traffic, for a rescan",
                "Programmatic",
                "HUMAN docs"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "85% of impressions, 20 trillion a week",
                "Coverage",
                "How widely MediaGuard is asked",
                "Programmatic",
                "Brochure"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/ias-vs-human.png?v=2",
          "alt": "IAS Papyrus is a post-identification comparison of clicks, price, and attention. HUMAN MediaGuard is a pre-bid prediction on the OpenRTB request.",
          "width": 1440,
          "height": 820,
          "caption": "A decision on the next bid and a write-up of a scheme found later happen at different hops.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "IAS vs HUMAN is a shortlist that pairs two companies buyers call when they want invalid traffic kept out of a campaign. The public artifacts are not the same artifact. IAS Threat Lab's Papyrus note, published August 6, 2026, measures a named mobile scheme against other traffic in IAS observation: nearly 25 times the click success rate, roughly 4 times the eCPM, about 13 percent higher attention. HUMAN's MediaGuard documentation describes a different object: a prediction, made from the OpenRTB bid, of whether that opportunity is likely invalid, returned in time to decide whether to bid. vastlint does not choose between IAS and HUMAN. It checks whether a VAST 2.0–4.4 tag still carries the verification node, and it does not see the bid request or classify invalid traffic.",
            "One sentence is about a cluster that has already been found, scored on engagement and price. The other is about a request that has not become an impression yet. A buyer who treats Papyrus's click multiple as HUMAN's block rate, or treats a MediaGuard IVT flag as a statement about attention, has changed the hop and the unit in one move.",
            "Both firms will take a fee to reduce invalid traffic. The research and the integration docs do not say they are reducing the same thing at the same moment. Remove the names and a post-identification cluster study still does not rank a pre-bid decision on a bid request."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the IAS figure measures",
          "paragraphs": [
            "Papyrus is a mobile operation in novel-reading apps. The user sees the book. Hidden webviews, orchestrated by the layer IAS calls BootNova, load other sites, take taps from the reading interface as clicks, and scroll on instruction from remote configuration. IAS reports more than 800 domains and nearly 8,000 unique host values. The ratios compare Papyrus-associated supply with non-Papyrus traffic after IAS has made that split.",
            "The monetization estimate, close to $1 million a month at the peak, applies an eCPM from Papyrus supply IAS directly observed to a broader impression footprint. IAS says clients using IVT avoidance are filtered against the associated apps, domains, and hostnames. That filter is a list built after the scheme was identified. It is not a prediction attached to an arbitrary OpenRTB bid that has never been tied to this cluster.",
            "The unit is a lift. Clicks, price, and an attention score moved for this named set relative to the residual. A lift on a cluster does not say what fraction of bid requests in a CTV auction HUMAN or IAS would have flagged before the bid. The Papyrus note does not publish that fraction."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the HUMAN figure measures",
          "paragraphs": [
            "HUMAN's MediaGuard docs describe the integration as sitting between bid requests received and bids made. The caller sends fields from the bid, or the OpenRTB BidRequest itself. MediaGuard returns a prediction of whether the opportunity is invalid, including an IVT flag the buyer can use to drop the request. The docs call it a predictive model based on reputation data, and they say the decision is meant to arrive in milliseconds, before the bid.",
            "FraudSensor is the other half, and the docs say it is required alongside MediaGuard. FraudSensor is the post-bid tag. Its observations train the pre-bid model. HUMAN's closing-the-loop note says MediaGuard lets 0.5 percent of traffic it has flagged as sophisticated invalid traffic through, so FraudSensor can rescan it, and lets 0.05 percent of general invalid traffic through for the same reason. Those percentages are a sampling valve on the pre-bid block, not a market IVT rate.",
            "A MediaGuard brochure states a different kind of number: 20 trillion transactions a week, more than 300 million unique devices a month, and a claim that over 85 percent of global programmatic impressions run through MediaGuard. Those are coverage and scale claims in HUMAN's own marketing. They are not a share of impressions classified invalid, and they are not a click multiple on a named scheme. Coverage of the bidstream is how often the model is asked. It is not how often the model says no."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why a scheme study and a bid decision do not rank each other",
          "paragraphs": [
            "The moment differs. Papyrus ratios are computed after the scheme is known and the log is split. MediaGuard's flag is computed before the impression, from what the bid request contains. A scheme that hides in the creative, in a webview behind a reading app, may not be visible in the bid fields MediaGuard is documented to consume. A bid that MediaGuard flags may never become the impression a post-bid study would have scored.",
            "The unit differs. IAS published a ratio of click success, a ratio of eCPM, and a percent difference in an attention score. HUMAN's integration publishes a boolean-style IVT decision and category codes on a request. You cannot average a 25-times click rate with an IVT flag. You can ask both questions about one campaign. They remain two questions.",
            "The training loop is not the study. FraudSensor teaching MediaGuard means post-bid labels update a pre-bid model. That is a product architecture. Papyrus is a published case about one operation's engagement metrics. An architecture that learns from post-bid tags does not, by itself, reproduce a named-scheme ratio, and a named-scheme ratio does not, by itself, say what the pre-bid model would have done on the bids that funded the scheme.",
            "Scale does not close the gap. A brochure claim that most programmatic impressions pass through MediaGuard says the model is widely asked. Papyrus says one cluster, once identified, looked more valuable than the residual on clicks and price. Wide coverage of bids and a deep study of one scheme are both useful to a buyer, and they answer a different meeting. The shortlist is the habit of holding them up as substitutes. A buyer can run both. The pre-bid model can refuse requests that match a reputation already learned, and a Papyrus-style study can explain a cluster that got through because the bid fields looked like ordinary phones. Using one document to answer the other question is how a mobile click multiple becomes a pretend block rate, or a millisecond flag becomes a pretend attention score."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Ask which hop the number came from. A pre-bid flag is a decision not to buy. A post-bid label is a decision about an impression that already served. A named-scheme study is a description of a cluster after someone identified it. IAS versus HUMAN is legible once those three are in different columns.",
            "If the risk you care about is hidden interaction on mobile, Papyrus is evidence that engagement metrics can be driven from a surface the user is not watching. If the risk you care about is bidding on requests that already look invalid, MediaGuard is documented as a check on the request. A campaign can need both, and neither publication substitutes for the other.",
            "The VAST tag is downstream of the bid. A request MediaGuard allowed can still carry a wrapper that drops verification, and a request it blocked never produces a tag to lint. vastlint is independent of IAS and of HUMAN. It checks the tag that remains, for VAST 2.0–4.4 structure. It does not predict IVT on the bid, and it does not reproduce a scheme study."
          ]
        },
        {
          "type": "list",
          "heading": "Hops that the shortlist collapses",
          "items": [
            "Pre-bid: a prediction on the OpenRTB request, before an impression exists.",
            "Post-bid tag: a label on a served ad, which HUMAN says also trains the pre-bid model.",
            "Named scheme: a cluster scored after identification, on clicks, price, and attention.",
            "Coverage: how many bids a model sees, which is not how many it rejects.",
            "The tag: whether verification survived the wrapper after the bid was won."
          ]
        },
        {
          "type": "quote",
          "quote": "A decision on the bid request and a study of a scheme found later are two moments, and a shortlist that averages them has lost both.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the tag that survives the bid",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification companions and impression events are present. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Papyrus: Inside a Mobile Scheme Built to Fake Clicks, Scrolls, and Attention",
              "href": "https://integralads.com/insider/papyrus-inside-a-mobile-scheme-built-to-fake-clicks-scrolls-and-attention/",
              "description": "IAS Threat Lab, August 6, 2026. The cluster ratios and the scope of the scheme.",
              "source": "Integral Ad Science"
            },
            {
              "label": "MediaGuard overview",
              "href": "https://docs.humansecurity.com/advertising/mediaguard-overview.mdx",
              "description": "HUMAN's description of pre-bid prediction on the OpenRTB bid, paired with FraudSensor.",
              "source": "HUMAN"
            },
            {
              "label": "Closing the loop: MediaGuard and FraudSensor",
              "href": "https://docs.humansecurity.com/advertising/closing-the-loop-mediaguard-and-fraudsensor.mdx",
              "description": "The 0.5 percent SIVT and 0.05 percent GIVT pass-through used to retrain the pre-bid model.",
              "source": "HUMAN"
            },
            {
              "label": "IAS vs Pixalate puts a named mobile cluster next to a quarterly open-auction share",
              "href": "/blog/ias-vs-pixalate/",
              "description": "The same Papyrus figures set beside a quarterly impression share instead of a pre-bid decision.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "human-vs-pixalate",
      "title": "HUMAN vs Pixalate Compares a Bid-Request Decision With a Quarterly Impression Share",
      "description": "HUMAN MediaGuard returns a pre-bid IVT prediction on an OpenRTB request. Pixalate's Q4 2025 benchmark says 19 percent of US CTV impressions in a predominantly open-auction set were invalid, across more than 103 billion impressions. A per-bid decision and a quarterly share do not rank each other.",
      "seoTitle": "HUMAN vs Pixalate lines up a pre-bid flag and a 19% share",
      "seoDescription": "HUMAN MediaGuard returns an IVT flag on the OpenRTB request before the bid. Pixalate puts Q4 2025 US CTV invalid traffic at 19% in open auction. vastlint checks the VAST tag. It does not choose between the suggestion and the share or classify invalid traffic.",
      "publishedAt": "2026-09-25",
      "updatedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A pre-bid decision and a quarterly impression share sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "HUMAN",
                "IVT flag before the bid",
                "Pre-bid decision",
                "One OpenRTB request",
                "Programmatic",
                "MediaGuard docs"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "0.5% SIVT and 0.05% GIVT passed through",
                "Sampling valve",
                "Flagged traffic, for a rescan",
                "Programmatic",
                "HUMAN docs"
              ]
            },
            {
              "cells": [
                "HUMAN",
                "85% of impressions, 20 trillion a week",
                "Coverage",
                "How widely MediaGuard is asked",
                "Programmatic",
                "Brochure"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "21% invalid",
                "Impression share",
                "Q4 2025 global CTV",
                "CTV",
                "March 9, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/human-vs-pixalate.png?v=2",
          "alt": "HUMAN MediaGuard returns an IVT flag on one bid request. Pixalate's Q4 2025 benchmark is 19 percent of US CTV impressions in a predominantly open-auction set.",
          "width": 1440,
          "height": 820,
          "caption": "A yes or no on the next bid and a percentage of last quarter are both about invalid traffic, and they are not the same fact.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "HUMAN vs Pixalate shows up when a buyer wants a fraud vendor and is handed two logos. The documents those logos publish answer different questions. HUMAN's MediaGuard docs describe a real-time prediction on a bid request: send the OpenRTB bid, receive an IVT decision before you bid. Pixalate's March 9, 2026 benchmark says 19 percent of US connected-TV impressions in its Q4 2025 set were invalid traffic, and 21 percent of global CTV, from more than 103 billion programmatic impressions that are predominantly buy-side open auction. vastlint does not choose between a pre-bid suggestion and an open-auction share. It checks whether a VAST 2.0–4.4 tag still carries the verification node, and it does not classify invalid traffic.",
            "A decision on one request is not a rate for a quarter, and a rate for a quarter is not a decision on the next request. The shortlist becomes a ranking only if someone pretends the 19 percent is HUMAN's block rate, or pretends MediaGuard's flag is a statement about the open-auction census. Neither document says that.",
            "Both companies sell protection against invalid traffic in programmatic, including CTV. Hiring one, the other, or both is a contract. The public numbers do not score the contract. Remove the names and a pre-bid prediction still does not order a quarterly impression share."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What HUMAN publishes about the decision",
          "paragraphs": [
            "MediaGuard, in HUMAN's own integration docs, sits between the bid requests a platform receives and the bids it submits. The input is fields from the bid or the full BidRequest. The output is a prediction that the opportunity is or is not invalid, with categories, fast enough that the caller can drop the request. HUMAN describes the model as reputation data, and it says FraudSensor, the post-bid tag, is part of the same integration because post-bid observations retrain the pre-bid model.",
            "The retraining note includes a sampling detail that is easy to misread as a market rate. MediaGuard allows 0.5 percent of traffic it has flagged as sophisticated invalid traffic to pass, so FraudSensor can check the prediction, and 0.05 percent of general invalid traffic for the same loop. That is a deliberate leak in the block, sized by HUMAN, so the post-bid tag still sees some of what the pre-bid model would have stopped. It is not Pixalate's 19 percent, and it is not the share of all bids HUMAN rejects.",
            "Scale claims live in a MediaGuard brochure rather than in that integration note: 20 trillion transactions a week, more than 300 million unique devices a month, and a line that over 85 percent of global programmatic impressions run through MediaGuard. Read those as HUMAN's description of coverage. Coverage is how widely the model is in the path. A firm can see most of the bidstream and still not be publishing the same quarterly IVT table as a firm that benchmarks the impressions it classified."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What Pixalate publishes about the quarter",
          "paragraphs": [
            "The March 9, 2026 North America release is a table. US CTV 19 percent, US mobile app 29 percent, US web 25 percent. Canada CTV 16 percent. Global CTV 21 percent, global mobile app 36 percent, global web 23 percent. The base is more than 103 billion global programmatic impressions, predominantly buy-side open auction. The 19 percent is a classification rate on that set, for that quarter, for US CTV.",
            "A March 26, 2026 supply-chain note repeats a 21 percent global CTV invalid share and ties it to open programmatic traffic specifically, on more than 7 billion transactions and $6.9 billion of global open programmatic CTV spend. Device rows in that note run from 14 percent on Amazon Fire TV to 28 percent on Samsung Smart TV. Those rows are still impression shares inside Pixalate's open-programmatic CTV cut. They are not per-bid accept rates from a different company's model.",
            "Pixalate also says it is accredited by the MRC for sophisticated invalid traffic detection and filtration. Accreditation is a statement about a method being audited. It does not convert the 19 percent into HUMAN's IVT flag, and it does not say what fraction of bid requests a pre-bid API would have rejected in the same quarter."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the decision and the share stay apart",
          "paragraphs": [
            "Time is the first split. MediaGuard is documented to answer before the bid. Pixalate's benchmark is a look back at impressions in a finished quarter. Impressions that were never bought because a pre-bid model said no are absent from a post-bid benchmark. Impressions that were bought and later classified invalid are present. A strict pre-bid model can shrink the post-bid rate without the quarterly benchmark, measured on unfiltered open auction, moving at all.",
            "Grain is the second split. HUMAN's API is one request in, one prediction out. Pixalate's headline is millions of impressions compressed into one percentage. You can aggregate predictions into a rate. HUMAN's docs do not publish that aggregate as a US CTV open-auction IVT percentage for Q4 2025. Pixalate's benchmark does not publish a per-request reason code. The shortlist is borrowing a shape from one firm and a number from the other.",
            "Population is the third. Pixalate names predominantly buy-side open auction. A MediaGuard customer can sit on the supply side, the demand side, or both, and can apply the flag only to some deals. An 85 percent coverage claim, if taken from the brochure, still does not say those impressions are the same 103 billion Pixalate analyzed, or that they were classified with the same rules.",
            "Accreditation does not collapse the split either. Pixalate's release says the firm is MRC-accredited for sophisticated invalid traffic detection and filtration. That is an audit of a method. HUMAN's docs describe a prediction and a post-bid tag that trains it. An audited classification of last quarter's impressions and a live flag on the next bid can both be careful work. Careful work at two different times is still two measurements, and a buyer who picks a vendor because one number was lower has picked a timestamp. If the question is whether to drop this bid, the answer is a flag with a reason code and a threshold the bidder chose. If the question is how invalid open-auction CTV looked last quarter in one firm's log, the answer is 19 percent with the population written beside it. Writing either answer into the other question's blank is how the shortlist manufactures a ranking."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Keep the per-bid decision and the quarterly share in different reports. Use the decision to explain why a request was dropped. Use the quarterly share to explain what a firm saw in open auction after the fact. HUMAN versus Pixalate does not become a single KPI by averaging them.",
            "Ask each firm for the number you actually need. If you need a block rate on your own bidstream, that is a report from the pre-bid integration, with your traffic as the denominator. If you need a market benchmark of open-auction CTV, that is a published table with its population written on it. A brochure coverage statistic answers neither.",
            "After the bid is won, the tag still has to carry measurement. vastlint is independent of HUMAN and of Pixalate. It checks VAST 2.0–4.4 structure, including verification and impression nodes. It does not call a pre-bid API, and it does not reproduce a quarterly IVT table."
          ]
        },
        {
          "type": "list",
          "heading": "Numbers that belong in different columns",
          "items": [
            "A pre-bid IVT flag on one OpenRTB request.",
            "A 0.5 percent pass-through of flagged SIVT, used to retrain, not a market rate.",
            "A coverage claim about how many impressions flow through a model.",
            "Pixalate Q4 2025 US CTV: 19 percent of a predominantly open-auction set.",
            "Pixalate device rows: 14 percent on Fire TV and 28 percent on Samsung, same supply-chain cut."
          ]
        },
        {
          "type": "quote",
          "quote": "A yes-or-no on the next bid and a percentage of last quarter's open auction are both about invalid traffic, and they are not the same fact.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the tag after the bid is won",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification and impression events are present and consistent. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "MediaGuard overview",
              "href": "https://docs.humansecurity.com/advertising/mediaguard-overview.mdx",
              "description": "Pre-bid prediction on the OpenRTB bid, with FraudSensor required alongside it.",
              "source": "HUMAN"
            },
            {
              "label": "Closing the loop: MediaGuard and FraudSensor",
              "href": "https://docs.humansecurity.com/advertising/closing-the-loop-mediaguard-and-fraudsensor.mdx",
              "description": "Pass-through of 0.5 percent of flagged SIVT and 0.05 percent of GIVT for rescanning.",
              "source": "HUMAN"
            },
            {
              "label": "Q4 2025 North America IVT and Ad Fraud Benchmarks",
              "href": "https://www.globenewswire.com/news-release/2026/03/09/3251883/0/en/Pixalate-Releases-Q4-2025-North-America-Invalid-Traffic-IVT-Ad-Fraud-Benchmarks-Connected-TV-CTV-IVT-Rate-in-United-States-at-19.html",
              "description": "US CTV at 19 percent and the 103 billion impression base.",
              "source": "Pixalate"
            },
            {
              "label": "Pixalate vs DoubleVerify lines up an open-auction share against a protected-campaign rate",
              "href": "/blog/pixalate-vs-doubleverify/",
              "description": "The same Pixalate benchmark set beside a protected-campaign rate instead of a pre-bid flag.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "viewability-vs-attention",
      "title": "Viewability vs Attention Compares a Pixel Threshold With a Score Built on Interaction",
      "description": "A video viewable impression, in the MRC definition, is at least half the pixels in view for two continuous seconds. An attention score is a model on time, sound, and interaction. IAS's Papyrus note found about 13 percent higher attention, and nearly 25 times the click success, on traffic the user was not watching. vastlint does not compute either figure. It checks the VAST nodes they depend on.",
      "publishedAt": "2026-09-25",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Measurement",
      "tags": [
        "Viewability",
        "Attention",
        "IVT",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "Viewability vs attention is the metric shortlist that sits under the vendor shortlists. Buyers say they want ads that were seen, then optimize the number that is easier to move. The two numbers are built differently. A viewable video impression, as the MRC states it and as trafficking teams already use it, means at least 50 percent of the pixels were in view for at least two continuous seconds. An attention score is a vendor model on top of duration, audibility, and interaction events. One is a threshold on the surface. The other is a score on behavior. vastlint does not compute viewability or attention. It checks whether the VAST 2.0–4.4 nodes those measurements depend on are present.",
            "IAS Threat Lab's Papyrus note is the clean demonstration that the score can rise while the person is elsewhere. In that August 6, 2026 analysis, Papyrus traffic had about 13 percent higher attention scores than non-Papyrus traffic, nearly 25 times the click success rate, and roughly 4 times the eCPM. The mechanism was hidden webviews behind a novel-reading app. The user was reading. The metrics were being generated on pages the user did not see. Attention and clicks moved. The surface the person was watching was the book.",
            "A campaign optimized on the score will bid up inventory that produces the inputs to the score. If those inputs can be synthesized, the score is not a stricter viewability. It is a different instrument, and it can point the other way. Remove the vendor names and a pixel-and-time threshold still does not equal a model of interaction."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/viewability-vs-attention.png?v=2",
          "alt": "Viewability for video is half the pixels in view for two continuous seconds. Attention is a model on interaction. Papyrus posted higher attention and far higher clicks on pages the reader was not watching.",
          "width": 1440,
          "height": 820,
          "caption": "A pixel threshold and an interaction score can move in opposite directions. The score is the one a hidden click is built to win.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What viewability measures",
          "paragraphs": [
            "The video threshold is geometric and temporal. Half the pixels, two continuous seconds, on the surface where the ad is rendered. Display uses a shorter time threshold for the same pixel idea. The point for video tags is the video rule: quartiles are not a substitute. A midpoint fires because the playhead crossed half of Duration. It does not record that half the pixels were in view. A tag can complete on a panel the viewer is not facing, or in a player that is not the visible surface, and still emit a full quartile set.",
            "VAST 4 puts a separate container, ViewableImpression, next to Impression for the viewability endpoints. That container is how the document declares where a viewability vendor should be called. If the URL is empty, or the node was dropped by a wrapper, the quartile trackers can still succeed. The join between \"the ad played\" and \"the ad met the pixel threshold\" never happens. The report then has completion and no viewability, or viewability from a different node than the one the buyer thinks is on the creative.",
            "Viewability is also silent about intent. An impression can meet the pixel threshold because the ad was on screen while the person read something else in the same app, or because a TV was on in an empty room. The MRC threshold does not claim attention. It claims a minimum of pixels and time. Teams that treat \"viewable\" as \"watched\" have already left the definition."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What attention measures",
          "paragraphs": [
            "Attention products take signals viewability does not require: time beyond the two-second floor, sound on, scroll, clicks, hover, sometimes eye-tracking panels used to train a model that is then applied to impressions without an eye tracker. The output is a score or an index. Two vendors can score the same impression differently because the models weight sound and interaction differently. There is no MRC threshold that says an attention score of a given number means the same thing in two methodologies.",
            "Papyrus shows the failure mode when interaction is unbound from the surface. Click modules passed taps from the reading UI into hidden webviews. Scroll modules moved pages the user was not looking at. IAS reported the attention score up about 13 percent and the click success rate up nearly 25 times against non-Papyrus traffic, with eCPM roughly 4 times higher. The score did what it was built to do. It treated interaction as evidence of value. The interaction was not the reader's.",
            "That is why a rising attention score with flat viewability and flat completion is a specific alarm. Viewability staying flat means the pixel threshold did not suddenly get easier to meet. Completion staying flat means the playhead did not suddenly get further. Interaction moving alone means the inputs that feed the attention model moved. Papyrus is one way to produce that pattern. It is not the only way. The pattern is the thing to split in reporting, whichever firm computes the score."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why optimizing the score can bid up the wrong inventory",
          "paragraphs": [
            "Bidders that use attention as a quality feature will pay more when the score is higher. If invalid traffic can outscore clean traffic, the feature points at the invalid supply. IAS's comparison was Papyrus versus non-Papyrus inside its own observation, not a census of all mobile. The direction still matters. A quality feature that ranks the fraudulent cluster above the residual will move money toward the cluster until something else in the system disagrees.",
            "Viewability does not automatically disagree. A hidden webview can meet a pixel threshold inside its own document while the user looks at another layer. A stitched CTV stream can meet a completion count from the stitcher's beacons while the set is off. The pixel rule and the playhead rule each have a gap. Attention, because it rewards interaction, has a gap that lines up with click fraud and scroll fraud specifically. Using it as a tie-breaker on top of viewability imports that gap into the bid.",
            "The practical split is in the columns, not in a blended \"quality\" field. Viewable rate, completion, attention, click rate. When the last two rise and the first two do not, the report is describing interaction inflation. When viewable rate rises and attention does not, the report is describing pixels in view without the interaction the model wanted. Both are real. Averaging them into one score hides which one moved."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Quote the definition with the number. A viewability rate should say which threshold, video or display, and which vendor's implementation of it. An attention rate should say which model, and whether interaction events are required to come from the same surface as the creative. A number without that sentence is how Papyrus reads as performance.",
            "On the tag, confirm ViewableImpression and AdVerifications refer to the player that has the media, not to a sibling container. Quartile URLs are not a stand-in. If a wrapper keeps Impression and drops ViewableImpression, you will have delivery and you will not have the pixel join.",
            "vastlint does not compute viewability and does not compute attention. It checks whether the nodes those measurements depend on are present and consistent in VAST 2.0–4.4. A missing ViewableImpression URL is a broken join. It is not, by itself, proof the clicks were synthetic. The structural check comes before the question of whether the interaction was real."
          ]
        },
        {
          "type": "list",
          "heading": "Signals worth keeping in separate columns",
          "items": [
            "Viewable rate against the pixel-and-time threshold, video or display stated.",
            "Completion and quartiles, which track the playhead, not pixels in view.",
            "Attention score, with the model named.",
            "Click rate on the same line item.",
            "Whether interaction beacons are bound to the surface that was actually on screen."
          ]
        },
        {
          "type": "quote",
          "quote": "A pixel threshold and an interaction score can move in opposite directions, and the score is the one a hidden click is built to win.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Validate viewability nodes before you trust the score",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so ViewableImpression and verification companions are present. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "MRC Viewable Ad Impression Measurement Guidelines",
              "href": "https://www.iab.com/guidelines/mrc-viewable-ad-impression-measurement-guidelines/",
              "description": "The pixel-and-time thresholds for display and video viewable impressions.",
              "source": "IAB / MRC"
            },
            {
              "label": "Papyrus: Inside a Mobile Scheme Built to Fake Clicks, Scrolls, and Attention",
              "href": "https://integralads.com/insider/papyrus-inside-a-mobile-scheme-built-to-fake-clicks-scrolls-and-attention/",
              "description": "IAS Threat Lab, August 6, 2026. Attention, click, and eCPM gaps on a hidden-webview scheme.",
              "source": "Integral Ad Science"
            },
            {
              "label": "How to validate ViewableImpression in VAST tags",
              "href": "/blog/how-to-validate-viewableimpression/",
              "description": "Why quartile beacons do not satisfy the viewability join.",
              "source": "vastlint"
            },
            {
              "label": "Hidden webview fraud can make invalid traffic look more valuable than the real thing",
              "href": "/blog/hidden-webview-fraud-manipulates-attention-metrics/",
              "description": "The Papyrus mechanism, and why engagement can outrank clean traffic.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "givt-vs-sivt",
      "title": "GIVT vs SIVT Separates List-Based Filtration From Traffic That Mimics a Person",
      "description": "The MRC's IVT addendum requires accredited measurers to filter general invalid traffic with lists and parameter checks, and it treats sophisticated invalid traffic as a further category that is encouraged rather than required. A log cleared of known bots and data-center ranges can still contain hijacked devices, hidden ads, and spoofed apps.",
      "seoTitle": "GIVT vs SIVT lines up a required list and an investigation",
      "seoDescription": "MRC accreditation requires list filtration for general invalid traffic. Sophisticated invalid traffic that mimics a person is encouraged rather than required. vastlint does not classify either category. It checks the VAST verification node.",
      "publishedAt": "2026-09-25",
      "updatedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "IVT",
      "tags": [
        "IVT",
        "SIVT",
        "GIVT",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "Required list filtration and an encouraged investigation sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "MRC, general",
                "Required for accreditation",
                "List checks",
                "Data centers, crawlers, prefetch, 0x0 and 1x1",
                "Shared lists",
                "June 2020"
              ]
            },
            {
              "cells": [
                "MRC, sophisticated",
                "Encouraged rather than required",
                "Investigation",
                "Hijacked devices, hidden ads, spoofed apps",
                "Mimics a person",
                "June 2020"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/givt-vs-sivt.png?v=2",
          "alt": "General invalid traffic is list and parameter filtration and is required for MRC accreditation. Sophisticated invalid traffic covers hijacked devices, hidden ads, and spoofed apps, and is encouraged rather than required.",
          "width": 1440,
          "height": 820,
          "caption": "A log cleared of known bots and data-center ranges can still contain the traffic that imitates a person.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "GIVT vs SIVT is the comparison inside the word invalid. Buyers say a campaign was filtered for IVT and mean one bucket. The Media Rating Council's Invalid Traffic Detection and Filtration Standards Addendum, in the June 2020 update, defines two. General invalid traffic is caught by routine means: lists and standardized parameter checks. Sophisticated invalid traffic is the remainder that takes advanced analytics, multi-point corroboration, or significant human intervention to identify. The addendum says accredited measurers must apply GIVT processes. It says SIVT processes are strongly encouraged, and it says they are not required. vastlint does not classify GIVT or SIVT. It checks whether impression events and AdVerifications are structurally present in VAST 2.0–4.4.",
            "That requirement gap is the whole comparison. Two accredited vendors can both remove known data-center traffic and declared crawlers, and only one of them may be looking for hijacked devices, hidden ads, or app spoofing. A report that says \"IVT filtered\" without saying which category was in scope has collapsed a mandatory list check and an optional investigation into one badge.",
            "The addendum also says the line moves. What is SIVT today can be reclassified as GIVT later, once the industry can put it on a shared list. The categories are a method split, not a permanent taxonomy of evil. Remove the acronyms and routine list filtration still does not equal an investigation of traffic that looks legitimate."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What GIVT covers",
          "paragraphs": [
            "The June 2020 addendum's examples of general invalid traffic are the checks a measurer can run from lists and parameters. Known invalid data-center traffic, with an explicit carve-out for routing artifacts of legitimate users. Bots, spiders, and crawlers, except the ones the addendum places in the sophisticated category because they masquerade as people. Non-browser user-agent headers and other unknown browsers. Pre-fetch and pre-rendered traffic where the ad was not then accessed by a valid user. Invalid placements such as 0x0 and 1x1 delivery on the client. Sessions whose device information says they cannot render an image, such as a headless browser, when the activity being counted is a rendered impression.",
            "The addendum is careful about what this is not. Non-rendering GIVT is not a viewability test. The text says the category is agnostic of whether an ad was viewable. It also says non-rendered impressions should stay out of gross impression counts rather than being reclassified as IVT. Pre-fetch that never becomes a real render is excluded from the count. The spirit of the list is: if a standardized check can see that this was never a legitimate opportunity, drop it the same way everyone else drops it.",
            "That sameness is why GIVT is mandatory for accredited measurement. The addendum says the point of a shared general category is to keep discrepancies between measurers small. If every audited firm strips the same data-center ranges and the same declared crawlers, the residual logs are comparable. If each firm invents its own general list, \"IVT-free\" means a different subtraction in every report."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What SIVT covers",
          "paragraphs": [
            "Sophisticated invalid traffic, in the same section, is the traffic that survives those lists. The examples include automated browsing from a dedicated device, such as emulators and custom automation, and automated browsing from a non-dedicated device, including infected and hijacked sessions. Manipulated activity: forced windows, forced clicks, clickjacking, hijacked measurement events. Falsified events, and the addendum names viewability, clicks, location, and server-side ad insertion spoofing among them. Domain and app misrepresentation. Bots that masquerade as legitimate users and are only caught by sophisticated means. Hidden, stacked, transparent, or otherwise obfuscated ad serving. Invalid proxy traffic. Adware and malware that inject ads. Cookie stuffing.",
            "Papyrus, the mobile scheme IAS described in August 2026, sits on this side of the line in spirit even though the MRC text does not name it. Hidden webviews, clicks passed through from a different surface, scrolls on remote instruction: that is manipulated activity and obfuscated serving, not a data-center range on a list. A GIVT filter that removes known crawlers would leave Papyrus in the log, because the devices are real phones and the user-agent can look ordinary. The damage showed up as engagement that beat the residual: nearly 25 times the click success rate, roughly 4 times the eCPM, about 13 percent higher attention.",
            "The addendum's reporting point follows. Because SIVT methods differ by vendor, two firms can disagree on the sophisticated slice and still agree on the general slice. A buyer who switches vendors and sees the IVT rate jump may be looking at a change in SIVT coverage, not a change in the traffic. The addendum says SIVT detection can be audited, and it encourages firms that do the work to seek that accreditation. It does not pretend the sophisticated number is interchangeable the way the general lists are meant to be."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why a clean GIVT rate can hide the problem you meant",
          "paragraphs": [
            "A campaign report that says general invalid traffic was removed has done the mandatory half. Data centers, declared bots, prefetch, tiny placements. What remains can include everything the sophisticated examples name. Hijacked measurement, spoofed apps, SSAI spoofing, hidden ads. Those are the cases that still look like people in a simple filter. They are also the cases that move click rate and attention, which is what an optimizer will bid toward.",
            "DoubleVerify's May 2026 CTV release is a reminder that the mix itself varies. In North America, bot fraud was 82 percent of the violations DV described. In APAC, data-center traffic was 98 percent. Data-center traffic is the GIVT example the MRC lists first. Bot schemes that imitate users are the sophisticated problem. A global \"IVT rate\" that blends those regions blends a list problem and an imitation problem. The fix for one is a range. The fix for the other is an investigation.",
            "Pre-bid and post-bid do not line up neatly on the same split. A list of data-center IPs can run before the bid. A judgment that a real device has been hijacked, or that a webview is hidden, often needs the impression. HUMAN's own taxonomy uses the MRC split and says sophisticated traffic resembles authentic behavior, so it is not caught by the routine methods used for general traffic. That is the addendum's distinction, restated as a product. Filtering GIVT pre-bid and calling the campaign SIVT-free is how the words get swapped."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the two categories",
          "paragraphs": [
            "Require the label. Every IVT rate in a report should say GIVT, SIVT, or both, and should say whether SIVT filtration was in scope. A vendor accredited for general filtration has done what the addendum requires. A vendor that also discloses sophisticated filtration has done the further thing. Comparing their headline rates without that sentence compares a list to an investigation.",
            "Watch the metrics SIVT is built to fake. Clicks, viewability decisions, and attention scores can move while a GIVT report stays quiet. IAS's Papyrus figures are the pattern: interaction up, on supply that was not a declared crawler. Split those metrics from the GIVT line so a clean general rate cannot hide them.",
            "On the tag, falsified measurement includes a verification node that never arrives. vastlint does not classify GIVT or SIVT. It checks whether impression events and AdVerifications are structurally present in VAST 2.0–4.4. A missing verification node is not sophisticated invalid traffic by itself. It is a document that cannot carry the post-bid check the sophisticated category depends on."
          ]
        },
        {
          "type": "list",
          "heading": "Examples the MRC addendum actually separates",
          "items": [
            "GIVT: known invalid data-center traffic, declared crawlers, non-browser user agents, prefetch that never renders, 0x0 and 1x1 placements.",
            "SIVT: hijacked devices, masquerading bots, hidden or stacked ads, app and domain spoofing, falsified viewability and clicks, SSAI spoofing.",
            "Required for accredited measurers: GIVT filtration.",
            "Encouraged, not required: SIVT filtration, which can be audited when a firm applies it.",
            "A category can move from sophisticated to general once it can be reduced to a shared list."
          ]
        },
        {
          "type": "quote",
          "quote": "A list can make two measurers agree, and the traffic that imitates a person is exactly what the list was not built to catch.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Check the tag that a post-bid filter would have to read",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so impression events and verification nodes are present. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Invalid Traffic Detection and Filtration Standards Addendum, June 2020 update",
              "href": "https://www.mediaratingcouncil.org/sites/default/files/Standards/IVT%20Addendum%20Update%20062520.pdf",
              "description": "MRC definitions, GIVT and SIVT examples, and the requirement that accredited measurers apply GIVT while SIVT is encouraged.",
              "source": "Media Rating Council"
            },
            {
              "label": "Papyrus: Inside a Mobile Scheme Built to Fake Clicks, Scrolls, and Attention",
              "href": "https://integralads.com/insider/papyrus-inside-a-mobile-scheme-built-to-fake-clicks-scrolls-and-attention/",
              "description": "A hidden-webview scheme whose damage shows up in clicks and attention rather than in a data-center list.",
              "source": "Integral Ad Science"
            },
            {
              "label": "Global Study: Fueled by AI, CTV Fraud Schemes Surge 140% Globally",
              "href": "https://doubleverify.com/company/newsroom/global-study-ctv-fraud-schemes-surge-140-globally",
              "description": "Regional mix of bot fraud and data-center traffic in CTV violations.",
              "source": "DoubleVerify"
            },
            {
              "label": "Viewability vs attention compares a pixel threshold with a score built on interaction",
              "href": "/blog/viewability-vs-attention/",
              "description": "Why interaction metrics are the ones sophisticated schemes are built to move.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "pre-bid-vs-post-bid-ivt",
      "title": "Pre-Bid vs Post-Bid IVT Compares a Decision Before the Bid With a Label After the Impression",
      "description": "A pre-bid IVT check decides whether you buy the request, using what the bid contains. A post-bid check labels an impression that already served, using signals the request did not have. HUMAN's own integration runs both, and lets a fraction of blocked traffic through so the post-bid tag can retrain the pre-bid model. vastlint does not make either call. It checks the VAST nodes a post-bid check needs.",
      "publishedAt": "2026-09-25",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "IVT",
      "tags": [
        "IVT",
        "Programmatic",
        "CTV",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "Pre-bid vs post-bid IVT is the comparison vendors blur in a single phrase like \"fraud protection.\" The two checks happen at different times and see different fields. Pre-bid runs before money moves. The input is the bid request: URL or app, device, IP, supply path, whatever the OpenRTB object carries. The output is a decision to bid or not. Post-bid runs after the ad is served. The input can include the rendered page or the player, the verification tag, and events the request never had. The output is a label on an impression you may already owe. vastlint does not make the pre-bid call and does not label IVT. It checks whether a VAST 2.0–4.4 document still contains the verification and impression nodes a post-bid check is supposed to use.",
            "HUMAN's MediaGuard and FraudSensor docs are unusually plain about running both on purpose. MediaGuard predicts from the bid. FraudSensor measures the served ad and retrains the prediction. The docs say MediaGuard allows 0.5 percent of traffic flagged as sophisticated invalid traffic to pass so FraudSensor can rescan it, and 0.05 percent of general invalid traffic for the same loop. The pass-through exists because a pre-bid decision that never lets the post-bid tag see a positive cannot check itself.",
            "IAS describes the same two moments in its own fraud write-up: a pre-bid avoidance segment that tells a DSP whether an opportunity looks like invalid traffic from the bid fields, and a tag that runs before render and can see URL, IP, user agent, and signals that were not available pre-bid, then block or report. Two stages, one vendor, and the second stage is there because the first stage is blind to part of the evidence. Remove the vendor names and a decision not to buy still does not equal a label on what served."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/pre-bid-vs-post-bid-ivt.png?v=2",
          "alt": "Pre-bid IVT uses the bid request to refuse an opportunity. Post-bid IVT labels an impression that already served. A small pass-through exists so the post-bid tag can check the pre-bid model.",
          "width": 1440,
          "height": 820,
          "caption": "The check before the bid can only refuse a request. The check after the impression can only argue with a bill.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What a pre-bid decision can see",
          "paragraphs": [
            "The bid request is a claim about the opportunity. Bundle, domain, device type, IP, user agent, and a supply chain. A model can learn that some combinations have a history of invalid outcomes and refuse them in milliseconds. That is MediaGuard's documented job, and it is the job of any pre-bid IVT segment that returns a yes or no to the bidder. The strength is timing. An impression you do not buy cannot invoice you.",
            "The weakness is the same timing. The creative has not run. A hidden webview, a click injected after render, a stitcher that will fire beacons from a data center with a spoofed device: none of that is finished when the bid is scored. The model is predicting from reputation and from fields that can themselves be spoofed. App ID and domain misrepresentation are on the MRC's sophisticated-invalid list precisely because the request can lie about where the ad will land.",
            "A pre-bid block rate is therefore a property of the requests you were willing to refuse, on the fields you sent. It is not the IVT rate of the impressions you served. A strict threshold makes the block rate high and the served-impression IVT rate low. Quoting only the served rate hides the refusals. Quoting only the block rate hides what got through."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What a post-bid label can see",
          "paragraphs": [
            "After the impression, a tag or a player callback can observe render, viewability, player size, and whether the media actually started. IAS's description of its JavaScript stage is this moment: more signals than the bid, and a choice to block the render or to report. HUMAN's FraudSensor is this moment for the ads that were allowed to serve, including the thin slice the pre-bid model intentionally let through.",
            "Post-bid is also where a quarterly benchmark lives. Pixalate's Q4 2025 figure, 19 percent of US CTV impressions invalid in a predominantly open-auction set, is a classification of impressions, not a count of bids refused. DoubleVerify's under-1-percent fraud rate on protected CTV campaigns is likewise a statement about campaigns after controls, not a statement about every request the bidder saw. Comparing a pre-bid block rate to either of those numbers compares refusals to a classified log of what remained.",
            "The bill follows the impression. A post-bid label can still dispute it, credit it, or exclude it from a viewability denominator. It cannot un-buy it. That is why buyers pay for pre-bid even when they already have post-bid: the expensive failure is the one that clears the auction. The reason they still pay for post-bid is that pre-bid is a prediction, and the pass-through percentages in HUMAN's docs are an admission that the prediction wants a later look."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the two rates diverge on the same campaign",
          "paragraphs": [
            "They should diverge. The pre-bid rate's denominator is requests. The post-bid rate's denominator is impressions, or viewable impressions, or completed plays. Dropping the worst requests makes the impression log look cleaner without the request log looking cleaner. A quarterly open-auction benchmark that includes unfiltered demand will look worse than a protected campaign from the same season. DoubleVerify's own split, under 1 percent protected and nearly 9 percent with controls off, is this gap measured inside one firm's tests.",
            "They can also disagree on one opportunity. The bid fields say the app is a known streaming bundle. The rendered result is a hidden webview or a different bundle. Pre-bid says buy. Post-bid says invalid. That disagreement is the false-representation case, and it is not a bug in the spreadsheet. It is the reason the second check exists. The reverse happens too: pre-bid refuses a request that would have rendered cleanly, and the post-bid tag never sees it, so the refusal is only visible in the bid log.",
            "SSAI adds a third twist. If the stitcher fires the impression beacon, the post-bid \"device\" is a server. A pre-bid model that trusted the device fields in the request, and a post-bid model that sees a data-center IP on the beacon, will disagree even when a person watched the ad. The MRC addendum lists SSAI spoofing under sophisticated invalid traffic. Distinguishing spoofing from legitimate server-side beaconing is exactly the kind of judgment a bid-field check cannot finish."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the two checks",
          "paragraphs": [
            "Report them on separate rows. Requests scored, requests refused, impressions served, impressions labeled invalid, impressions missing a verification event. A single \"IVT percent\" that does not say which row it came from will be compared with someone else's row, and the comparison will be wrong in a predictable direction.",
            "Keep a sample of pre-bid positives in the post-bid path if you want the model to stay honest. HUMAN documents that sample as a fraction of a percent. The size is their choice. The existence of the sample is the lesson: a block that is never checked against a served impression drifts.",
            "The tag is the post-bid instrument for video. If AdVerifications never survive the wrapper, the post-bid vendor is labeling from a pixel that is not on the creative, or labeling nothing. vastlint does not make the pre-bid call and does not label IVT. It checks that the VAST 2.0–4.4 document still contains the verification and impression nodes a post-bid check is supposed to use."
          ]
        },
        {
          "type": "list",
          "heading": "Rows that should not share one rate",
          "items": [
            "Bid requests scored, and bid requests refused, before an impression exists.",
            "Impressions served, and impressions labeled invalid after the fact.",
            "A deliberate pass-through of flagged traffic, used to retrain, not a market IVT rate.",
            "A protected-campaign rate and an open-auction benchmark from the same quarter.",
            "Server-fired SSAI beacons versus device-fired beacons on the same creative."
          ]
        },
        {
          "type": "quote",
          "quote": "The check before the bid can only refuse a request, and the check after the impression can only argue with a bill.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Make sure the post-bid tag is still in the VAST",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification companions survive the wrapper. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "MediaGuard overview",
              "href": "https://docs.humansecurity.com/advertising/mediaguard-overview.mdx",
              "description": "Pre-bid prediction on the OpenRTB bid, documented as paired with a post-bid tag.",
              "source": "HUMAN"
            },
            {
              "label": "Closing the loop: MediaGuard and FraudSensor",
              "href": "https://docs.humansecurity.com/advertising/closing-the-loop-mediaguard-and-fraudsensor.mdx",
              "description": "Why a fraction of pre-bid flags are allowed through for post-bid rescanning.",
              "source": "HUMAN"
            },
            {
              "label": "IAS's multi-tiered approach to combating ad fraud",
              "href": "https://integralads.com/insider/iass-multi-tiered-approach-to-combating-ad-fraud/",
              "description": "IAS on pre-bid avoidance from bid fields and a later tag with signals the bid did not have.",
              "source": "Integral Ad Science"
            },
            {
              "label": "GIVT vs SIVT separates list-based filtration from traffic that mimics a person",
              "href": "/blog/givt-vs-sivt/",
              "description": "Why some of what post-bid can see will never be a pre-bid list.",
              "source": "vastlint"
            },
            {
              "label": "SSAI spoofing lines up a server beacon and a falsified measurement event",
              "href": "/blog/ssai-spoofing/",
              "description": "The fraud category that imitates a legitimate stitch.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ssai-vs-csai",
      "title": "SSAI vs CSAI Compares a Beacon Fired by the Stitcher With a Beacon Fired by the Device",
      "description": "In client-side ad insertion the device requests the VAST and fires the beacons. In server-side ad insertion the stitcher can do both, then hand the screen one continuous stream. The same creative produces a different measurement object depending on who fired the impression. vastlint does not detect spoofing. It checks the VAST document either path parses.",
      "publishedAt": "2026-09-25",
      "updatedAt": "2026-09-26",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "CTV delivery",
      "tags": [
        "SSAI",
        "CTV",
        "VAST",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "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. vastlint does not detect stitcher spoofing. It checks the VAST 2.0–4.4 document the stitcher or the device will parse.",
            "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."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/ssai-vs-csai.png?v=2",
          "alt": "In client-side ad insertion the device requests the VAST and fires beacons. In server-side ad insertion the stitcher can fetch the tag and fire beacons itself, which looks like data-center traffic unless the device address is forwarded.",
          "width": 1440,
          "height": 820,
          "caption": "The impression URL can be identical and still mean a playhead on the device or a clock on the stitcher.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What client-side insertion measures",
          "paragraphs": [
            "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."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What server-side insertion measures",
          "paragraphs": [
            "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](https://pixellint.org/docs/vast-tracking-events-are-pixels/) 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."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the same tag produces two fraud stories",
          "paragraphs": [
            "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."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the two paths",
          "paragraphs": [
            "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."
          ]
        },
        {
          "type": "list",
          "heading": "Questions that decide which count you have",
          "items": [
            "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?"
          ]
        },
        {
          "type": "quote",
          "quote": "The impression URL can be identical and still mean a playhead on the device or a clock on the stitcher.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the tag each path will actually fetch",
          "paragraph": "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.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Invalid Traffic Detection and Filtration Standards Addendum, June 2020 update",
              "href": "https://www.mediaratingcouncil.org/sites/default/files/Standards/IVT%20Addendum%20Update%20062520.pdf",
              "description": "MRC places SSAI spoofing among falsified measurement events in the sophisticated invalid category.",
              "source": "Media Rating Council"
            },
            {
              "label": "SSAI rewrites your VAST",
              "href": "/blog/ssai-vast-stitch-time-failures/",
              "description": "What a stitcher does to wrappers, media files, and beacons between QA and the screen.",
              "source": "vastlint"
            },
            {
              "label": "GIVT vs SIVT separates list-based filtration from traffic that mimics a person",
              "href": "/blog/givt-vs-sivt/",
              "description": "Why a data-center list cannot tell a stitcher from a botnet by itself.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vpaid-vs-simid",
      "title": "VPAID vs SIMID Compares an Executable in the Player With a Sidecar Beside the Media File",
      "description": "IAB Tech Lab marks VPAID deprecated and replaced by SIMID for interactivity and OMID for measurement. VPAID can be the thing that plays the ad. SIMID sits beside a media file the player controls. vastlint checks that split in the tag. It does not execute VPAID or open a SIMID session.",
      "publishedAt": "2026-09-25",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "VPAID",
        "SIMID",
        "OMID",
        "CTV",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each framework, in one row",
          "caption": "An executable that plays the ad and a sidecar beside a file the player already owns do not belong in one fallback chain. vastlint checks the nodes. It does not run them.",
          "columns": [
            "Spec",
            "Owns",
            "If it fails",
            "Runtime"
          ],
          "rows": [
            {
              "cells": [
                "VPAID",
                "Playback, and often measurement",
                "Often no media file left",
                "IMA HTML5. Deprecated."
              ]
            },
            {
              "cells": [
                "SIMID",
                "Interaction beside the file",
                "The media file can still play",
                "A player that implements SIMID"
              ]
            },
            {
              "cells": [
                "OMID",
                "Measurement",
                "The ad can play unmeasured",
                "AdVerifications, via OM SDK"
              ]
            }
          ]
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "VPAID vs SIMID is the comparison trafficking sheets still ask when a creative needs a click or an overlay. The IAB Tech Lab's answer is on the standards pages: VPAID is deprecated and replaced, SIMID is the interactive piece, and OMID is the measurement piece that used to be tangled inside VPAID. Google's IMA documentation draws the runtime line in public: only the HTML5 SDK supports VPAID 2 JavaScript creatives. SIMID support is documented separately. The two strings are not interchangeable values of one apiFramework attribute. vastlint checks apiFramework values, secure URLs, and whether a linear creative still has a file a player can render. It does not execute VPAID and it does not open a SIMID session.",
            "The architectural difference is who owns the video. A VPAID creative can be the playback engine. The player hands it a slot, and the unit loads its own media, draws its own controls, and emits its own events. A SIMID unit is a sidecar. The player plays a media file it selected, and the interactive document talks to that player over a defined channel. If the sidecar fails, the media file can still play. If a VPAID unit fails, there is often no separate media file left to play.",
            "That is why \"fall back to VPAID\" on a CTV or SSAI tag is not a compatibility plan. Those runtimes do not want an arbitrary executable in the player, and a stitcher cannot splice an executable into a content stream the way it splices a media file. Remove the names and an executable that replaces the player is still a different object from an interactive document that sits beside a file the player already owns."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vpaid-vs-simid.png?v=2",
          "alt": "VPAID is an executable that can be the playback engine. SIMID is an interactive file beside a media file the player controls, with measurement in OMID rather than inside the creative.",
          "width": 1440,
          "height": 820,
          "caption": "An executable that plays the ad and a sidecar beside a file the player already owns do not belong in one fallback chain.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What VPAID puts in the tag",
          "paragraphs": [
            "In the VAST document, VPAID usually appears as a media file whose API framework says VPAID, often a JavaScript resource. The player that supports it loads that resource and expects the VPAID interface: init, start, and a stream of events the creative chooses to emit. Quartiles and impressions can be fired by the creative rather than by the player's own playhead. Measurement code bundled inside the same executable was the historical reason verification vendors shipped VPAID. The creative, the playback, and the measurement were one object.",
            "That object depends on a browser-like JavaScript environment. Google's IMA docs limit VPAID 2 JavaScript support to the HTML5 SDK. A television player, a native mobile player, and a server-side stitcher are outside that environment even when they play ordinary MP4. A tag that offers only a VPAID media file has not offered those platforms a file. The error the device returns is a media-file miss. The trafficking sheet still said the line item had a creative.",
            "Deprecation does not delete old tags. IAB's label means new work should not start there, and existing work should move. A 2026 wrapper that still prefers VPAID because \"some web players need it\" keeps an executable on a path that also serves CTV. The web player that needed it is a shrinking set. The television that cannot run it is not."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What SIMID puts in the tag",
          "paragraphs": [
            "SIMID is an interactive creative file, identified in VAST with apiFramework SIMID, alongside media the player can play without it. The player owns duration, quartiles, and the decision to start. The SIMID document loads in a sandboxed frame and exchanges messages with the player. Clicks, overlays, and other interaction go through that channel. If the frame never loads, the media file is still a media file. Measurement vendors are directed to OMID, not to code hidden inside the interactive unit.",
            "IAB's SIMID page describes that split as the point: SIMID for interactivity, OMID for measurement, and a better fit for mobile, SSAI, OTT, and live than a single executable was. A stitcher can transcode the media file and still leave the interactive sidecar for a client that supports it, or ignore the sidecar and play the file. It cannot transcode a VPAID script into an MPEG segment and preserve the script's behavior.",
            "The tag-level mistakes are specific. A SIMID URL that is empty, not HTTPS, or pointed at a VPAID payload will fail the players that implemented the new interface and will not revive the old one. Putting SIMID only in a nonlinear iframe when the linear creative has no media file repeats the VPAID failure mode: nothing to play if the interactive part fails. The preferred shape is a real media file plus the interactive file, with OMID in AdVerifications rather than inside either one."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the fallback story keeps the deprecated path alive",
          "paragraphs": [
            "A fallback is supposed to widen the set of devices that can play the ad. Offering VPAID as the alternative to SIMID narrows it. Devices that run SIMID already have a media file to play if you gave them one. Devices that run neither will not run VPAID either, if they are televisions and native apps. The only runtime that uniquely wanted VPAID was a browser SDK, and that SDK's vendor now documents SIMID on its own page.",
            "Measurement is the part people smuggle back in. A VPAID unit that \"also does viewability\" feels like one tag instead of two. The replacement is two explicit nodes: the media file, and an OMID verification. Collapsing them again into an executable recreates the security and the SSAI problems VPAID created, in exchange for a shorter trafficking form. The form is not the measurement. OMID in AdVerifications is the measurement. A script that happens to emit a quartile is a creative claiming it played.",
            "Wrappers hide the choice until the last hop. The wrapper you QA can look like a simple MP4. The inline it fetches can be VPAID-only. Or the inline can be SIMID with a broken media file and a healthy interactive URL. Hop-one inspection that stops at the wrapper will bless both. The comparison that matters is in the inline the player or the stitcher finally parses."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the two frameworks",
          "paragraphs": [
            "Treat VPAID as a legacy web path you still have to detect, not as a format you add for safety. New tags get a playable media file, SIMID only when there is a real interaction, and OMID when a vendor must measure. If a screen does not need interaction, it does not need either framework. The media file is the ad.",
            "On old tags, find every MediaFile and InteractiveCreativeFile whose apiFramework is VPAID or SIMID, and check that a non-executable file remains. A SIMID file with no sibling media file is the VPAID shape wearing the new name. A VPAID file as the only media file is the shape televisions already drop.",
            "vastlint checks those structures for VAST 2.0–4.4: apiFramework values, secure URLs, and whether a linear creative still has something a player can render. It does not execute VPAID and it does not open a SIMID session. The check is there so a deprecated executable is visible before a CTV player is the first system to refuse it."
          ]
        },
        {
          "type": "list",
          "heading": "What to look for in the inline",
          "items": [
            "A media file the player can decode without loading JavaScript.",
            "SIMID only as an interactive file beside that media, when interaction is actually required.",
            "OMID in AdVerifications, not inside the creative executable.",
            "Any remaining VPAID media file, treated as legacy web compatibility rather than as a CTV fallback.",
            "The inline after wrappers, not the wrapper you were handed in QA."
          ]
        },
        {
          "type": "quote",
          "quote": "An executable that plays the ad and a sidecar that sits beside a file the player already owns do not fail the same way, and they do not belong in one fallback chain.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "See whether the inline still depends on VPAID",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so SIMID, OMID, and ordinary media files are structurally consistent. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab SIMID standard",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID for interactivity and OMID for measurement, as the replacement for VPAID's combined role.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub, where VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: VPAID 2 JavaScript",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "VPAID is deprecated. Stop treating it like a fallback",
              "href": "/blog/vpaid-is-deprecated-stop-treating-it-like-a-fallback/",
              "description": "The deprecation record and why a VPAID fallback narrows the devices that can play the ad.",
              "source": "vastlint"
            },
            {
              "label": "How to validate SIMID in VAST tags",
              "href": "/blog/how-to-validate-simid-in-vast-tags/",
              "description": "The structural checks on InteractiveCreativeFile and the media file beside it.",
              "source": "vastlint"
            },
            {
              "label": "What replaced VPAID",
              "href": "/blog/what-replaced-vpaid/",
              "description": "The index across SIMID, OMID, MRAID, and the media file.",
              "source": "vastlint"
            },
            {
              "label": "A SIMID alternative depends on the job",
              "href": "/blog/simid-alternative/",
              "description": "When the right replacement is no interactive framework.",
              "source": "vastlint"
            }
          ]
        }
      ],
      "seoTitle": "VPAID vs SIMID lines up an executable and a sidecar",
      "seoDescription": "VPAID can be the playback engine and is deprecated. SIMID sits beside a media file the player owns. vastlint checks both in the VAST tag. It does not run either session.",
      "updatedAt": "2026-09-29"
    },
    {
      "slug": "ias-vs-pixalate",
      "title": "IAS vs Pixalate Puts a Named Mobile Cluster Next to a Quarterly Open-Auction Share",
      "description": "IAS Threat Lab's Papyrus note measures a named mobile cluster against other traffic it already separated: nearly 25 times the click success rate, roughly 4 times the eCPM, and about 13 percent higher attention. Pixalate's Q4 2025 benchmark measures a share of predominantly buy-side open-auction impressions: 19 percent of US CTV and 21 percent of global CTV, across more than 103 billion impressions. Those figures answer different questions.",
      "seoTitle": "IAS vs Pixalate lines up nearly 25× clicks and a 19% share",
      "seoDescription": "IAS Papyrus shows nearly 25× the clicks on a named mobile cluster. Pixalate puts Q4 2025 US CTV invalid traffic at 19% in open auction. vastlint checks the VAST tag. It does not rank the firms or classify invalid traffic.",
      "publishedAt": "2026-09-25",
      "updatedAt": "2026-09-27",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "CTV",
        "Programmatic",
        "Mobile fraud",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each published figure, in one row",
          "caption": "A named mobile cluster and a quarterly open-auction share sit together here and do not share a scale.",
          "columns": [
            "Firm",
            "Figure",
            "Unit",
            "Population",
            "Surface",
            "Date"
          ],
          "rows": [
            {
              "cells": [
                "IAS",
                "Nearly 25× clicks, about 4× eCPM, 13% higher attention",
                "Cluster lift",
                "Papyrus vs other IAS traffic",
                "Mobile reading apps",
                "August 6, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "19% invalid",
                "Impression share",
                "Q4 2025 US CTV, mostly open auction",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "21% invalid",
                "Impression share",
                "Q4 2025 global CTV",
                "CTV",
                "March 9, 2026"
              ]
            },
            {
              "cells": [
                "Pixalate",
                "29% US, 36% global",
                "Impression share",
                "Q4 2025 mobile app",
                "Mobile app",
                "March 9, 2026"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/ias-vs-pixalate.png?v=2",
          "alt": "IAS Papyrus compares a named mobile cluster with other traffic on clicks, price, and attention. Pixalate's benchmark is 19 percent of US CTV impressions in a predominantly open-auction quarter.",
          "width": 1440,
          "height": 820,
          "caption": "Putting the click multiple next to the quarterly share ranks neither the traffic nor the firms.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "The query IAS vs Pixalate, which is the same shortlist people type as Pixalate vs Integral Ad Science, is a vendor shortlist. The two headlines that travel with those names are a named-scheme study and a quarterly impression share. On August 6, 2026, IAS Threat Lab described Papyrus: novel-reading apps that keep a reading interface on screen while hidden webviews load other sites, pass user taps through as clicks, and scroll pages on remote instruction. In IAS analysis that cluster showed nearly 25 times the click success rate, roughly 4 times the eCPM, and about 13 percent higher attention scores than non-Papyrus traffic. On March 9, 2026, Pixalate published Q4 2025 invalid-traffic benchmarks: 19 percent of US connected-TV impressions in its set, 21 percent of global CTV, drawn from more than 103 billion programmatic impressions that are predominantly buy-side open auction. vastlint does not rank IAS against Pixalate. It checks whether a VAST 2.0–4.4 tag still carries the verification node either study assumes, and it does not classify invalid traffic.",
            "The denominator is the argument. Papyrus is how a cluster scored on clicks, price, and attention after IAS had already separated it from the rest of its observation. The Pixalate table is the share of impressions, in a quarterly open-auction set, that Pixalate classified as invalid. A click multiple on a named scheme is a result about that scheme, and a 19 percent invalid share is a result about that impression set. Adjacent cells in a shortlist do not turn those two results into a ranking of the traffic or of the firms.",
            "Both companies sell detection and measurement. IAS describes IVT avoidance that filters the apps, domains, and hostnames once a scheme is identified. Pixalate describes fraud protection, privacy, and supply-chain analytics, and the benchmark release says Pixalate is accredited by the MRC for sophisticated invalid traffic detection and filtration. Hiring either firm is a contract, a coverage map, and a log you can actually join. The public research leaves that choice open, because the headlines answer different questions. Remove the company names and the claim still stands: a post-identification cluster study and a quarterly impression benchmark do not order each other."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the IAS figures measure",
          "paragraphs": [
            "Papyrus is a mobile operation built around long reading sessions. A utility app is open briefly, while a novel app stays in the foreground, and IAS treats that window as the time the scheme monetizes. BootNova, the orchestration layer IAS names, takes remote configuration for whether hidden activity runs, which URLs load, how many webviews are active, and how those webviews interact with the page. Workers IAS calls WebViewOut attach the webviews behind the visible interface through native layering. IAS reports more than 800 domains and nearly 8,000 unique host values, skewed toward gaming, blog, news-style, and generative-AI destinations.",
            "The ratios, Papyrus-associated supply compared with non-Papyrus traffic in IAS observation, are nearly 25 times the click success rate, roughly 4 times the eCPM, and about 13 percent higher attention scores. IAS puts monetization impact near $1 million a month at the peak. The method IAS states takes an eCPM from Papyrus supply it directly observed and applies that eCPM to a broader impression footprint from supply-path data. The comparison group is the traffic IAS left outside the Papyrus bucket. IAS's prose also calls the gap a case of fraudulent traffic looking more valuable than legitimate traffic. The published statistic itself is the split between the named cluster and the residual.",
            "IAS says clients on IVT avoidance are already protected, because the associated apps, domains, and hostnames are filtered as invalid across avoidance and measurement. That is a block list after identification. The document reports the cluster's lift on clicks, price, and attention, a domain count, a host count, and an estimated monthly monetization figure built from an observed eCPM and a broader impression footprint. A Q4 2025 share of all mobile impressions, a CTV rate, and another firm's label on the same apps are outside what this note contains."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the Pixalate figures measure",
          "paragraphs": [
            "The March 9, 2026 release is a table of invalid-traffic shares for Q4 2025. United States: desktop and mobile web 25 percent, mobile app 29 percent, CTV 19 percent. Canada: web 20 percent, mobile app 27 percent, CTV 16 percent. Global, in the same release: web 23 percent, mobile app 36 percent, CTV 21 percent. Pixalate says its data science team analyzed more than 103 billion global programmatic impressions, and that the datasets behind the insights consist predominantly of buy-side open-auction traffic.",
            "The 19 percent is the share of US CTV impressions in that set which Pixalate classified as invalid. Open auction is the source Pixalate names as predominant. A campaign bought as private marketplace or programmatic guaranteed sits outside the population that sentence describes. A log that has already passed through a pre-bid IVT segment is a further cut: the benchmark is the classification rate on the traffic Pixalate analyzed, which is a different object from invalid traffic remaining after a buyer's own filter.",
            "Pixalate published a second Q4 2025 cut on March 26. That CTV supply-chain note says 21 percent of global CTV open programmatic ad traffic was invalid, from more than 7 billion open programmatic transactions across 185,000 CTV devices, next to $6.9 billion in global open programmatic CTV ad spend. Inside that note, Amazon Fire TV is the low end of global device IVT at 14 percent and Samsung Smart TV is the high end at 28 percent. Seven billion CTV transactions and 103 billion impressions across web, app, and CTV are different bases. Both writings print a 21 percent global CTV figure. Matching headlines with different bases are two measurements that happen to share a number.",
            "A third Pixalate cut is a spend map. MediaPost, on August 5, 2026, reported a June 2026 Pixalate study: large-screen devices account for 57 percent of US open programmatic CTV ad spending, and 43 percent runs on phones, tablets, and other small screens. The finding is a device split of spend, with no invalid-traffic rate attached. Across the three public Pixalate headlines, one is an impression classification, one is a CTV transaction classification, and one is a spend composition."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the two headlines have no shared scale",
          "paragraphs": [
            "The units differ. IAS reports relative click success, eCPM, and an attention score for one scheme against other traffic in its observation. Pixalate reports the percent of impressions it classified invalid. There is no conversion from nearly 25 times the click success rate into 19 percent invalid traffic. A spreadsheet that places them in one ranking has joined two quantities that do not share a scale.",
            "The moment of measurement differs. Papyrus ratios exist because IAS identified the scheme and split the log. The residual includes whatever was outside that cluster, including invalid traffic IAS had not placed in this bucket. Pixalate's quarterly share is a classification across the impressions it analyzed, rather than a before-and-after on one operation. A cluster can look expensive on engagement metrics and still be a small slice of impressions. A 19 percent rate can be the sum of many patterns that never receive a name.",
            "The surface differs. Papyrus is mobile, in reading apps, with hidden webviews. The Pixalate number set next to it in a shortlist is usually the US CTV row at 19 percent. The closer row in Pixalate's own March 9 table is mobile app: 29 percent in the United States and 36 percent globally. That row is an impression share for open-auction app traffic in a quarter, which is a different statistic from a click ratio on novel-reading apps that run concealed browsers."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with the shortlist",
          "paragraphs": [
            "Ask for the population before a headline becomes a reason to hire. Which impressions are in the denominator: a named cluster, open auction, deals, or traffic that already passed a filter. Whether the figure is a block decision before the bid or a label after the impression. Whether the surface is a mobile webview, a mobile app, the web, or CTV. A firm can be the right operator for a campaign and still have published a number that answers a different question from the one on the shortlist.",
            "Split the metrics on the campaign you already run. When click success or an attention score rises while viewability and completion stay flat, the pattern matches what Papyrus did to engagement, and the next question is whether those events were bound to the surface a person actually saw. When an IVT rate moves because the buy shifted from open auction into deals, the denominator moved: that incident is a mix shift, and a new named scheme is a different incident.",
            "The VAST payload is a separate check from either report. A wrapper can drop AdVerifications, fire an impression, and leave a verification vendor with nothing on the creative the player rendered. vastlint is independent of IAS and of Pixalate. It checks structural consistency for VAST 2.0–4.4: required elements, tracker URLs, and verification placement. It does not detect invalid traffic, and it does not choose between these firms. The check tells you whether the tag can carry the measurement the shortlist is about to argue over."
          ]
        },
        {
          "type": "list",
          "heading": "Questions worth writing down before the comparison",
          "items": [
            "Denominator: named cluster, open auction, deals, or traffic already filtered.",
            "Timing: a block before the bid, or a label after the impression.",
            "Surface: mobile webview, mobile app, web, or CTV, matched to the row you are quoting.",
            "Unit: a ratio against residual traffic, or a share of impressions in a quarter.",
            "On a live line item, whether click or attention moved while viewability and completion stayed flat.",
            "Whether AdVerifications and impression events are still in the tag the player received."
          ]
        },
        {
          "type": "quote",
          "quote": "A named cluster and a quarterly impression share can both be accurate, and they still cannot rank the firms that published them.",
          "attribution": "measurement triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the tag the measurement is supposed to see",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules so verification companions and impression events are present and consistent. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Papyrus: Inside a Mobile Scheme Built to Fake Clicks, Scrolls, and Attention",
              "href": "https://integralads.com/insider/papyrus-inside-a-mobile-scheme-built-to-fake-clicks-scrolls-and-attention/",
              "description": "IAS Threat Lab, August 6, 2026. Primary for the click, eCPM, attention, domain, host, and monthly impact figures, and for the observed-eCPM method.",
              "source": "Integral Ad Science"
            },
            {
              "label": "Q4 2025 North America IVT and Ad Fraud Benchmarks",
              "href": "https://www.globenewswire.com/news-release/2026/03/09/3251883/0/en/Pixalate-Releases-Q4-2025-North-America-Invalid-Traffic-IVT-Ad-Fraud-Benchmarks-Connected-TV-CTV-IVT-Rate-in-United-States-at-19.html",
              "description": "March 9, 2026. US, Canada, and global IVT shares, and the 103 billion impression, predominantly buy-side open-auction base.",
              "source": "Pixalate"
            },
            {
              "label": "Q4 2025 CTV Ad Supply Chain Trends Report",
              "href": "https://www.pixalate.com/blog/q4-2025-ctv-ad-supply-chain-trends-report",
              "description": "March 26, 2026. Global open programmatic CTV IVT at 21 percent on more than 7 billion transactions, with device rates and $6.9 billion in spend.",
              "source": "Pixalate"
            },
            {
              "label": "Study Finds More Than Half Of CTV Programmatic Served On Large Screens",
              "href": "https://www.mediapost.com/publications/article/416951/study-finds-more-than-half-of-ctv-programmatic-ser.html",
              "description": "MediaPost, August 5, 2026, on Pixalate's June 2026 US open programmatic CTV spend split: 57 percent large screen, 43 percent small screen.",
              "source": "MediaPost"
            },
            {
              "label": "Hidden webview fraud can make invalid traffic look more valuable than the real thing",
              "href": "/blog/hidden-webview-fraud-manipulates-attention-metrics/",
              "description": "The Papyrus mechanism, and which engagement signals move when the impression is synthetic.",
              "source": "vastlint"
            },
            {
              "label": "Open programmatic CTV runs on TV sets and phone apps in nearly equal measure",
              "href": "/blog/open-programmatic-ctv-two-playback-surfaces/",
              "description": "The June 2026 spend split as a delivery problem for one VAST tag on two player regimes.",
              "source": "vastlint"
            },
            {
              "label": "IAS vs DoubleVerify compares a named mobile cluster with a count of CTV schemes",
              "href": "/blog/ias-vs-doubleverify/",
              "description": "The same Papyrus figures beside DoubleVerify's scheme counts and protected-campaign rates.",
              "source": "vastlint"
            },
            {
              "label": "Pixalate vs DoubleVerify lines up an open-auction share against a protected-campaign rate",
              "href": "/blog/pixalate-vs-doubleverify/",
              "description": "The Q4 2025 benchmark beside DoubleVerify's protected and unprotected CTV rates.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "how-to-validate-vmap",
      "title": "How to Validate VMAP Ad Breaks",
      "description": "A VMAP document can be schema-valid and still schedule an ad break the player cannot fetch if AdTagURI is empty or timeOffset is unparseable.",
      "publishedAt": "2026-09-25",
      "updatedAt": "2026-09-25",
      "author": "Alex Sekowski",
      "readingTime": "12 min read",
      "heroKicker": "VMAP",
      "tags": [
        "VMAP",
        "How-to",
        "CTV",
        "Ad breaks",
        "SSAI"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "A FAST channel can show healthy VAST fill in the ad server while the living-room player never requests a mid-roll tag. Trafficking exported a VMAP playlist from Google Ad Manager or a broadcaster CMS. QA opened the XML in a browser, saw AdBreak nodes with timeOffset values, and signed off. At the ten-minute mark the player hit the break window, found an AdSource with an empty AdTagURI, and skipped the commercial pod without firing breakStart or breakEnd.",
            "The production bug is rarely a player that ignores VMAP on principle. It is a playlist that parses as XML but cannot bind a fetchable ad tag to a schedulable offset. Empty CDATA inside AdTagURI, a timeOffset written as minutes-only instead of hh:mm:ss.mmm, or a breakType the player does not implement for that surface all produce the same symptom: the content timeline reaches the break, nothing monetizes, and upstream logs still look like a valid schedule file shipped.",
            "IAB Tech Lab published VMAP so content owners can describe break structure separately from the VAST that fills each break. This piece is the structural check on that playlist: required AdBreak attributes, AdSource content rules, and the failure modes that survive schema tools because the document is well-formed even when the player cannot act on it."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/how-to-validate-vmap.png?v=2",
          "alt": "A VMAP playlist can show AdBreak nodes and a timeOffset while AdTagURI is empty, so the player skips the pod and never requests a tag.",
          "width": 1440,
          "height": 820,
          "caption": "A schedule that parses is not a break the player can monetize.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "Why a valid root element is not a break schedule",
          "paragraphs": [
            "Buyers reconcile delivery on VAST impressions and quartiles. Publishers reconcile pod revenue on breakStart and the VAST chain each break returns. Neither dashboard proves the VMAP handed the player a non-empty AdTagURI at the offset the content clock actually uses.",
            "That split is expensive on CTV because the schedule file and the ad response are different HTTP transactions. The player reads VMAP once (or per period in live workflows), waits until timeOffset matches content progress, then GETs the AdTagURI. Validating only the first VAST tag in a spreadsheet misses the hop that decides whether a break ever requests ads.",
            "SSAI paths add a third reader. The stitcher may consume VMAP to plan splice points while the client player consumes a manifest that already inlined segments. A VMAP that validates in isolation but uses percentage offsets against the wrong duration baseline schedules breaks the stitcher never sees.",
            "Genre splits make the mistake repeatable. A VOD title with a fixed duration tolerates timestamp mid-rolls. A FAST loop with sliding windows needs start, end, or ordinal #m offsets. Copying a broadcast template without re-validating timeOffset format against the player SDK docs is how green XML still yields silent breaks."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What timeOffset actually controls",
          "paragraphs": [
            "Each AdBreak requires timeOffset. VMAP accepts start, end, a clock value hh:mm:ss.mmm, a percentage such as 25%, or an ordinal position #2 meaning the second ad opportunity in the stream. The attribute tells the player when to open the break, not which creative plays.",
            "Players map timeOffset against their content clock. A value of 15:00 is not a valid clock form unless your toolchain treats it as fifteen minutes with implicit seconds. vastlint reports VMAP-1.0-adbreak-timeoffset-format when the string does not match the spec grammar, because the mid-roll will not schedule where trafficking thinks it will.",
            "repeatAfter adds recurring breaks for long-form and live-style loops. A repeatAfter that conflicts with breakId or duplicate offsets can warn as VMAP-1.0-repeatafter-conflict even when each AdBreak alone looks plausible. Validation catches static contradictions before the stream airs.",
            "breakType is required and names linear, nonlinear, or display acceptance for the break. Comma-separated values appear in the wild. A linear breakType on a player configured for overlay-only breaks fails later in the SDK, but timeOffset and AdSource still need to be valid or the player never reaches the SDK branch."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "AdSource, AdTagURI, and the fetch the player performs",
          "paragraphs": [
            "AdSource must contain exactly one of AdTagURI, VASTAdData, or CustomAdData. AdTagURI is the common production path: a URL that returns VAST when the break triggers. templateType declares vast4, vast3, vast2, vast1, or proprietary so the player knows what parser to run after the GET.",
            "allowMultipleAds and followRedirects are boolean attributes on AdSource. followRedirects false on a tag that only returns Wrapper chains stops monetization at hop one even when timeOffset is perfect. allowMultipleAds true on a break that trafficking sized for a single thirty-second spot affects pod sequencing inside the VAST response, not the VMAP schedule itself.",
            "VASTAdData embeds a full VAST document inline. vastlint runs the VAST rule chain on embedded creatives and reports paths under AdBreak AdSource VASTAdData. A broken inline VAST makes the break look populated in XML while the player fails as soon as it parses the inner tag.",
            "Empty AdTagURI is an error class of its own: VMAP-1.0-adtaguri-empty fires when CDATA is blank or whitespace. The break exists on the timeline with nothing to fetch. Seller-side fill reports stay flat while the content owner insists the schedule file was delivered."
          ]
        },
        {
          "type": "list",
          "heading": "VMAP checks before you traffic a CTV schedule",
          "items": [
            "Root vmap:VMAP declares version 1.0 and the videosuite namespace URI expected by IAB VMAP 1.0.",
            "Every AdBreak includes timeOffset and breakType; timeOffset matches start, end, hh:mm:ss.mmm, n%, or #m grammar.",
            "Each AdSource has non-empty AdTagURI in CDATA, or valid VASTAdData, or CustomAdData with CDATA where required.",
            "AdTagURI macros use CDATA so expanded query strings with ampersands stay well-formed XML.",
            "templateType on AdTagURI matches the VAST version your ad server actually returns for that placement.",
            "Embedded VAST under VASTAdData passes VAST validation on the same version declared inside the inner root.",
            "Break-level TrackingEvents URLs are HTTPS where the player environment requires TLS."
          ]
        },
        {
          "type": "code",
          "heading": "A VMAP mid-roll the player can fetch",
          "language": "xml",
          "code": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<vmap:VMAP xmlns:vmap=\"http://www.iab.net/videosuite/vmap\" version=\"1.0\">\n  <vmap:AdBreak timeOffset=\"00:10:00.000\" breakType=\"linear\" breakId=\"midroll-1\">\n    <vmap:AdSource id=\"mid-1\" allowMultipleAds=\"true\" followRedirects=\"true\">\n      <vmap:AdTagURI templateType=\"vast4\">\n        <![CDATA[https://ads.example.com/vast?pos=midroll&cb=[CACHEBUSTING]]]>\n      </vmap:AdTagURI>\n    </vmap:AdSource>\n    <vmap:TrackingEvents>\n      <vmap:Tracking event=\"breakStart\"><![CDATA[https://t.example.com/break?id=midroll-1&e=start]]></vmap:Tracking>\n    </vmap:TrackingEvents>\n  </vmap:AdBreak>\n</vmap:VMAP>"
        },
        {
          "type": "paragraphs",
          "heading": "What the player does with that document",
          "paragraphs": [
            "The SDK loads the VMAP, registers the mid-roll at ten minutes of content time, and waits. When the content clock crosses 00:10:00.000 on a linear breakType, it fires breakStart if present, then GETs the AdTagURI with macro expansion applied.",
            "followRedirects true allows Wrapper chains on the VAST response. allowMultipleAds true permits podded VAST inside the break. The VMAP job ends at a successful VAST handoff; quartiles and impressions remain VAST responsibilities.",
            "If templateType says vast4 but the ad server returns a 3.0 root, parser mismatch surfaces as a VAST failure, not a VMAP failure. Keeping templateType honest is part of schedule QA because it sets player expectations before the fetch."
          ]
        },
        {
          "type": "code",
          "heading": "A schedule that validates as XML but never monetizes",
          "language": "xml",
          "code": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<vmap:VMAP xmlns:vmap=\"http://www.iab.net/videosuite/vmap\" version=\"1.0\">\n  <vmap:AdBreak timeOffset=\"10:00\" breakType=\"linear\" breakId=\"midroll-bad\">\n    <vmap:AdSource id=\"mid-empty\" allowMultipleAds=\"false\" followRedirects=\"true\">\n      <vmap:AdTagURI templateType=\"vast4\">\n        <![CDATA[]]>\n      </vmap:AdTagURI>\n    </vmap:AdSource>\n  </vmap:AdBreak>\n</vmap:VMAP>"
        },
        {
          "type": "paragraphs",
          "heading": "Why that shape still passes some QA",
          "paragraphs": [
            "Generic XML validators see a well-formed VMAP with an AdBreak and AdSource tree. timeOffset 10:00 fails VMAP-1.0-adbreak-timeoffset-format because it is not hh:mm:ss.mmm, start, end, a percentage, or #m. Trafficking may have meant ten minutes but wrote a shorthand the spec does not accept.",
            "Empty AdTagURI CDATA triggers VMAP-1.0-adtaguri-empty. The player reaches the break, has no URL to call, and skips monetization. breakStart may never fire because some SDKs only ping tracking after a successful ad source resolution.",
            "Fix order: rewrite timeOffset to 00:10:00.000 or 10% if percentage was intended, paste a live ad tag URL inside CDATA, re-run validation on the exported file from the ad server rather than a hand-edited sample, and test one break on the target player OS before full rotation."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "VMAP versus live cue workflows",
          "paragraphs": [
            "Static VMAP assumes known break positions before playback. Live sports and event streams often generate VMAP per cue with timeOffset set to the current transport timestamp. The same rules apply: empty AdTagURI and bad timeOffset formats break monetization seconds before air.",
            "Do not confuse this check with the live-event integration story. Per-cue generation is an ops pattern; this how-to is the envelope on each generated file. Validate the file the player or stitcher actually receives after cue substitution, not the VOD template in version control.",
            "When SSAI consumes VMAP, confirm the stitched output still contains AdTagURI after any server-side rewrite. Some pipelines strip tracking or swap AdSource ids while leaving timeOffset intact, which looks like a fill problem in logs when the root cause is an empty URI on the stitched copy."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate VMAP before the break reaches the player",
          "paragraph": "Paste a VMAP playlist or fetch the schedule URL. vastlint detects document type, checks timeOffset, AdTagURI, namespace, and embedded VAST on the same rule surface as VAST tags.",
          "href": "/validate/",
          "label": "Open the validator"
        },
        {
          "type": "resources",
          "heading": "Primary references",
          "items": [
            {
              "label": "IAB Tech Lab VMAP standard",
              "href": "https://iabtechlab.com/standards/vmap/",
              "description": "Video Multiple Ad Playlist specification and resources.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "What is VMAP?",
              "href": "/docs/vmap/",
              "description": "AdBreak, timeOffset, AdSource, and VMAP versus VAST on vastlint.org.",
              "source": "Docs"
            },
            {
              "label": "VMAP-1.0-adtaguri-empty",
              "href": "/docs/rules/VMAP-1.0-adtaguri-empty/",
              "description": "Empty AdTagURI prevents the player from fetching VAST for the break.",
              "source": "Rules"
            },
            {
              "label": "VMAP-1.0-adbreak-timeoffset-format",
              "href": "/docs/rules/VMAP-1.0-adbreak-timeoffset-format/",
              "description": "Invalid timeOffset strings leave breaks unscheduled.",
              "source": "Rules"
            }
          ]
        }
      ]
    },
    {
      "slug": "how-to-validate-mezzanine-files",
      "title": "How to Validate Mezzanine Files in VAST Tags",
      "description": "A Mezzanine without delivery, type, width, and height cannot be transcoded by SSAI, so the ready-to-serve rendition never appears.",
      "publishedAt": "2026-09-22",
      "updatedAt": "2026-09-22",
      "author": "Alex Sekowski",
      "readingTime": "12 min read",
      "heroKicker": "SSAI",
      "tags": [
        "Mezzanine",
        "VAST 4.1",
        "SSAI",
        "How-to",
        "CTV"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "A FAST pod can show one hundred percent completion in the ad server while the living-room stream never received a TV-bitrate rendition. Trafficking exported VAST 4.1 with a single 800 kbps MediaFile because that file plays in a desktop preview. The stitcher logged a transcode job. The manifest the Roku pulled still carried a web-sized rung, or nothing at all, because the tag never declared a mezzanine the SSAI pipeline could treat as a master.",
            "The production bug is rarely a stitcher that refuses video on principle. It is a Mezzanine element that is missing, nested wrong, or present without the attributes VAST 4.1 expects: delivery, type, width, and height on the transcode source. Without those fields a quality-aware SSAI stack cannot evaluate the asset before it downloads multi-gigabyte masters, and a permissive stack falls back to recompressing the highest MediaFile, which airs soft next to broadcast content.",
            "IAB Tech Lab added Mezzanine in VAST 4.0 for server-side ad insertion and addressable TV, with VAST 4.1 adding the attribute set stitchers use to filter masters before fetch. This piece is the envelope check on that element: where it lives under Linear MediaFiles, which attributes are required at 4.1+, and what breaks when trafficking treats mezzanine as optional metadata beside a playable MP4."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/how-to-validate-mezzanine-files.png?v=2",
          "alt": "A single low-bitrate MediaFile can pass a desktop preview while a stitcher has no Mezzanine to transcode for the living-room stream.",
          "width": 1440,
          "height": 820,
          "caption": "Playable in preview and usable as a transcode source are different files.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "Why a playable MediaFile is not a mezzanine check",
          "paragraphs": [
            "Buyers reconcile delivery in DSP quartiles. Publishers reconcile stitch success in SSAI logs. Neither dashboard proves the tag handed the stitcher a mastering-quality source. A tag can fire every tracker while the server transcodes from an already lossy 720p file because Mezzanine was absent or hollow.",
            "That split is expensive on CTV because the living-room player and the stitcher read different children under MediaFiles. Players select among MediaFile renditions. Stitchers consume Mezzanine when present, then emit HLS or DASH segments matched to content. Validating only MediaFile bitrate and MIME type on a browser tool misses the hop that actually sets TV quality.",
            "Open programmatic CTV concentrates spend on paths that include SSAI on FAST and broadcaster apps. Mezzanine recommended findings in validators are easy to dismiss as informational until a platform with a hard floor rejects the creative entirely. The trafficking ticket then reads underdelivery while the XML looked green on hop one.",
            "Genre and surface splits make the mistake repeatable. A creative tested on mobile web inventory may never trigger mezzanine rules in QA, then fails on large-screen supply where the spec expects a transcode source. The failure is in the VAST document, not in the bid request headline."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What Mezzanine actually declares",
          "paragraphs": [
            "Mezzanine is not another MediaFile rung for the player to rank. It is the URI to a high-bitrate master meant for server-side transcoding. IAB describes mezzanine files as part of VAST 4 features aimed at delivering video efficiently across devices, including separation of media from verification code and a mezzanine file for server-side ad insertion.",
            "In VAST 4.0 the element can appear as a bare URI under MediaFiles. VAST 4.1 adds delivery, type, width, height, and optional codec, id, fileSize, and mediaType so pipelines can reject unsuitable masters without pulling the file. vastlint treats missing delivery, type, width, or height at 4.1+ as errors on the Mezzanine node itself.",
            "The population that matters is the resolved InLine after wrapper merges and after any SSAI rewrite, not the first wrapper response. A mezzanine on the trafficking export that disappears on the live chain is the same class of failure as UniversalAdId dropped upstream.",
            "Correct players ignore Mezzanine during client-side rendition selection. Misconfigured players that treat every URI under MediaFiles as playable can stall on a file never meant to stream. Validation separates transcode source from playback assets before the tag reaches the stitcher."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where Mezzanine lives in the tag",
          "paragraphs": [
            "For linear video, Mezzanine sits inside Linear Creative MediaFiles as a sibling of MediaFile, not inside TrackingEvents and not on the Wrapper root without a resolved InLine. VAST 2.x used Extension type mezzanine under InLine with a separate CreativeId tie; 4.x nests under the creative that will play.",
            "Each Mezzanine carries a CDATA-wrapped HTTPS URL to the master. delivery distinguishes progressive download from streaming protocols on the master itself. type names the container MIME type. width and height name native pixel dimensions of the source file, which stitchers use to decide whether the master matches 1080p or UHD ladders.",
            "Optional fileSize helps pipelines skip downloads when duration and bitrate math already prove the asset cannot meet policy. Optional codec follows RFC 4281 values. None of these fields execute at ad-server response time beyond XML parsing; the stitcher reads them when it plans transcode jobs.",
            "When multiple creatives share one tag, each mezzanine must associate with the correct Linear creative. Under 2.x extensions that means CreativeId matching the Creative id attribute. Under 4.x the nesting under the correct Creative subtree is the association mechanism."
          ]
        },
        {
          "type": "list",
          "heading": "Mezzanine checks to run before SSAI launch",
          "items": [
            "Declared VAST version is 4.0+ when Mezzanine is present; 4.1+ tags include delivery, type, width, and height on Mezzanine.",
            "Mezzanine URI is non-empty HTTPS and parses as a valid URI.",
            "At least one TV-oriented MediaFile remains for players after stitch; mezzanine alone is not a playback plan.",
            "Unwrapped live chain still contains the same Mezzanine subtree as the trafficking export.",
            "Width and height on Mezzanine match the actual master, not a downscaled MediaFile dimension copied by mistake.",
            "type reflects video/mp4 or the container you upload; mismatched MIME types confuse stitcher prefetch.",
            "Wrapper depth review: mezzanine on hop one but missing on merged InLine means stitch never saw the master."
          ]
        },
        {
          "type": "code",
          "heading": "A Mezzanine block SSAI can evaluate",
          "language": "xml",
          "code": "<MediaFiles>\n  <Mezzanine delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\"\n             codec=\"h264\" fileSize=\"850000000\">\n    <![CDATA[https://cdn.example.com/masters/spot-30s-1080p-master.mp4]]>\n  </Mezzanine>\n  <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\" bitrate=\"8000\">\n    <![CDATA[https://cdn.example.com/renditions/spot-30s-1080p.mp4]]>\n  </MediaFile>\n</MediaFiles>"
        },
        {
          "type": "paragraphs",
          "heading": "What the stitcher does with that envelope",
          "paragraphs": [
            "After the InLine resolves, the SSAI pipeline reads Mezzanine attributes before it commits to a transcode. delivery progressive signals HTTP-friendly master fetch. type and codec tell the job planner which decoder path to open. width and height set the output ladder targets relative to content.",
            "The sibling MediaFile remains the fallback preview and sometimes the only asset on client-side paths. On SSAI inventory the stitcher may never expose the mezzanine URL to the device; it emits segmented media aligned to the channel manifest. A valid Mezzanine block therefore declares intent and constraints, not guaranteed glass quality.",
            "If fileSize is present and implausibly small for the declared resolution, some platforms still attempt transcode and fail mid-job, which surfaces as VAST error 403 or silent refill depending on the seller. Attribute coherence is how you catch masters mis-labeled before match day."
          ]
        },
        {
          "type": "code",
          "heading": "A Mezzanine that will fail 4.1 attribute rules",
          "language": "xml",
          "code": "<MediaFiles>\n  <Mezzanine>\n    <![CDATA[https://cdn.example.com/masters/spot-30s.mp4]]>\n  </Mezzanine>\n  <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1280\" height=\"720\" bitrate=\"1500\">\n    <![CDATA[https://cdn.example.com/renditions/spot-30s-720p.mp4]]>\n  </MediaFile>\n</MediaFiles>"
        },
        {
          "type": "paragraphs",
          "heading": "Why that shape still passes some previews",
          "paragraphs": [
            "A bare Mezzanine URI mirrors VAST 4.0 shape and looks acceptable to schema tools that do not version-gate attributes. At 4.1+ the same node triggers missing delivery, type, width, and height findings because the stitcher cannot classify the master without them.",
            "The 720p MediaFile plays in a browser validator, so trafficking assumes the tag is CTV-ready. SSAI then either rejects the creative for missing mezzanine metadata or transcodes from the 720p rung, which is the soft-ad failure mode next to pristine content.",
            "Fix order: add required 4.1 attributes on Mezzanine, confirm the master URL returns 200 with the declared MIME type, re-run validation on the unwrapped InLine, and paste the live ad tag URL after redirects the player will see."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Mezzanine versus recommended-only findings",
          "paragraphs": [
            "vastlint flags missing Mezzanine at info severity on 4.1+ tags where MediaFiles exist but no transcode source is declared. Treat that as a SSAI readiness signal on FAST and broadcaster paths, not as decoration for browser-only campaigns.",
            "Separate rules fire when Mezzanine attributes contradict MediaFile typing, when HTTPS policy fails on the master URL, or when version declares 3.0 while 4.x-only children are present. Together they approximate the four-part readiness bar ops teams use before caching creatives for live pods.",
            "Validation cannot download every master, verify GOP alignment, or prove the stitcher honored fileSize. It catches XML incoherence that guarantees transcode failure or quality collapse before the creative enters rotation."
          ]
        },
        {
          "type": "list",
          "heading": "Pre-launch mezzanine checklist",
          "items": [
            "Confirm VAST version on the resolved InLine matches mezzanine rules you enforce.",
            "Require delivery, type, width, and height on every 4.1+ Mezzanine before SSAI cache.",
            "Compare mezzanine dimensions to uploaded master probes, not to compressed rungs.",
            "Inspect wrapper merges for dropped Mezzanine while Impression nodes survive.",
            "Pair mezzanine validation with MediaFile codec checks for dominant CTV OS targets.",
            "Re-test after any downgrade export to 2.x or 3.x compatibility templates."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate Mezzanine on production VAST tags",
          "paragraph": "Paste a tag or fetch a live URL. vastlint checks Mezzanine placement, 4.1 attributes, HTTPS URIs, and version coherence on the unwrapped chain.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "IAB VAST standard",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST 4.0 mezzanine for server-side ad insertion; VAST 4.1 attribute requirements.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "What is a Mezzanine file?",
              "href": "/docs/mezzanine/",
              "description": "SSAI transcode source versus playable MediaFiles.",
              "source": "Docs"
            },
            {
              "label": "VAST-4.1-mezzanine-delivery",
              "href": "/docs/rules/VAST-4.1-mezzanine-delivery/",
              "description": "Missing delivery on Mezzanine at VAST 4.1+.",
              "source": "Rules"
            },
            {
              "label": "VAST-4.1-mezzanine-recommended",
              "href": "/docs/rules/VAST-4.1-mezzanine-recommended/",
              "description": "No Mezzanine on a 4.1 tag may be rejected in CTV and SSAI contexts.",
              "source": "Rules"
            }
          ]
        }
      ]
    },
    {
      "slug": "how-to-validate-viewableimpression",
      "title": "How to Validate ViewableImpression in VAST Tags",
      "description": "ViewableImpression URLs that are empty or HTTP-only fail the viewability join even when quartiles fire.",
      "publishedAt": "2026-09-19",
      "updatedAt": "2026-09-26",
      "author": "Alex Sekowski",
      "readingTime": "11 min read",
      "heroKicker": "Viewability",
      "tags": [
        "ViewableImpression",
        "VAST 4.0",
        "Viewability",
        "How-to",
        "CTV"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "A CTV line item can show one hundred percent quartile completion in the DSP while the viewability vendor reports undetermined on the same impressions. The trafficking export lists ViewableImpression because someone migrated the tag to VAST 4.0. The player fired start, firstQuartile, midpoint, thirdQuartile, and complete on schedule. The viewability dashboard stayed flat because the URLs that were supposed to carry the MRC-style state never executed.",
            "The production bug is rarely a player that refuses to measure viewability on principle. It is a ViewableImpression subtree that exists in XML but cannot complete the join: empty CDATA inside Viewable, NotViewable, or ViewUndetermined, HTTP-only asset hosts on HTTPS-only CTV apps, creative tracking pasted under ViewableImpression where the schema allows only the three viewability children, or a wrapper chain that drops the block while quartile TrackingEvents survive on the merged InLine.",
            "IAB Tech Lab introduced ViewableImpression in VAST 4.0 as a dedicated container for viewability-state beacons, separate from the standard Impression URL and separate from quartile TrackingEvents. VAST 4.3 refined semantics and wrapper-chain handling for server-side insertion environments. This piece is the envelope check: where ViewableImpression lives, which child URLs must be fetchable before a player or measurement script can classify an impression, and what validation can catch while linear video still plays normally. It is not a substitute for OMID; AdVerifications remains the path for third-party viewability scripts."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/how-to-validate-viewableimpression.png?v=2",
          "alt": "Quartile tracking events can all fire while ViewableImpression URLs are empty, so completion is 100 percent and viewability stays undetermined.",
          "width": 1440,
          "height": 820,
          "caption": "A full quartile set is not evidence that half the pixels were in view.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "Why hollow viewability beacons look like a player bug",
          "paragraphs": [
            "Buyers reconcile viewability in a different pipeline than delivery. DSP and ad-server dashboards count starts and completes. Viewability vendors and in-house MRC-style reports count Viewable, NotViewable, and ViewUndetermined firings against their thresholds. When only quartiles arrive, delivery looks healthy and viewability looks broken, which sends engineers to firmware and SDK release notes before anyone pastes the resolved VAST.",
            "That delay is expensive because quartile URLs and viewability URLs share the same trafficking template in many tools. A generator that copies the complete beacon into TrackingEvents and leaves ViewableImpression as an empty placeholder satisfies a spreadsheet column named viewability without giving the player anything to ping when OMID is absent.",
            "SSAI paths make the gap worse. Stitchers that rebuild InLine from MediaFiles and Impression often preserve quartile TrackingEvents because those URLs are wired into transcode and pod timing. ViewableImpression is easier to drop as optional metadata from an upstream wrapper. The living-room device plays the spot and fires completes while the viewability join never receives a non-empty HTTPS URL.",
            "Open auction metadata does not rescue the join. Sellers expose viewability measurement in deal notes or verification product flags while the VAST the player resolves carries ViewableImpression with blank children. The buy looked measured. The classification pipeline had nothing to classify."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What ViewableImpression actually measures",
          "paragraphs": [
            "ViewableImpression is not the [impression pixel](https://pixellint.org/docs/vast-tracking-events-are-pixels/). The InLine Impression element fires on load or on a player-defined threshold that may or may not align with MRC viewability rules. ViewableImpression holds up to three optional child URLs, Viewable, NotViewable, and ViewUndetermined, that fire when the player or an integrated measurement layer decides which state applies.",
            "Quartile TrackingEvents measure media progress against Duration. They do not prove that fifty percent of pixels were in view for two continuous seconds. A tag can fire midpoint on a minimized outstream unit or on a CTV panel where the ad rendered off-screen. ViewableImpression is where the document declares separate endpoints for viewability classification, when the stack implements VAST 4.x viewability semantics at all.",
            "The population that matters for QA is the resolved InLine the player parses after redirects and after SSAI, not the first wrapper hop and not the trafficking PDF. Validating ViewableImpression on hop one while the final chain omits the block is the same category error as validating UniversalAdId only on the entry URL.",
            "OMID AdVerifications can run parallel to ViewableImpression or replace reliance on the three child URLs entirely, depending on the verification vendor and player. Many CTV stacks prefer OMID for third-party viewability while still accepting ViewableImpression for legacy server-side classification. Empty ViewableImpression plus missing AdVerifications leaves you with quartiles only, which is the failure mode this check targets."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where ViewableImpression lives and what the player reads",
          "paragraphs": [
            "In typical VAST 4.x linear traffic, ViewableImpression sits at InLine level alongside Impression, Error, Creatives, and Extensions, not inside Linear TrackingEvents. That placement matters because players walk different trees for creative progress beacons versus ad-level viewability containers. Pasting a Tracking event under ViewableImpression violates the schema and can cause strict parsers to reject the entire block.",
            "Each allowed child is a URI element: CDATA holds the HTTPS URL the player or measurement layer should request when the corresponding viewability state is determined. Viewable fires when the ad meets the implemented viewability definition. NotViewable fires when measurement completes and the ad did not qualify. ViewUndetermined fires when the environment cannot decide, which is common on SSAI-only paths without client-side confirmation.",
            "The optional id attribute on ViewableImpression helps when multiple viewability vendors appear in one document. Duplicate ids or duplicate Viewable URLs across wrapper hops can double-count in downstream logs if the player merges chains naively. VAST 4.3 guidance emphasizes clearer wrapper handling; operational QA still needs the merged view the device will see.",
            "Nothing in ViewableImpression executes at ad-server response time beyond XML parsing. The player selects MediaFile, begins playback, evaluates viewability through OMID or native APIs if present, and then fires the appropriate child URL. If every child is empty or uses HTTP on a secure app, most stacks skip the viewability join silently and continue firing quartiles."
          ]
        },
        {
          "type": "list",
          "heading": "What ViewableImpression validation can catch before playback",
          "items": [
            "ViewableImpression containing anything other than Viewable, NotViewable, and ViewUndetermined.",
            "Empty CDATA on any populated viewability child (VAST-2.0-url-empty class findings on URI fields).",
            "HTTP viewability beacon URLs on HTTPS-only CTV inventory.",
            "Malformed URLs that fail URI parsing while quartile TrackingEvents on the same Linear still look valid.",
            "ViewableImpression present on the trafficking export but absent on the unwrapped live InLine or post-SSAI output.",
            "Viewability children present but every URL blank while Impression and complete still fire (spreadsheet false positive).",
            "Creative TrackingEvents mistakenly nested under ViewableImpression instead of Linear TrackingEvents."
          ]
        },
        {
          "type": "code",
          "heading": "A ViewableImpression block that should pass validation",
          "language": "xml",
          "code": "<InLine>\n  <Impression><![CDATA[https://track.example.com/impression]]></Impression>\n  <ViewableImpression id=\"viewability-vendor-a\">\n    <Viewable><![CDATA[https://track.example.com/viewable]]></Viewable>\n    <NotViewable><![CDATA[https://track.example.com/not-viewable]]></NotViewable>\n    <ViewUndetermined><![CDATA[https://track.example.com/undetermined]]></ViewUndetermined>\n  </ViewableImpression>\n  <Creatives>\n    <Creative>\n      <Linear>\n        <Duration>00:00:30</Duration>\n        <TrackingEvents>\n          <Tracking event=\"complete\"><![CDATA[https://track.example.com/complete]]></Tracking>\n        </TrackingEvents>\n      </Linear>\n    </Creative>\n  </Creatives>\n</InLine>"
        },
        {
          "type": "paragraphs",
          "heading": "What a player does with that viewability envelope",
          "paragraphs": [
            "After the InLine resolves, the player fires Impression according to its own rules, starts linear playback, and evaluates viewability through OMID verification scripts and/or native viewability APIs where implemented. When classification completes, it requests the matching Viewable, NotViewable, or ViewUndetermined URL.",
            "Quartile and complete TrackingEvents on Linear proceed independently. A valid ViewableImpression block does not guarantee MRC-compliant numbers on every device; it guarantees the tag declared fetchable endpoints for the three states the VAST 4.x model expects.",
            "If all three child URLs are non-empty HTTPS endpoints, downstream vendors can still disagree on counts when wrapper merges duplicate beacons or when SSAI fires server-side impressions without client confirmation. Envelope validation proves the document handed the stack a complete viewability contract in XML shape; it does not prove agreement between verification vendors."
          ]
        },
        {
          "type": "code",
          "heading": "A ViewableImpression block that lists viewability but should be flagged",
          "language": "xml",
          "code": "<ViewableImpression id=\"vi1\">\n  <Viewable><![CDATA[]]></Viewable>\n  <NotViewable><![CDATA[http://track.example.com/not-viewable]]></NotViewable>\n  <Tracking event=\"viewable\">\n    <![CDATA[https://track.example.com/wrong-node]]>\n  </Tracking>\n</ViewableImpression>"
        },
        {
          "type": "paragraphs",
          "heading": "Why that block still looks compliant in a spreadsheet",
          "paragraphs": [
            "Trafficking exports often reduce viewability to a yes/no column: ViewableImpression present. The container exists and id is set, so the row looks migrated to VAST 4.0. Viewable CDATA is empty, so the primary state beacon has nothing to fetch even if the player implements native viewability.",
            "NotViewable uses HTTP, which mixed-content rules block on many HTTPS CTV apps. The stray Tracking node under ViewableImpression is not a valid child; parsers that strict-reject the container drop the entire block, including the partially valid NotViewable entry, while Linear TrackingEvents elsewhere in the document continue to fire.",
            "Fix order: move creative tracking back under Linear TrackingEvents, require non-empty HTTPS URIs on each viewability child you intend to use, remove unknown children, and re-run validation on the unwrapped InLine the player will see after SSAI."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "ViewableImpression versus OMID and SSAI",
          "paragraphs": [
            "MRC viewability on CTV often depends on OMID AdVerifications or on vendor SDKs embedded in the app, not on VAST child URLs alone. SSAI guidance from measurement bodies stresses that server-fired beacons cannot confirm viewability the way client-side confirmation can, which is why client beacons remain recommended even under stitchers.",
            "ViewableImpression still matters for stacks that map native viewability results to the three URLs without loading a full verification script, and for legacy integrations that never adopted AdVerifications. Validating the container catches the case where someone added the 4.0 element for compliance optics but left every URL blank.",
            "Do not treat a passing ViewableImpression check as OMID readiness. JavaScriptResource under Verification carries apiFramework omid, vendor codes, and executable URLs. That hop is documented in the AdVerifications how-to. This hop is the simpler tri-state beacon envelope."
          ]
        },
        {
          "type": "list",
          "heading": "A pre-launch ViewableImpression checklist",
          "items": [
            "Declared VAST version is 4.0+ and ViewableImpression sits at InLine level on the document the player resolves.",
            "Each viewability child you rely on has non-empty HTTPS CDATA and parses as a valid URI.",
            "ViewableImpression contains only Viewable, NotViewable, and ViewUndetermined; quartile beacons stay under Linear TrackingEvents.",
            "The unwrapped live chain, including post-SSAI output, still contains the same ViewableImpression subtree as the trafficking export.",
            "If the buy requires third-party viewability, AdVerifications is present and OMID-capable, not only empty ViewableImpression placeholders.",
            "Wrapper merge review: duplicate Viewable URLs across hops are intentional or deduped in player config.",
            "Compare viewability vendor logs against resolved VAST when quartiles fire but viewability stays undetermined."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What viewability envelope validation cannot prove",
          "paragraphs": [
            "A valid ViewableImpression block is necessary, not sufficient. XML checks do not download every beacon, confirm MRC thresholds on each CTV firmware build, or prove OMID scripts executed. They will not catch a stitcher that removes ViewableImpression after you validated the upstream chain.",
            "They also will not replace vendor-side reconciliation when Impression fires from the ad server while viewability fires from the client. Timing skew between those hops is a measurement design problem, not something URI validation resolves.",
            "If complete fires and viewability still reports undetermined, compare the resolved InLine against the trafficking export. If the video never starts, fix MediaFiles first. If the video plays and ViewableImpression is absent or hollow on the live chain, this checklist is the one."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate ViewableImpression in your VAST tag",
          "paragraph": "Paste a tag or fetch a live URL. vastlint checks ViewableImpression shape, URI fields, and allowed children on the unwrapped chain before launch.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "IAB VAST standard",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST 4.0 ViewableImpression for viewability-state tracking URLs.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VAST-4.0-viewableimpression-unknown-child",
              "href": "/docs/rules/VAST-4.0-viewableimpression-unknown-child/",
              "description": "ViewableImpression may only contain Viewable, NotViewable, and ViewUndetermined.",
              "source": "Rules"
            },
            {
              "label": "VAST-2.0-url-empty",
              "href": "/docs/rules/VAST-2.0-url-empty/",
              "description": "Empty URI fields on viewability children fail silently at fetch time.",
              "source": "Rules"
            },
            {
              "label": "VAST 3.0 to 4.0 migration",
              "href": "/docs/vast-3-to-4/",
              "description": "ViewableImpression introduction and example tri-state beacons.",
              "source": "Docs"
            }
          ]
        }
      ]
    },
    {
      "slug": "how-to-validate-closed-captions-in-vast",
      "title": "How to Validate Closed Captions in VAST Tags",
      "description": "ClosedCaptionFiles with an empty URL or a non-caption MIME type leave CTV inventory looking captioned in the bid while the player has nothing to render.",
      "publishedAt": "2026-09-16",
      "updatedAt": "2026-09-16",
      "author": "Alex Sekowski",
      "readingTime": "12 min read",
      "heroKicker": "Accessibility",
      "tags": [
        "Closed captions",
        "VAST 4.1",
        "MediaFiles",
        "How-to",
        "CTV"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "A CTV pod can complete every quartile, pass viewability, and still ship zero captions on the glass. The trafficking sheet says CC: yes because someone checked a box when the creative uploaded. The buyer's accessibility review assumes WebVTT or TTML arrived with the MediaFile. The seller's player logs a completed view. None of those dashboards inspect whether ClosedCaptionFile CDATA resolves to a fetchable track.",
            "The production bug is rarely a player that refuses captions on principle. It is a ClosedCaptionFiles subtree that exists in XML but cannot render: an empty URI inside ClosedCaptionFile, a type attribute that names video/mp4 instead of text/vtt, language missing on a multilingual pod, or ClosedCaptionFiles copied on the trafficking export but stripped by SSAI before the living-room device parses the InLine.",
            "IAB Tech Lab added ClosedCaptionFiles under MediaFiles in VAST 4.1 as an accessibility container for sidecar caption tracks. VAST 4.2 tightened MediaFiles child rules and VAST 4.4 extends the same container to NonLinear MediaFiles. This piece is the envelope check: where captions live, which attributes must be present before a CTV SDK fetches a track, and what validation can catch while linear video still plays normally."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/how-to-validate-closed-captions-in-vast.png?v=2",
          "alt": "A CTV pod can complete every quartile while ClosedCaptionFile has an empty URL or a non-caption MIME type, so the glass never gets a track.",
          "width": 1440,
          "height": 820,
          "caption": "Completed views do not inspect whether a caption URL resolves.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "Why hollow captions are a compliance and reach problem",
          "paragraphs": [
            "Regulated and brand-led CTV buys increasingly treat captions as part of the creative contract, not a post-production nice-to-have. When the track never loads, the campaign can be out of policy with the publisher or the advertiser's accessibility checklist even though delivery metrics look fine. Support tickets arrive after manual review on one device model shows no CC button or no visible text during dialogue.",
            "That delay is expensive because nobody reconciles caption presence in the same pipeline as quartile completion. DSP dashboards count impressions. Publisher ad servers count starts and completes. SSAI logs transcode success on the mezzanine or the highest MediaFile rung. None of those signals prove ClosedCaptionFile returned 200 with a caption MIME type.",
            "Open auction metadata makes the gap worse. Sellers expose accessibility or language flags in deal notes, ad server UI, or downstream OpenRTB extensions while the VAST the player resolves carries ClosedCaptionFiles with placeholder URLs copied from a template. The bid looked captioned. The rendered pod did not.",
            "Wrapper chains and stitchers compound silent loss. Captions can sit under MediaFiles inside an InLine three redirects deep. QA that validates hop one sees ClosedCaptionFiles and assumes compliance. The final InLine the player resolves under timeout may have dropped the entire container when an intermediary flattened the document for latency."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What ClosedCaptionFiles actually carries",
          "paragraphs": [
            "ClosedCaptionFiles is a sibling of MediaFile, Mezzanine, and InteractiveCreativeFile inside Linear MediaFiles (and, in VAST 4.4 portfolio work, under NonLinear MediaFiles as well). The XSD allows one or more ClosedCaptionFile children. Each ClosedCaptionFile is a URI element: CDATA holds the HTTPS URL to the sidecar track, not embedded caption text.",
            "The type attribute identifies the MIME type of the caption file. Production examples use text/vtt for WebVTT, application/ttml+xml for TTML, or other text-based caption formats the player supports. Treating type as optional in generators is a mistake on 4.4 schema work where type is required on ClosedCaptionFile: players use type to decide whether to attempt a fetch before showing the CC affordance.",
            "The language attribute uses ISO 639-1 codes with an optional locale suffix per VAST 4.2 XSD documentation. Omitting language on a single-track ad is survivable on some SDKs. Omitting it on multi-language pods means the player cannot match the viewer's UI language to the correct ClosedCaptionFile when several siblings are present.",
            "Nothing in ClosedCaptionFiles executes at ad-server response time beyond XML parsing. The player selects a MediaFile, begins decode, and optionally fetches one or more ClosedCaptionFile URIs to mux text into the render pipeline or expose a system caption track. If the URI is empty or the MIME type does not match bytes on the wire, most stacks skip captions silently and continue linear playback."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where to validate: wrapper depth and post-SSAI output",
          "paragraphs": [
            "Operational QA should mirror how the player resolves the chain. Paste or fetch the entry URL, follow VASTAdTagURI redirects until you hold the InLine the device will parse, and validate ClosedCaptionFiles on that merged view. A green first hop plus missing captions on the final InLine is the same category error as validating Duration only on hop one.",
            "For SSAI, validate the document the device receives after stitching, not only the pre-stitch asset in the creative library. Stitchers that rebuild InLine from MediaFiles alone often omit ClosedCaptionFiles even when the upstream chain included them. The living-room player never sees the caption contract the trafficker exported.",
            "Version declarations matter. ClosedCaptionFiles under MediaFiles requires VAST 4.1 or later. Feeds that declare 2.0 or 3.0 while injecting ClosedCaptionFiles rely on lenient parsers. Strict CTV SDKs ignore unknown 4.x children on older version strings, which looks like captioned trafficking with no CC at playback.",
            "Bid-side reviewers who only read OpenRTB video fields never see ClosedCaptionFiles at all. Caption assurance belongs on the VAST hop after the win, the same place you validate MediaFile HTTPS and tracking consistency."
          ]
        },
        {
          "type": "list",
          "heading": "What caption validation can catch before playback",
          "items": [
            "ClosedCaptionFiles containing anything other than ClosedCaptionFile elements.",
            "ClosedCaptionFile with empty CDATA URL (VAST-2.0-url-empty class findings on URI fields).",
            "Missing or incorrect type when the declared VAST version requires MIME on ClosedCaptionFile.",
            "HTTP caption asset URLs on HTTPS-only CTV inventory.",
            "language absent when multiple ClosedCaptionFile siblings target different locales.",
            "ClosedCaptionFiles present on the trafficking export but absent on the unwrapped live InLine or post-SSAI output.",
            "type naming a video MIME while CDATA points at a sidecar caption path (player may never invoke the caption loader)."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "MIME type and empty URL failures in practice",
          "paragraphs": [
            "Trafficking tools sometimes copy the MediaFile type attribute into ClosedCaptionFile because both live under MediaFiles. A ClosedCaptionFile typed video/mp4 with a .vtt URL is internally inconsistent: the player may classify the track as video and refuse to parse cues.",
            "Empty CDATA is worse because schema validators and lenient parsers disagree. Some SDKs treat empty ClosedCaptionFile as absent. Others allocate a caption slot, attempt fetch against an empty string, fail without surfacing an error code, and leave the CC toggle visible but inert.",
            "Sidecar captions are not burned-in video. If the only caption artifact is a soft subtitle inside the mezzanine MP4 and ClosedCaptionFiles is empty, accessibility reviewers watching the exported MP4 in desktop tools see text while CTV players that expect sidecar WebVTT see nothing. Validation separates sidecar contract from baked-in pixels."
          ]
        },
        {
          "type": "code",
          "heading": "A ClosedCaptionFiles block that should pass validation",
          "language": "xml",
          "code": "<MediaFiles>\n  <ClosedCaptionFiles>\n    <ClosedCaptionFile type=\"text/vtt\" language=\"en\">\n      <![CDATA[https://cdn.example.com/spot-en.vtt]]>\n    </ClosedCaptionFile>\n    <ClosedCaptionFile type=\"text/vtt\" language=\"es\">\n      <![CDATA[https://cdn.example.com/spot-es.vtt]]>\n    </ClosedCaptionFile>\n  </ClosedCaptionFiles>\n  <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\">\n    <![CDATA[https://cdn.example.com/spot.mp4]]>\n  </MediaFile>\n</MediaFiles>"
        },
        {
          "type": "paragraphs",
          "heading": "What a player does with that caption envelope",
          "paragraphs": [
            "After Linear resolves, the player reads MediaFiles, chooses a MediaFile rung, and inspects ClosedCaptionFiles before or during startup depending on the SDK. For each ClosedCaptionFile it records type and language, fetches the CDATA URL, and attaches the parsed cues to the render surface or exposes them through the system caption API.",
            "If both language siblings return 200 with valid WebVTT, the viewer can switch EN and ES where the app supports multi-track selection. The video decode path is unchanged: captions ride alongside MediaFile bytes rather than replacing them.",
            "If every field in the passing example is present, captions still might not appear on a given CTV device because the SDK ignores ClosedCaptionFiles on that firmware build or because the app hides CC when the stream declares embedded captions elsewhere. Envelope validation proves the tag handed the player a complete sidecar contract in the shape VAST expects; it does not prove pixel-perfect rendering on every panel."
          ]
        },
        {
          "type": "code",
          "heading": "A ClosedCaptionFiles block that lists captions but should be flagged",
          "language": "xml",
          "code": "<ClosedCaptionFiles>\n  <ClosedCaptionFile type=\"video/mp4\" language=\"en\">\n    <![CDATA[]]>\n  </ClosedCaptionFile>\n  <ClosedCaptionFile language=\"en\">\n    <![CDATA[http://cdn.example.com/captions.vtt]]>\n  </ClosedCaptionFile>\n  <Tracking event=\"start\">\n    <![CDATA[https://track.example.com/start]]>\n  </Tracking>\n</ClosedCaptionFiles>"
        },
        {
          "type": "paragraphs",
          "heading": "Why that block still looks compliant in a spreadsheet",
          "paragraphs": [
            "Trafficking exports often reduce captions to a yes/no column: ClosedCaptionFiles present. The first ClosedCaptionFile declares language en and type video/mp4, so the row looks populated while the MIME type tells the player not to treat the resource as a text track. The CDATA is empty, so there is nothing to fetch even if type were corrected.",
            "The second ClosedCaptionFile points at a plausible .vtt path but uses HTTP and omits type on versions that require it. Mixed-content rules block many HTTPS CTV apps from fetching the track. The stray Tracking node under ClosedCaptionFiles is not a valid child; parsers that strict-reject the container drop the entire block, including any partially valid ClosedCaptionFile entries.",
            "Fix order: non-empty HTTPS URIs, caption MIME types on type, language on each sibling, move creative tracking back under Linear TrackingEvents, and re-run validation on the unwrapped InLine the player will see."
          ]
        },
        {
          "type": "list",
          "heading": "A pre-launch closed-caption checklist",
          "items": [
            "Declared VAST version is 4.1+ and ClosedCaptionFiles sits under MediaFiles on the InLine the player resolves.",
            "Every ClosedCaptionFile has non-empty HTTPS CDATA and a caption MIME type in type.",
            "language is set when multiple ClosedCaptionFile siblings exist or when the buy specifies locale.",
            "The unwrapped live chain, including post-SSAI output, still contains the same ClosedCaptionFiles subtree as the trafficking export.",
            "curl -sI each caption URL returns 200 with a text-compatible Content-Type.",
            "ClosedCaptionFiles contains only ClosedCaptionFile children.",
            "Caption sidecar presence is not inferred from burned-in video inside MediaFile alone."
          ]
        },
        {
          "type": "code",
          "heading": "Use the CLI when hollow captions should block launch",
          "language": "sh",
          "code": "vastlint check tag.xml --format json\n\nvastlint check tag.xml --fail-on-warning\n\nvastlint check \"https://ad.example.com/vast?cid=9001\" --unwrap"
        },
        {
          "type": "paragraphs",
          "heading": "What caption validation cannot prove",
          "paragraphs": [
            "A valid ClosedCaptionFiles envelope is necessary, not sufficient. XML checks do not download every WebVTT, verify cue timing against the mezzanine, or confirm the CTV SDK implements sidecar captions on that firmware. They will not catch a stitcher that removes ClosedCaptionFiles after you validated the upstream chain.",
            "They also will not replace manual CC review on reference devices. Some players render captions only on web and ignore ClosedCaptionFiles on native CTV even when the XML passes. Session logs from those SDKs rarely mention captions; they simply never attach a text track.",
            "If quartiles fire and accessibility still reports missing captions, compare the resolved InLine against the trafficking export. If the video never starts, fix MediaFiles first. If the video plays and ClosedCaptionFiles is absent or hollow on the live chain, this checklist is the one."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate closed captions in your VAST tag",
          "paragraph": "Paste a tag or fetch a live URL. vastlint checks ClosedCaptionFiles shape, URI fields, and container rules on the unwrapped chain before launch.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "IAB VAST standard",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST 4.1+ ClosedCaptionFiles under MediaFiles for sidecar caption tracks.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VAST-4.2-closedcaptionfiles-unknown-child",
              "href": "/docs/rules/VAST-4.2-closedcaptionfiles-unknown-child/",
              "description": "ClosedCaptionFiles may only contain ClosedCaptionFile elements.",
              "source": "Rules"
            },
            {
              "label": "VAST-2.0-url-empty",
              "href": "/docs/rules/VAST-2.0-url-empty/",
              "description": "Empty URI fields on ClosedCaptionFile CDATA fail silently at fetch time.",
              "source": "Rules"
            },
            {
              "label": "VAST 4.0 to 4.1 migration",
              "href": "/docs/vast-4-to-4-1/",
              "description": "ClosedCaptionFiles introduction and example WebVTT sidecar.",
              "source": "Docs"
            }
          ]
        }
      ]
    },
    {
      "slug": "how-to-validate-vast-icons",
      "title": "How to Validate VAST Icons",
      "description": "An Icon without program, height, width, position, and a renderable resource never appears on CTV, so AdChoices and why-this-ad overlays fail silently while the spot still plays.",
      "publishedAt": "2026-09-13",
      "updatedAt": "2026-09-26",
      "author": "Alex Sekowski",
      "readingTime": "11 min read",
      "heroKicker": "Industry icons",
      "tags": [
        "Icons",
        "AdChoices",
        "VAST 3.0",
        "How-to",
        "CTV"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "A CTV pod can deliver a clean :15, fire every quartile, and still ship zero visible disclosure. The buyer's compliance review assumes AdChoices appeared because the trafficking sheet says Icons: yes. The seller's player logs a completed view. Neither dashboard names the overlay that never rendered, because the linear MediaFile played and the impression pixel fired on schedule.",
            "The usual production bug is not a missing DAA browser extension on the living-room device. It is an Icon element that exists in the XML but cannot be drawn: program missing so the player does not know which overlay slot to fill, width and height absent so layout math fails, xPosition and yPosition empty so the badge lands off-screen or defaults unpredictably, or a StaticResource with an empty CDATA body so there is metadata but no fetchable image.",
            "IAB Tech Lab introduced Icons under Linear in VAST 3.0 so ad servers could ship industry overlays (AdChoices, why-this-ad, custom program badges) inside the same document as the creative. VAST 4.4 draft work extends Icons to NonLinearAds for pause and portfolio formats. This piece is the container check: where Icons lives, which attributes must be present before any CTV SDK paints pixels, and what validation can catch while the video still plays normally."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/how-to-validate-vast-icons.png?v=2",
          "alt": "A linear ad can complete and fire an impression while the Icon is missing a program or has an empty resource, so no disclosure overlay renders.",
          "width": 1440,
          "height": 820,
          "caption": "The media file playing does not mean the icon rendered.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "Why a silent icon failure is a compliance and revenue problem",
          "paragraphs": [
            "Self-regulatory programs treat visible AdChoices as part of the buy, not a creative nice-to-have. When the badge never renders, the campaign can be out of policy with the publisher and the program even though delivery metrics look fine. Support tickets arrive weeks later when a manual screen capture on one device model shows no triangle in the corner.",
            "That delay is expensive because nobody reconciles icon presence in the same pipeline as quartile completion. DSP dashboards count impressions. Publisher ad servers count starts and completes. Neither side tracks whether Icons resolved to a bitmap on the glass. The failure mode looks like a player bug until someone pastes the VAST and notices the Icon block is hollow.",
            "SSAI stitchers compound the problem. Many templates copy MediaFiles and Impression faithfully and treat Icons as optional decoration from an upstream era. The stitched InLine the device receives may declare version 4.2 while omitting the Icons subtree that lived on the pre-stitch Linear. The spot transcodes and plays. The disclosure overlay from the trafficking export never reaches the player parser.",
            "Wrapper chains create the same invisible loss. Icons can sit on Linear inside an InLine three redirects deep. QA that validates hop one sees an Icon with program AdChoices and assumes compliance. The final InLine the player resolves under timeout may have dropped Icons when an intermediary flattened the document to VAST 2.0 shape for latency."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What Icons actually carries in the document",
          "paragraphs": [
            "Icons is a container under Linear (and, in VAST 4.4 draft guidance, under NonLinearAds for pause-style units). It holds one or more Icon children. Each Icon names its purpose with program (commonly AdChoices), declares width and height in pixels for layout, and pins placement with xPosition and yPosition, which accept keywords like left, right, top, bottom or numeric offsets per the schema.",
            "Optional duration and offset attributes tell the player how long the overlay stays visible and when it enters relative to the linear timeline. Without them, behavior is player-defined: some SDKs show the badge for the full ad, others hide it after a few seconds, and QA across devices diverges even when the XML is identical.",
            "The Icon is not the image. Like Companion and NonLinear, it must wrap a renderable resource: StaticResource for PNG and GIF badges, IFrameResource or HTMLResource for markup-heavy disclosures. IconClicks optionally carries IconClickThrough and IconClickTracking so the badge links to the opt-out or why-this-ad page. VAST 4.2 added IconClickFallbackImages for environments where click-through is blocked.",
            "None of this executes at ad-server response time. The player parses the final document, reserves a rectangle from width, height, and position, fetches the resource URL, and composites the overlay on the video surface for the declared window. If any required attribute or the resource URL is missing, most stacks skip the overlay silently and continue linear playback."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where Icons lives: Linear, NonLinearAds, and the chain you must fetch",
          "paragraphs": [
            "On VAST 3.0 through 4.3, Icons is a sibling of MediaFiles and TrackingEvents under Linear inside Creatives. It is not an InLine-level metadata field and not a substitute for CompanionAds. Checking a trafficking export that lists Icons on a wrapper while never unwrapping to the InLine is the same category error as validating Duration on hop one only.",
            "Operational QA should mirror how the player resolves the chain. Paste or fetch the entry URL, follow VASTAdTagURI redirects until you hold the InLine (or the deepest document your player timeout allows), and validate Icons on that merged view. A green first hop plus a missing Icons block on the InLine is a common false negative in manual review.",
            "For SSAI, validate the document the device receives after stitching, not only the pre-stitch asset in the creative library. Stitchers that rebuild InLine from MediaFiles alone often omit Icons even when the upstream chain included them. The living-room player never sees the upstream overlay contract.",
            "VAST 4.4 draft work places Icons under NonLinearAds as well, so pause and portfolio formats can carry the same AdChoices disclosure as linear pods. The attribute and resource rules on Icon itself do not change; only the parent path moves. Validation must target the creative type you actually traffic."
          ]
        },
        {
          "type": "list",
          "heading": "What Icon validation can catch before playback",
          "items": [
            "Icons containing anything other than Icon elements.",
            "Icon missing the required program attribute, or program present but empty.",
            "Icon missing required width, height, xPosition, or yPosition.",
            "Icon with no StaticResource, IFrameResource, or HTMLResource child.",
            "StaticResource missing creativeType or carrying an empty CDATA URL.",
            "HTTP icon asset URLs on HTTPS-only CTV inventory.",
            "IconClicks with unknown child elements that break schema parsing.",
            "Duplicate program values when the player expects one badge per program slot.",
            "Icons present on the trafficking export but absent on the unwrapped live InLine or post-SSAI output."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Required attributes versus the attributes players actually use",
          "paragraphs": [
            "VAST 3.0 made program, width, height, xPosition, and yPosition required on Icon. That is stricter than many legacy feeds assume. Trafficking tools sometimes emit duration and offset copied from a template while leaving width and height blank, expecting the player to infer size from the asset. Parsers that enforce the schema reject or skip the Icon; lenient parsers may draw a zero-size box.",
            "program identifies which industry overlay this entry represents. AdChoices is the common value for the DAA triangle. Custom program strings are valid when you ship proprietary badges, but empty program gives the player no slot key. Multiple Icon entries with the same program and overlapping geometry can collide on screen.",
            "xPosition and yPosition use vastIntegerOrPercent_type in the schema, so right and top are valid keywords and numeric offsets are valid on Icon (unlike QrCodePosition in VAST 4.4, which is percent-only). Copying pixel coordinates from a QR block into an Icon without reading the type difference is a recurring generator bug."
          ]
        },
        {
          "type": "code",
          "heading": "A Linear Icons block that should pass validation",
          "language": "xml",
          "code": "<Linear>\n  <Duration>00:00:30</Duration>\n  <Icons>\n    <Icon program=\"AdChoices\" width=\"77\" height=\"15\" xPosition=\"right\" yPosition=\"top\"\n          duration=\"00:00:30\" offset=\"00:00:00\">\n      <StaticResource creativeType=\"image/png\">\n        <![CDATA[https://cdn.example.com/adchoices-77x15.png]]>\n      </StaticResource>\n      <IconClicks>\n        <IconClickThrough>\n          <![CDATA[https://optout.aboutads.info/?c=2&lang=EN]]>\n        </IconClickThrough>\n        <IconClickTracking>\n          <![CDATA[https://track.example.com/icon-click]]>\n        </IconClickTracking>\n      </IconClicks>\n    </Icon>\n  </Icons>\n  <MediaFiles>\n    <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\">\n      <![CDATA[https://cdn.example.com/spot.mp4]]>\n    </MediaFile>\n  </MediaFiles>\n</Linear>"
        },
        {
          "type": "paragraphs",
          "heading": "What a player does with that Icons envelope",
          "paragraphs": [
            "After Linear resolves, the player reads Icons before or during startup depending on the SDK. For each Icon, it records program, computes screen coordinates from width, height, xPosition, and yPosition, fetches the StaticResource URL, and composites the PNG for the window defined by duration and offset.",
            "IconClickThrough is separate from Linear VideoClicks. Tapping the badge should open the disclosure URL, not the advertiser landing page, unless you deliberately wire the same destination. [IconClickTracking](https://pixellint.org/docs/impression-vs-click-trackers/) fires on interaction; it does not replace impression or quartile beacons.",
            "If every field in the passing example is present, the badge still might not appear on a given CTV device because the SDK ignores Icons on that firmware build or because safe-area clipping removes a right-top overlay on ultrawide layouts. Envelope validation proves the tag handed the player a complete Icon contract in the shape VAST 3.0 expects; it does not prove pixel-perfect placement on every panel."
          ]
        },
        {
          "type": "code",
          "heading": "An Icons block that lists AdChoices but should be flagged",
          "language": "xml",
          "code": "<Icons>\n  <Icon width=\"77\" height=\"15\" xPosition=\"right\" yPosition=\"top\">\n    <StaticResource creativeType=\"image/png\">\n      <![CDATA[]]>\n    </StaticResource>\n  </Icon>\n  <Icon program=\"AdChoices\" xPosition=\"120\" yPosition=\"10\">\n    <StaticResource creativeType=\"image/png\">\n      <![CDATA[http://cdn.example.com/adchoices.png]]>\n    </StaticResource>\n  </Icon>\n  <Tracking event=\"start\">\n    <![CDATA[https://track.example.com/start]]>\n  </Tracking>\n</Icons>"
        },
        {
          "type": "paragraphs",
          "heading": "Why that block still looks compliant in a spreadsheet",
          "paragraphs": [
            "Trafficking exports often reduce icons to a yes/no column: Icons present. The first Icon has width, height, and position, so the row looks populated. program is missing, so the player cannot classify the overlay as AdChoices versus a custom badge. The StaticResource CDATA is empty, so there is nothing to fetch even if program were fixed.",
            "The second Icon declares program AdChoices but omits width and height, which are required in VAST 3.0+. xPosition 120 is schema-valid on Icon as an integer offset, but without height the layout engine may collapse the overlay to zero vertical space. The asset URL uses HTTP, which mixed-content rules block on many HTTPS CTV apps.",
            "The stray Tracking node under Icons is not a valid child. Parsers that strict-reject the Icons container drop the entire block, including any partially valid Icon entries. Fix order: require non-empty program, width, height, xPosition, yPosition, a non-empty HTTPS StaticResource with creativeType, move creative tracking back under Linear TrackingEvents, and re-run validation on the unwrapped InLine the player will see."
          ]
        },
        {
          "type": "list",
          "heading": "What the Icon rule set should complain about",
          "items": [
            "VAST-3.0-icon-program because the first Icon has no program attribute.",
            "VAST-3.0-icon-resource or empty URL warnings because the first StaticResource CDATA is empty.",
            "VAST-3.0-icon-width and VAST-3.0-icon-height because the second Icon omits dimensions.",
            "VAST-3.0-icons-unknown-child because Tracking is not allowed directly under Icons.",
            "VAST-3.0-icon-attrs when recommended attribute combinations are incomplete.",
            "HTTPS-related warnings when icon assets use HTTP on secure inventory."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "IconClicks, fallback images, and CTV remote input",
          "paragraphs": [
            "IconClickThrough is how the viewer reaches the why-this-ad or opt-out experience. Omitting IconClicks entirely is schema-valid but weak for programs that expect a tappable disclosure. Many CTV remotes cannot click arbitrary overlays; some platforms treat IconClickThrough as informational only and open the URL on a dedicated button.",
            "VAST 4.2 IconClickFallbackImages provides alternate static assets when click-through is unsupported. Each IconClickFallbackImage should carry width and height so the player knows the fallback dimensions before fetch. Missing those attributes produces the same silent skip pattern as a bare Icon.",
            "Do not confuse Icon overlays with OpenRTB regs.ext.adchoices, which carries the DAA Protect My Choices signal in the bid request. That signal and the VAST Icon solve different hops: one is auction-time preference, the other is render-time disclosure on the creative. A bid can carry adchoices while the VAST Icon is hollow, and the viewer sees no badge."
          ]
        },
        {
          "type": "list",
          "heading": "A pre-launch Icons checklist",
          "items": [
            "Declared VAST version is 3.0+ and Icons sits under Linear (or NonLinearAds for 4.4 portfolio traffic) inside the InLine the player resolves.",
            "Every Icon has a non-empty program value appropriate to the badge (AdChoices for the industry triangle).",
            "Every Icon includes width, height, xPosition, and yPosition.",
            "Every Icon includes StaticResource, IFrameResource, or HTMLResource with a non-empty HTTPS URL and correct creativeType for static assets.",
            "IconClicks present when the buy requires a clickable disclosure, with IconClickThrough pointing at the program URL.",
            "duration and offset set explicitly when QA needs consistent timing across devices.",
            "Icons contains only Icon children; creative TrackingEvents stay under Linear.",
            "The unwrapped live chain, including post-SSAI output, still contains the same Icons subtree as the trafficking export."
          ]
        },
        {
          "type": "code",
          "heading": "Use the CLI when hollow icons should block launch",
          "language": "sh",
          "code": "vastlint check tag.xml --format json\n\nvastlint check tag.xml --fail-on-warning\n\nvastlint check \"https://ad.example.com/vast?cid=9001\" --unwrap"
        },
        {
          "type": "paragraphs",
          "heading": "What Icon validation cannot prove",
          "paragraphs": [
            "A valid Icons envelope is necessary, not sufficient. XML checks do not download the PNG, verify the CDN returns 200, or confirm the CTV SDK implements Icons on that firmware. They do not prove the badge clears notch and overscan safe areas. They will not catch a stitcher that removes Icons after you validated the upstream chain.",
            "They also will not replace manual capture on reference devices. Some players render Icons only on web and ignore them on native CTV even when the XML passes. Session logs from those SDKs rarely mention Icons; they simply never allocate the overlay layer.",
            "If quartiles fire and compliance still reports missing AdChoices, compare the resolved InLine against the trafficking export. If the video never starts, fix MediaFiles first. If the video plays and Icons is absent or hollow on the live chain, this checklist is the one."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate Icons in your VAST tag",
          "paragraph": "Paste a tag or fetch a live URL. vastlint checks Icon attributes, resources, Icons container shape, and wrapper chain before launch.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "IAB VAST standard",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST 3.0 Icons under Linear; industry icon overlays and AdChoices placement.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VAST-3.0-icon-program",
              "href": "/docs/rules/VAST-3.0-icon-program/",
              "description": "Icon requires a non-empty program attribute.",
              "source": "Rules"
            },
            {
              "label": "VAST-3.0-icon-resource",
              "href": "/docs/rules/VAST-3.0-icon-resource/",
              "description": "Icon must include a renderable StaticResource, IFrameResource, or HTMLResource.",
              "source": "Rules"
            },
            {
              "label": "VAST-3.0-icon-attrs",
              "href": "/docs/rules/VAST-3.0-icon-attrs/",
              "description": "Width, height, and position together define a renderable overlay.",
              "source": "Rules"
            },
            {
              "label": "VAST 2.0 to 3.0 migration",
              "href": "/docs/vast-2-to-3/",
              "description": "Icons introduction and AdChoices XML example.",
              "source": "Docs"
            },
            {
              "label": "How to validate VAST wrappers",
              "href": "/blog/how-to-validate-vast-wrappers/",
              "description": "Why Icons on hop one is not proof it survives the chain.",
              "source": "Blog"
            }
          ]
        }
      ]
    },
    {
      "slug": "how-to-validate-adverifications-in-vast-tags",
      "title": "How to Validate AdVerifications in VAST Tags",
      "description": "A tag can list AdVerifications and still ship zero OMID measurement if Verification has no executable resource or the vendor key is empty.",
      "publishedAt": "2026-09-10",
      "updatedAt": "2026-09-10",
      "author": "Alex Sekowski",
      "readingTime": "12 min read",
      "heroKicker": "Verification envelope",
      "tags": [
        "AdVerifications",
        "OMID",
        "VAST 4.1",
        "How-to",
        "CTV"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "A VAST InLine can play a clean MP4, fire every quartile, and still deliver zero third-party measurement. The buyer's verification vendor sees an unmeasured impression. The seller's ad server logs a completed view. Both sides think the other side broke something, because the XML looked verified at trafficking time.",
            "The usual production bug is not a missing OM SDK build on the player. It is an AdVerifications envelope that exists on paper but cannot execute: a Verification node with an empty vendor attribute, a JavaScriptResource with no URL inside the CDATA, or a wrapper chain where Impression pixels survive every hop but AdVerifications never reaches the InLine the player actually parses.",
            "IAB Tech Lab moved verification out of Extensions and into a first-class AdVerifications element in VAST 4.1. That envelope is the contract between trafficking, the player, and the measurement vendor. This piece is the container check: where the block has to live, which fields must be present before OM SDK ever runs, and what XML validation can catch while the video still plays normally."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/how-to-validate-adverifications-in-vast-tags.png?v=2",
          "alt": "An InLine can play and fire quartiles while AdVerifications is missing or emptied by a wrapper, so the seller logs a complete and the verification vendor logs nothing.",
          "width": 1440,
          "height": 820,
          "caption": "Looking verified in trafficking is not the same as a verification node surviving to the player.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "Why the verification envelope is a money problem",
          "paragraphs": [
            "Programmatic video buys increasingly price verification into the deal. A PMP that requires viewability or IVT measurement assumes the tag carries a parseable Verification entry with a loadable resource. When that entry is hollow, the impression still clears. The buyer's post-bid report simply marks it unmeasured, and reconciliation drifts toward the buyer's lower count.",
            "That drift is slow until it is not. Inventory that persistently fails measurement gets repriced without a support ticket. DSP algorithms shade bids on supply that cannot prove itself. The seller sees CPM decay and assumes creative fatigue, when the actual failure is a Verification shell that never pointed at an executable script.",
            "SSAI makes the envelope problem worse because the stitcher is a new publisher of VAST. It may copy Impression and MediaFiles faithfully and drop AdVerifications because the downstream player template only understands VAST 3.0 shapes. The stitched InLine plays. The verification block from the pre-stitch package is gone. Buyer and seller reports disagree, and neither side's dashboard names XML as the root cause.",
            "Wrapper chains create the same invisible loss. AdVerifications can legally sit on a Wrapper or on the InLine. Players that accumulate verification from every hop will merge entries from outer wrappers with the final InLine. A QA paste of hop one that shows a Verification block is compatible with an InLine three redirects later that never inherited it, especially when an intermediary SSP re-renders the document and strips 4.x-only children."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What AdVerifications actually carries",
          "paragraphs": [
            "AdVerifications is a container, not a measurement session. It holds one or more Verification children. Each Verification names a vendor and points at the resource the player should load: JavaScriptResource for web and many CTV SDK paths, ExecutableResource for native binaries on some platforms. Optional VerificationParameters pass vendor-specific configuration. TrackingEvents under Verification should include verificationNotExecuted so the vendor learns when load or execution failed instead of inferring silence.",
            "None of that runs at ad-server response time. The player parses the final document, discovers Verification entries, and asks OM SDK (or a legacy integration) to load the resource. If vendor is missing, both resource types are absent, or the JavaScript URL is empty, the player has nothing to execute. Many stacks still start the linear creative. Quartile pixels fire. The verification vendor sees nothing.",
            "That is the distinction from an OMID runtime guide. OM SDK integration, access modes, and session APIs matter after the envelope is valid. Envelope validation asks a narrower question: did this tag actually hand the player an identifiable vendor and a fetchable resource, in the place and shape the declared VAST version expects?"
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where the block lives: InLine, Wrapper, and the chain you must fetch",
          "paragraphs": [
            "On VAST 4.1 and later, AdVerifications is a direct child of InLine or Wrapper. It is not a Creative child and not a substitute for Linear tracking. Checking a Wrapper paste for verification while never unwrapping to the InLine is the same category error as demanding Duration on hop one.",
            "Operational QA should mirror how the player resolves the chain. Paste or fetch the entry URL, follow VASTAdTagURI redirects until you hold the InLine (or the deepest document your player timeout allows), and validate that merged view. A green first hop plus a missing block on the InLine is a common false negative in manual review.",
            "For SSAI, validate the document the device receives after stitching, not only the pre-stitch asset in the creative library. Stitchers that downgrade version or rebuild InLine from MediaFiles often omit AdVerifications even when the upstream chain included it. The player never sees the upstream envelope."
          ]
        },
        {
          "type": "list",
          "heading": "What AdVerifications envelope validation can catch before playback",
          "items": [
            "AdVerifications containing anything other than Verification elements.",
            "Verification missing the required vendor attribute, or vendor present but empty.",
            "Verification with neither JavaScriptResource nor ExecutableResource.",
            "JavaScriptResource or ExecutableResource missing apiFramework, or OMID resources not declaring apiFramework=\"omid\".",
            "ExecutableResource missing type when the platform requires it.",
            "Empty or HTTP verification script URLs on secure inventory.",
            "Duplicate vendor identifiers inside one AdVerifications block.",
            "VerificationParameters missing or empty when the vendor script requires runtime configuration.",
            "verificationNotExecuted tracking missing the [REASON] macro, weakening post-mortems.",
            "Extension type=\"AdVerifications\" on pre-4.1 documents where the player expects a top-level block instead."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "VAST 4.1+ top-level placement versus the Extension compatibility path",
          "paragraphs": [
            "VAST 4.1 introduced AdVerifications as a first-class sibling of Creatives under InLine and Wrapper. That is the shape modern OM SDK integrations target. Google IMA and other players document that 4.1 and higher should use the top-level element; older traffic sometimes wrapped the same data inside Extension type=\"AdVerifications\".",
            "The compatibility path matters in legacy feeds, but it is not interchangeable with 4.1 placement. A player configured for top-level AdVerifications will ignore verification buried only in Extensions on a document that declares version=\"4.2\". The XML can contain the data in a spec-valid Extension and still deliver zero measurement on that player.",
            "Migration work is therefore two-part: move verification to the top-level element for 4.1+ trafficking, and stop declaring 4.x while serializing pre-4.1 Extension shapes. Version honesty and envelope placement have to match, or parsers pick one shape and discard the other."
          ]
        },
        {
          "type": "code",
          "heading": "A VAST 4.2 AdVerifications envelope that should pass",
          "language": "xml",
          "code": "<InLine>\n  <AdSystem version=\"1.0\">Example Ad Server</AdSystem>\n  <AdTitle>Spring CTV :15</AdTitle>\n  <Impression><![CDATA[https://track.example.com/imp]]></Impression>\n  <AdVerifications>\n    <Verification vendor=\"measurement.example.com-omid\">\n      <JavaScriptResource apiFramework=\"omid\" browserOptional=\"true\"><![CDATA[https://cdn.measurement.example.com/omsdk/omid.js]]></JavaScriptResource>\n      <VerificationParameters><![CDATA[{\"placement\":\"ctv-spring\"}]]></VerificationParameters>\n      <TrackingEvents>\n        <Tracking event=\"verificationNotExecuted\"><![CDATA[https://track.example.com/vne?reason=[REASON]]]></Tracking>\n      </TrackingEvents>\n    </Verification>\n  </AdVerifications>\n  <Creatives>\n    <Creative id=\"9001\">\n      <Linear>\n        <Duration>00:00:15</Duration>\n        <MediaFiles>\n          <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\"><![CDATA[https://cdn.example.com/spot.mp4]]></MediaFile>\n        </MediaFiles>\n      </Linear>\n    </Creative>\n  </Creatives>\n</InLine>"
        },
        {
          "type": "paragraphs",
          "heading": "What a player does with that envelope",
          "paragraphs": [
            "After the InLine resolves, the player reads AdVerifications before or during linear startup depending on the SDK. For each Verification, it records vendor, fetches the JavaScriptResource URL (unless browserOptional and native integration apply), passes VerificationParameters into the vendor script, and registers verificationNotExecuted if load fails.",
            "Quartile TrackingEvents on Linear are unrelated to Verification TrackingEvents. Wiring start or firstQuartile under Verification is a schema and semantics error: those events belong on the creative, not on the measurement vendor block. The player may still play media while ignoring miswired verification tracking.",
            "If every field in the passing example is present, OM SDK still might not run on a given CTV device. That is an integration question. Envelope validation only proves the tag handed the player a vendor key and a non-empty HTTPS script URL in the shape VAST 4.1 expects."
          ]
        },
        {
          "type": "code",
          "heading": "An AdVerifications block that lists verification but should be flagged",
          "language": "xml",
          "code": "<AdVerifications>\n  <Verification vendor=\"\">\n    <VerificationParameters><![CDATA[{\"campaign\":\"spring\"}]]></VerificationParameters>\n    <TrackingEvents>\n      <Tracking event=\"start\"><![CDATA[https://track.example.com/start]]></Tracking>\n    </TrackingEvents>\n  </Verification>\n  <Verification vendor=\"moat\">\n    <JavaScriptResource apiFramework=\"OMSDK\"><![CDATA[]]></JavaScriptResource>\n  </Verification>\n  <Verification vendor=\"moat\">\n    <JavaScriptResource apiFramework=\"omid\"><![CDATA[http://measurement.example.com/omid.js]]></JavaScriptResource>\n  </Verification>\n</AdVerifications>"
        },
        {
          "type": "paragraphs",
          "heading": "Why that block still looks verified in a spreadsheet",
          "paragraphs": [
            "Trafficking exports often reduce verification to a yes/no column: AdVerifications present. The first Verification has Parameters and Tracking, so the row looks populated. vendor is empty, so the player cannot disambiguate which integration to load. No JavaScriptResource or ExecutableResource exists on that entry, so there is nothing to fetch even if vendor were fixed.",
            "The second and third entries share a bare vendor name and duplicate moat, which violates the domain-qualified vendor convention and triggers duplicate-vendor warnings. The second entry's JavaScriptResource declares the wrong apiFramework and an empty CDATA body. The third points at HTTP. A shallow DOM count says three verifications. Runtime executes zero.",
            "Fix order: require non-empty vendor in domain-omid form, exactly one Verification per vendor, a non-empty HTTPS JavaScriptResource with apiFramework=\"omid\", move creative tracking off the Verification node, and add verificationNotExecuted with [REASON]. Re-run validation on the unwrapped InLine the player will see, not on the wrapper cover sheet."
          ]
        },
        {
          "type": "list",
          "heading": "What the AdVerifications rule set should complain about",
          "items": [
            "VAST-4.1-verification-vendor because the first Verification has an empty vendor attribute.",
            "VAST-4.1-verification-no-resource because the first Verification has no JavaScriptResource or ExecutableResource.",
            "VAST-4.1-verification-vendor-format because moat is not domain-qualified.",
            "VAST-4.1-verification-duplicate-vendor because moat appears twice.",
            "VAST-4.1-js-resource-apiframework-value because OMSDK is not omid.",
            "VAST-4.1-js-resource-https because the script URL uses HTTP.",
            "Verification tracking event errors because start is not a valid Verification tracking event.",
            "VAST-4.1-verification-parameters may warn on entries that need parameters; the empty-vendor entry has parameters but no resource to consume them."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Wrapper hops that drop the envelope",
          "paragraphs": [
            "Verification injected at the outermost wrapper survives only if every downstream hop preserves AdVerifications and the player merges wrapper-level entries correctly. Some SSPs flatten wrappers into a single InLine for latency and copy only Impression, Creatives, and MediaFiles. Verification from hop one never reaches the device.",
            "The failure mode looks like a vendor outage. The buyer's dashboard shows a sudden spike in unmeasured impressions on one supply path. The seller's fill and completion rates are unchanged. Support compares two VAST pastes from different days and finds verification on the trafficking export but not on the live resolved chain.",
            "Prevention is chain inspection, not a single-hop paste. Fetch the live tag URL with the same timeout and redirect policy as production, unwrap programmatically, and diff AdVerifications nodes across hops. If an intermediary strips them, fix the intermediary or move verification injection to the InLine that survives stitching."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "ExecutableResource versus JavaScriptResource on CTV",
          "paragraphs": [
            "Most web and hybrid CTV stacks use JavaScriptResource with apiFramework=\"omid\". Native-only integrations sometimes use ExecutableResource with a type attribute describing the binary interface. A Verification that lists only ExecutableResource on a player expecting JavaScript will not load measurement, even when vendor and URLs look valid for a different platform.",
            "browserOptional on JavaScriptResource tells native players they may skip the script when a native OM SDK integration exists. Omitting browserOptional on CTV webviews that cannot execute JS should lead to verificationNotExecuted, not silent success. Envelope checks cannot prove the player honored browserOptional; they can prove the attribute and resource types match the declared VAST version.",
            "When trafficking the same asset to web and CTV, duplicate Verification entries with different resource types are valid if vendor strings differ per integration. Duplicate vendor with conflicting resources is not."
          ]
        },
        {
          "type": "list",
          "heading": "A pre-launch AdVerifications checklist",
          "items": [
            "Declared VAST version is 4.1+ and AdVerifications is top-level under InLine or Wrapper, not only inside Extensions unless the player documents Extension support.",
            "Every Verification has a non-empty vendor in domain-omid form.",
            "Every Verification includes JavaScriptResource or ExecutableResource with required attributes for the target platform.",
            "OMID JavaScriptResource URLs are HTTPS, non-empty, and declare apiFramework=\"omid\".",
            "No duplicate vendor values inside one AdVerifications block.",
            "VerificationParameters present when the vendor script requires them.",
            "verificationNotExecuted tracking includes the [REASON] macro.",
            "Creative quartile tracking is on Linear, not miswired under Verification.",
            "The unwrapped live chain, including post-SSAI output, still contains the same Verification entries as the trafficking export."
          ]
        },
        {
          "type": "code",
          "heading": "Use the CLI when hollow verification should block launch",
          "language": "sh",
          "code": "vastlint check tag.xml --format json\n\nvastlint check tag.xml --fail-on-warning\n\nvastlint check \"https://ad.example.com/vast?cid=9001\" --unwrap"
        },
        {
          "type": "paragraphs",
          "heading": "What AdVerifications envelope validation cannot prove",
          "paragraphs": [
            "A valid envelope is necessary, not sufficient. XML checks do not download the script, verify the vendor signed it, or confirm OM SDK is integrated on the device. They do not prove verificationNotExecuted fires when execution fails. They will not catch a stitcher that removes the block after you validated the upstream chain.",
            "They also will not replace OMID session debugging. Session errors, access mode mismatches, and creative container geometry belong in player logs and vendor tooling after the envelope passes.",
            "If quartiles fire and the buyer still sees unmeasured impressions, compare the resolved InLine against the trafficking export. If the video never starts, fix Linear and MediaFiles first. If the video plays and verification is absent on the live chain, this checklist is the one."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate AdVerifications in your VAST tag",
          "paragraph": "Paste a tag or fetch a live URL. vastlint checks the Verification envelope, vendor format, resources, and wrapper chain before launch.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "What Is OMID",
              "href": "/docs/omid/",
              "description": "AdVerifications structure, Verification children, and how OM SDK uses the envelope at runtime.",
              "source": "Docs"
            },
            {
              "label": "VAST-4.1-verification-vendor",
              "href": "/docs/rules/VAST-4.1-verification-vendor/",
              "description": "Verification requires a non-empty vendor attribute.",
              "source": "Rules"
            },
            {
              "label": "VAST-4.1-verification-no-resource",
              "href": "/docs/rules/VAST-4.1-verification-no-resource/",
              "description": "Verification should include JavaScriptResource or ExecutableResource.",
              "source": "Rules"
            },
            {
              "label": "VAST-4.0-adverifications-unknown-child",
              "href": "/docs/rules/VAST-4.0-adverifications-unknown-child/",
              "description": "AdVerifications may only contain Verification elements.",
              "source": "Rules"
            },
            {
              "label": "How to validate OMID in VAST tags",
              "href": "/blog/how-to-validate-omid-in-vast-tags/",
              "description": "Runtime-oriented OMID checks after the envelope is valid.",
              "source": "Blog"
            },
            {
              "label": "How to validate VAST wrappers",
              "href": "/blog/how-to-validate-vast-wrappers/",
              "description": "Why verification on hop one is not proof it survives the chain.",
              "source": "Blog"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST 4.1 AdVerifications and Verification element definitions.",
              "source": "IAB Tech Lab"
            }
          ]
        }
      ]
    },
    {
      "slug": "how-to-validate-universaladid-in-vast-tags",
      "title": "How to Validate UniversalAdId in VAST Tags",
      "description": "UniversalAdId validation is version-specific: VAST 4.0 needs idRegistry plus idValue, VAST 4.1+ needs idRegistry plus text content. Catch a missing identity before SSAI strips it and frequency caps stop joining.",
      "publishedAt": "2026-09-07",
      "updatedAt": "2026-09-07",
      "author": "Alex Sekowski",
      "readingTime": "12 min read",
      "heroKicker": "Creative identity",
      "tags": [
        "UniversalAdId",
        "VAST 4.x",
        "How-to",
        "CTV"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "A VAST 4.x InLine can play a clean MP4 and still be useless for frequency capping. The creative identity that buyers, sellers, and verification vendors are supposed to share lives in UniversalAdId, not in Creative id, not in Ad id, and not in the filename on the CDN. If that element is missing, stored in the wrong place for the declared version, or rewritten on every stitch, three systems will log three different creatives for one spot.",
            "IAB Tech Lab made UniversalAdId required inside InLine Creative from VAST 4.0 onward. Wrappers do not carry it. SSAI packs that downgrade 4.x to 2.0 or 3.0 for an old player have no home for the element, so the identity is stripped even when media and duration survive. The session looks healthy in the player and broken in the frequency and competitive-separation reports.",
            "The usual production bug is not a missing MP4. It is a template that still emits the VAST 4.0 idValue attribute, sets version=\"4.2\", and leaves the element body empty. Parsers that only read text content see no identifier. This piece is the envelope check: where the ID has to live, which rule fires, and what XML validation cannot prove about Ad-ID itself."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/how-to-validate-universaladid-in-vast-tags.png?v=2",
          "alt": "Creative id, Ad id, and the media filename are not UniversalAdId. The shared creative identity sits on the InLine, as an attribute in VAST 4.0 and as element text from 4.1.",
          "width": 1440,
          "height": 820,
          "caption": "A playing MP4 can still be three different creatives in three systems if UniversalAdId is missing or rewritten on the stitch.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "Why creative identity is a money problem",
          "paragraphs": [
            "Ad servers, DSPs, SSPs, and verification vendors each mint their own creative IDs. None of them match. UniversalAdId is the cross-system identifier, typically an Ad-ID registry code in the US or a Clearcast code in the UK. Frequency caps that are supposed to fire across two apps and a CTV channel need that one ID. Without it, a viewer who saw the same :15 three times looks like three unrelated exposures.",
            "Pod dedup is the same join with a tighter clock. Two DSPs can win adjacent slots in one break with the same asset under different internal IDs. Competitive separation (two car brands out of the same break) has the same requirement: the pod logic has to know what the creatives actually are, not what each seller labeled them in its private namespace.",
            "Audits and brand-safety reviews need a join key that survives a quarter of delivery logs from different vendors. At IAB Tech Lab's August 2026 Ad Ops workshop, buyer or advertiser demand and better frequency or separation controls each led at 33% when the room was asked what would make UniversalAdId worth enforcing. Trafficking will not put the element on every tag until those controls fail visibly.",
            "Version downgrades are the quiet kill. A 4.2 InLine that is re-rendered as VAST 3.0 for a device that \"does not support 4.x\" drops UniversalAdId because the older schema has no such child. MediaFile still plays. The identity does not. That is the same class of failure as a version mismatch the player already printed, except nobody looks at identity when the video started."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The identifier lives on the InLine, after the wrappers",
          "paragraphs": [
            "A Wrapper is allowed to be thin. Impression pixels on hop one are real. Duration is not on the wrapper. MediaFiles are not on the wrapper. UniversalAdId is not on the wrapper. Checking a pasted VASTAdTagURI document for Creative identity is a category error: the element you need is on the InLine at the bottom of the chain.",
            "SSAI makes that worse because the stitcher is a new publisher of VAST. It may fetch the chain, choose renditions, and emit a new InLine to the player. If that generated document copies Creative id from the ad server and omits UniversalAdId, or copies idValue into a 4.2 document with empty text, the player never sees the registry code. Frequency and verification vendors that read the stitched tag, not the pre-stitch InLine, join on nothing.",
            "The working split is the same as wrapper QA. File in git or a trafficking export you already unwrapped: validate the InLine. Partner URL: fetch it, then inspect hops until you see the InLine Creative. A green wrapper paste is compatible with a missing UniversalAdId three hops down."
          ]
        },
        {
          "type": "list",
          "heading": "What UniversalAdId XML validation can catch before playback",
          "items": [
            "Creative in a VAST 4.x InLine with no UniversalAdId.",
            "UniversalAdId missing idRegistry.",
            "VAST 4.0 document with no idValue attribute.",
            "VAST 4.1+ document with empty text content.",
            "VAST 4.1+ document that still uses idValue (warning; parsers that only read text content see an empty ID).",
            "idRegistry claiming Ad-ID while the value is an internal ad-server token."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "VAST 4.0 still uses the idValue attribute",
          "paragraphs": [
            "VAST 4.0 stores the identifier on idValue and keeps idRegistry as the required registry name. Text content may repeat the same code; when both are present they must agree. A 4.0 Creative with idRegistry and no idValue is a spec miss, not a style choice.",
            "Keep 4.0 templates on 4.0. Relabeling version=\"4.1\" without moving the value into text content is the migration bug IAB documented when 4.1 shipped. The schema removed idValue. A document that still has the attribute and an empty body is invalid as 4.1 even if it was valid as 4.0.",
            "If you still have to emit 4.0 for a specific player, emit 4.0 honestly. Do not declare 4.2 and internally serialize 4.0. Downstream XML parsers will pick one shape. They will not merge attribute and text for you."
          ]
        },
        {
          "type": "code",
          "heading": "VAST 4.0 shape that should pass",
          "language": "xml",
          "code": "<Creative id=\"5480\" sequence=\"1\">\n  <UniversalAdId idRegistry=\"Ad-ID\" idValue=\"CNPA0484000H\">CNPA0484000H</UniversalAdId>\n  <Linear>\n    <Duration>00:00:15</Duration>\n    <MediaFiles>\n      <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\">\n        <![CDATA[https://cdn.example.com/video.mp4]]>\n      </MediaFile>\n    </MediaFiles>\n  </Linear>\n</Creative>"
        },
        {
          "type": "paragraphs",
          "heading": "VAST 4.1 moved the value into text. 4.2 allows more than one.",
          "paragraphs": [
            "From VAST 4.1 the identifier is the element's text content. idRegistry stays required. Leftover idValue is a warning because strict parsers ignore the attribute and then find an empty body. VAST 4.2 also allows multiple UniversalAdId children on one Creative so a spot can carry Ad-ID and Clearcast at once.",
            "That multiplicity is for registries, not for minting a new code per hop. Two UniversalAdId elements with the same registry and different values are a fight. Two elements with Ad-ID and clearcast.co.uk are the intended 4.2 case: one asset, two industry codes.",
            "SSAI output that sets version=\"4.2\", keeps idValue, and leaves the body empty is the document in the next block. It often still has a Creative id the ad server understands. The player plays. The join key is gone."
          ]
        },
        {
          "type": "code",
          "heading": "VAST 4.2+ shape that should pass",
          "language": "xml",
          "code": "<Creative id=\"5480\" sequence=\"1\">\n  <UniversalAdId idRegistry=\"Ad-ID\">CNPA0484000H</UniversalAdId>\n  <UniversalAdId idRegistry=\"clearcast.co.uk\">AAA/BBBB123/030</UniversalAdId>\n  <Linear>\n    <Duration>00:00:15</Duration>\n    <MediaFiles>\n      <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\">\n        <![CDATA[https://cdn.example.com/video.mp4]]>\n      </MediaFile>\n    </MediaFiles>\n  </Linear>\n</Creative>"
        },
        {
          "type": "code",
          "heading": "A 4.2 creative that looks identified but should be flagged",
          "language": "xml",
          "code": "<VAST version=\"4.2\">\n  <Ad>\n    <InLine>\n      <Creatives>\n        <Creative id=\"5480\">\n          <UniversalAdId idRegistry=\"Ad-ID\" idValue=\"CNPA0484000H\"></UniversalAdId>\n          <Linear>\n            <Duration>00:00:15</Duration>\n            <MediaFiles>\n              <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\">https://cdn.example.com/video.mp4</MediaFile>\n            </MediaFiles>\n          </Linear>\n        </Creative>\n      </Creatives>\n    </InLine>\n  </Ad>\n</VAST>"
        },
        {
          "type": "paragraphs",
          "heading": "What a player that only reads text content does with that 4.2 tag",
          "paragraphs": [
            "The element is present, so a shallow \"do we have UniversalAdId\" check can pass. idRegistry is present, so a registry check can pass. The identifier the 4.1+ schema actually carries is the text node, and that node is empty. Frequency systems that parse 4.2 correctly treat the creative as unidentified.",
            "Verification vendors that join on UniversalAdId will not match the pre-stitch InLine that still had idValue. Seller logs that key on Creative id will still show the campaign. The two reports disagree, and the disagreement looks like a measurement outage instead of a schema migration miss.",
            "Fix the template: copy idValue into the element body, drop the attribute on 4.1+, and keep version honest. Then re-run the stitched output, not only the pre-stitch package."
          ]
        },
        {
          "type": "list",
          "heading": "What the UniversalAdId rule set should complain about",
          "items": [
            "VAST-4.0-universaladid-present because the Creative has no UniversalAdId on a 4.x InLine.",
            "VAST-4.0-universaladid-idregistry because idRegistry is missing.",
            "VAST-4.0-universaladid-idvalue because a 4.0 document omitted the idValue attribute.",
            "VAST-4.1-universaladid-content because a 4.1+ document has no text content.",
            "VAST-4.1-universaladid-idvalue-removed because idValue is still present on 4.1+."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "UniversalAdId is not AdServingId, and not Creative id",
          "paragraphs": [
            "Creative id identifies the creative inside one ad server. Ad id identifies the buy wrapping it, also private. Those attributes are useful in that vendor's UI. They are not a cross-platform join key. Copying Creative id into UniversalAdId and setting idRegistry=\"Ad-ID\" claims a registry you do not have.",
            "AdServingId, added in VAST 4.1, identifies one serving transaction so player, verification, and ad-server logs can join a single impression. It should be unique per response, typically a GUID minted at serve time. Regenerating UniversalAdId on every response turns the asset ID into a session ID. Use AdServingId for the session. Keep UniversalAdId stable across campaigns and hops.",
            "If you do not have a registry code, idRegistry=\"unknown\" with your durable internal creative ID is honest. It will not join Ad-ID graphs. It also will not poison them. Unknown plus a stable value is still better than a new GUID per stitch."
          ]
        },
        {
          "type": "list",
          "heading": "A pre-launch identity checklist",
          "items": [
            "Declared VAST version matches the UniversalAdId shape: idValue on 4.0, text content on 4.1+.",
            "InLine Creative has at least one UniversalAdId with a non-empty idRegistry.",
            "If idRegistry is Ad-ID or Clearcast, the value is a real registry code, not the ad-server Creative id.",
            "The same identifier is on the stitched InLine the player will see, not only on the pre-SSAI package.",
            "Wrappers in the chain are not the place you look for identity; inspect until the InLine.",
            "AdServingId, if present, changes per impression. UniversalAdId does not."
          ]
        },
        {
          "type": "code",
          "heading": "Use the CLI when missing identity should block launch",
          "language": "sh",
          "code": "vastlint check creative.xml --format json\n\nvastlint check creative.xml --fail-on-warning"
        },
        {
          "type": "paragraphs",
          "heading": "What UniversalAdId XML validation cannot prove",
          "paragraphs": [
            "A well-formed element is necessary. It is not a certificate that Ad-ID issued the code, or that two vendors share a join table. XML checks will not call the registry. They will not tell you the buyer actually caps on UniversalAdId rather than on a private creative ID.",
            "They also will not tell you the stitcher preserved the element. Validate the document the player fetches, after SSAI, on the version the player declared. A clean package in the creative tool and a stripped InLine on the device are compatible.",
            "If the player already printed a version error, start from the version mismatch post. Identity is downstream of a document the player refused to parse. If the video played and the frequency report looks like a new creative every session, this checklist is the one."
          ]
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "What Is UniversalAdId",
              "href": "/docs/universal-ad-id/",
              "description": "Why creative identity is a money problem, syntax by version, and common mistakes.",
              "source": "Docs"
            },
            {
              "label": "VAST-4.0-universaladid-present",
              "href": "/docs/rules/VAST-4.0-universaladid-present/",
              "description": "Creative must contain UniversalAdId on VAST 4.0+ InLine.",
              "source": "Rules"
            },
            {
              "label": "VAST-4.1-universaladid-content",
              "href": "/docs/rules/VAST-4.1-universaladid-content/",
              "description": "Text content is required in VAST 4.1+.",
              "source": "Rules"
            },
            {
              "label": "VAST 4.0 to 4.1",
              "href": "/docs/vast-4-to-4-1/",
              "description": "idValue removed, value moves to text content.",
              "source": "Docs"
            },
            {
              "label": "VAST 4.1 to 4.2",
              "href": "/docs/vast-4-1-to-4-2/",
              "description": "Migration notes, including multiple UniversalAdId elements.",
              "source": "Docs"
            },
            {
              "label": "A live VAST URL is not a paste",
              "href": "/blog/vast-tester-is-not-the-inspector/",
              "description": "Identity lives on the InLine. Fetch the chain before you declare the tag identified.",
              "source": "Blog"
            },
            {
              "label": "CTV Ad Ops Grows Up",
              "href": "https://iabtechlab.com/ctv-ad-ops-grows-upfrom-promising-capabilities-to-repeatable-operations/",
              "description": "August 2026 workshop recap: UniversalAdId demand and frequency or separation controls each at 33%.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "Primary specification for UniversalAdId.",
              "source": "IAB"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Check the Creative identity",
          "paragraph": "Paste the InLine the player will see, not only the wrapper. Look for UniversalAdId presence and the version-correct identifier shape.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        }
      ]
    },
    {
      "slug": "how-to-validate-simid-in-vast-tags",
      "title": "How to Validate SIMID in VAST Tags",
      "description": "SIMID validation starts in the VAST XML: InteractiveCreativeFile type, apiFramework, HTTPS URL, and a MediaFile fallback. Catch envelope mistakes before you debug createSession in the player.",
      "publishedAt": "2026-08-29",
      "updatedAt": "2026-08-29",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "SIMID validation",
      "tags": [
        "SIMID",
        "VAST 4.x",
        "Interactive",
        "How-to"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "SIMID validation in VAST starts with the XML envelope. If InteractiveCreativeFile is missing type=text/html, apiFramework is not SIMID, the URL is HTTP or empty, or there is no MediaFile fallback, the interactive layer is already broken before the player loads the iframe.",
            "vastlint can catch those VAST-side SIMID mistakes in the web validator, CLI, and tester. What it cannot do is prove the SIMID handshake. createSession, postMessage, and X-Frame-Options only show up when you load the creative HTML. Validate the envelope first, then test the live tag."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/how-to-validate-simid-in-vast-tags.png?v=2",
          "alt": "SIMID in VAST needs InteractiveCreativeFile with type text/html, apiFramework SIMID, an HTTPS URL, and a MediaFile beside it so the ad can still play if the iframe fails.",
          "width": 1440,
          "height": 820,
          "caption": "Interactive in the sheet and interactive in the document are different tests.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What SIMID is doing in the tag",
          "paragraphs": [
            "IAB Tech Lab positions SIMID as the secure replacement for VPAID. The VAST side is InteractiveCreativeFile inside MediaFiles: type=text/html, apiFramework=SIMID, and a URL the player loads in a sandboxed iframe. The player keeps media playback. The creative talks over postMessage.",
            "Players that do not support SIMID skip the interactive file and play the MediaFile. That fallback is why a SIMID tag still needs a real video rendition. VPAID-era tags that only ship a JavaScript file fail as error 901 on CTV."
          ]
        },
        {
          "type": "list",
          "heading": "What SIMID XML validation can catch before playback",
          "items": [
            "InteractiveCreativeFile missing type, or type that is not text/html.",
            "apiFramework missing, misspelled, or still set to VPAID.",
            "Empty creative URL, HTTP URL on an HTTPS page, or a data: HTML blob the player will not fetch.",
            "No MediaFile fallback next to the interactive file.",
            "variableDuration set to a value other than true or false.",
            "Nonlinear SIMID that is missing the IFrameResource path used in SIMID 1.1."
          ]
        },
        {
          "type": "code",
          "heading": "A minimal SIMID block that should pass",
          "language": "xml",
          "code": "<MediaFiles>\n  <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1280\" height=\"720\">\n    <![CDATA[https://cdn.example.com/video.mp4]]>\n  </MediaFile>\n  <InteractiveCreativeFile type=\"text/html\" apiFramework=\"SIMID\">\n    <![CDATA[https://cdn.example.com/simid/creative.html]]>\n  </InteractiveCreativeFile>\n</MediaFiles>"
        },
        {
          "type": "code",
          "heading": "A block that looks interactive but should be flagged",
          "language": "xml",
          "code": "<MediaFiles>\n  <InteractiveCreativeFile type=\"application/javascript\" apiFramework=\"VPAID\">\n    <![CDATA[http://cdn.example.com/vpaid.js]]>\n  </InteractiveCreativeFile>\n</MediaFiles>"
        },
        {
          "type": "list",
          "heading": "What the SIMID rule set should complain about",
          "items": [
            "VAST-4.1-interactive-creative-type because the MIME type is not text/html.",
            "VAST-4.1-vpaid-apiframework or SIMID-1.0-simid-apiframework-case because apiFramework is still VPAID or the wrong case.",
            "SIMID-1.0-simid-url-https because the creative URL is HTTP.",
            "SIMID-1.0-simid-mediafile-required because there is no MediaFile fallback.",
            "Player error 901 if a VPAID unit still ships to CTV; error 902 if a SIMID file is present but fails at runtime."
          ]
        },
        {
          "type": "list",
          "heading": "Which channel to use",
          "items": [
            "The web validator at vastlint.org/validate is the fastest paste check for InteractiveCreativeFile attributes.",
            "The VAST tester at vastlint.org/tester fetches a live URL and is the right next step after the envelope is clean.",
            "The SIMID explainer at vastlint.org/docs/simid/ still titles What Is SIMID. Its paste CTA opens the tester.",
            "The CLI is the launch gate: vastlint check simid.xml. Use --fail-on-warning when SIMID hygiene should block traffic."
          ]
        },
        {
          "type": "code",
          "heading": "Use the CLI when SIMID should block launch",
          "language": "sh",
          "code": "vastlint check simid-example.xml --format json\n\nvastlint check simid-example.xml --fail-on-warning"
        },
        {
          "type": "paragraphs",
          "heading": "What SIMID XML validation cannot prove",
          "paragraphs": [
            "A valid InteractiveCreativeFile is necessary. It is not the same thing as a working SIMID session. The player still has to load the HTML, accept postMessage, and complete createSession. A JavaScript error, a missing iframe sandbox flag, or X-Frame-Options only shows up in a live host.",
            "Validate the XML first. Then paste the live tag into the tester. Use error 901 and 902 pages when the player already printed a code."
          ]
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "What Is SIMID",
              "href": "/docs/simid/",
              "description": "Meaning, SIMID vs VPAID, and paste-into-tester CTA.",
              "source": "Docs"
            },
            {
              "label": "SIMID validation",
              "href": "/docs/simid-validation/",
              "description": "Envelope checks versus live fetch and handshake.",
              "source": "Docs"
            },
            {
              "label": "VAST tester",
              "href": "/tester/",
              "description": "Fetch a live SIMID tag and preview the creative.",
              "source": "Tool"
            },
            {
              "label": "VAST validator",
              "href": "/validate/",
              "description": "Paste XML for InteractiveCreativeFile rule checks.",
              "source": "Tool"
            },
            {
              "label": "Error 901",
              "href": "/docs/vast-error-codes/901/",
              "description": "General VPAID failure; migrate to SIMID.",
              "source": "Docs"
            },
            {
              "label": "Error 902",
              "href": "/docs/vast-error-codes/902/",
              "description": "InteractiveCreativeFile failed at runtime.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Test the live SIMID tag",
          "paragraph": "Paste a URL or XML into the tester after the envelope is clean. Use the validator when you already have resolved XML.",
          "href": "/tester/",
          "label": "Open the VAST tester"
        }
      ]
    },
    {
      "slug": "how-to-validate-companion-ads",
      "title": "How to Validate Companion Ads in VAST Tags",
      "description": "Companion validation starts in the XML: CompanionAds, width, height, and a renderable resource. Catch empty banners and unmatched IAB sizes before the page slot stays blank.",
      "publishedAt": "2026-08-29",
      "updatedAt": "2026-08-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Companion ads",
      "tags": [
        "Companion ads",
        "VAST",
        "Display",
        "How-to"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "Companion validation in VAST starts with the XML. If CompanionAds is missing, a Companion has no StaticResource, IFrameResource, or HTMLResource, or width and height are absent, the banner slot never fills even when the video plays.",
            "vastlint can catch empty companions and missing dimensions in the web validator and CLI. Slot matching still depends on the page. Ship 300x250 plus a large format, then paste the resolved tag. Most CTV players ignore companions."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/how-to-validate-companion-ads.png?v=2",
          "alt": "A VAST video can play while CompanionAds is missing a StaticResource, IFrameResource, or HTMLResource, or is missing width and height, so the companion slot stays empty.",
          "width": 1440,
          "height": 820,
          "caption": "The video completing does not fill the banner beside it.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What companion ads are doing in the tag",
          "paragraphs": [
            "Companions are display creatives served alongside linear video. The page or app, not the video decoder, renders them. VAST describes the assets in CompanionAds. Each Companion must declare width and height so the host can match a slot.",
            "required=all, any, or none on CompanionAds changes fill behavior. required=all can kill the video if no companion size matches. required=none keeps the video even when the banner misses."
          ]
        },
        {
          "type": "list",
          "heading": "What companion XML validation can catch before playback",
          "items": [
            "Companion with no renderable resource.",
            "Companion missing width or height.",
            "required set to a value other than all, any, or none.",
            "Unknown children under CompanionAds.",
            "Wrapper hops that drop CompanionAds when followCompanions is false."
          ]
        },
        {
          "type": "code",
          "heading": "A companion block that should pass",
          "language": "xml",
          "code": "<CompanionAds required=\"any\">\n  <Companion width=\"300\" height=\"250\">\n    <StaticResource creativeType=\"image/png\">\n      <![CDATA[https://cdn.example.com/300x250.png]]>\n    </StaticResource>\n    <CompanionClickThrough>\n      <![CDATA[https://advertiser.example.com/landing]]>\n    </CompanionClickThrough>\n  </Companion>\n  <Companion width=\"728\" height=\"90\">\n    <StaticResource creativeType=\"image/png\">\n      <![CDATA[https://cdn.example.com/728x90.png]]>\n    </StaticResource>\n  </Companion>\n</CompanionAds>"
        },
        {
          "type": "code",
          "heading": "A companion that looks present but should be flagged",
          "language": "xml",
          "code": "<CompanionAds required=\"all\">\n  <Companion>\n    <!-- no width, height, or resource -->\n  </Companion>\n</CompanionAds>"
        },
        {
          "type": "list",
          "heading": "What the companion rule set should complain about",
          "items": [
            "VAST-2.0-companion-resource because the Companion is empty.",
            "VAST-2.0-companion-dimensions because width or height is missing.",
            "VAST-3.0-companion-required-attr because required is not all, any, or none."
          ]
        },
        {
          "type": "list",
          "heading": "Which channel to use",
          "items": [
            "The validator at vastlint.org/validate is the paste check for Companion structure.",
            "The tester at vastlint.org/tester shows which companion assets survived a live fetch.",
            "The inspector at vastlint.org/inspect is the wrapper chain tester when companions vanish after a hop.",
            "Problem pages cover companion ads not showing and IAB sizes 300x250 and 728x90."
          ]
        },
        {
          "type": "code",
          "heading": "Use the CLI when companion XML should block launch",
          "language": "sh",
          "code": "vastlint check companion-example.xml --format json\n\nvastlint check companion-example.xml --fail-on-warning"
        },
        {
          "type": "paragraphs",
          "heading": "What companion XML validation cannot prove",
          "paragraphs": [
            "A valid CompanionAds block is necessary. It does not prove the publisher page has a matching slot, or that the image CDN returned 200. Size mismatch is a trafficking problem, not a schema problem.",
            "Validate the XML, ship more than one IAB size, then test the live URL. On CTV, treat a missing banner as expected unless the platform documents companion support."
          ]
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "Companion ads format guide",
              "href": "/guides/vast-companion-ads/",
              "description": "CompanionAds, resource types, and tracking.",
              "source": "Guides"
            },
            {
              "label": "Companion ads not showing",
              "href": "/guides/vast-companion-ads-not-showing/",
              "description": "Empty Companion, required=all, wrappers, CTV ignore.",
              "source": "Guides"
            },
            {
              "label": "IAB companion sizes",
              "href": "/guides/vast-companion-sizes/",
              "description": "300x250, 728x90, 160x600, required width and height.",
              "source": "Guides"
            },
            {
              "label": "VAST validator",
              "href": "/validate/",
              "description": "Paste XML for companion rule checks.",
              "source": "Tool"
            },
            {
              "label": "VAST tester",
              "href": "/tester/",
              "description": "Fetch a live tag and review companion assets.",
              "source": "Tool"
            },
            {
              "label": "A Companion with no width is not a 300x250",
              "href": "https://dev.to/aleksuix/a-companion-with-no-width-is-not-a-300x250-the-player-cannot-match-it-45h7",
              "description": "Slot matching, required=all, and the warning that does not block until you fail on warning.",
              "source": "DEV"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Validate the companion XML",
          "paragraph": "Paste resolved XML into the validator. Fetch a live URL in the tester when you need to see which companions survived the chain.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        }
      ]
    },
    {
      "slug": "how-to-validate-vast-wrappers",
      "title": "How to Validate VAST Wrappers",
      "description": "Wrapper validation starts with VASTAdTagURI, chain depth, and the last hop. Catch missing redirects in XML, then inspect live hops when the player prints 303 or 302.",
      "publishedAt": "2026-08-29",
      "updatedAt": "2026-08-29",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Wrapper chains",
      "tags": [
        "Wrappers",
        "VAST",
        "Inspector",
        "How-to"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "Wrapper validation in VAST starts with the XML. If VASTAdTagURI is missing or empty, the chain is a dead end. If the chain is too deep, players fire 302. If wrappers resolve but the last hop is empty, players fire 303.",
            "vastlint can catch missing VASTAdTagURI and wrapper depth in pasted XML. Live hops need the inspector, which is the wrapper chain tester. Validate the wrapper document, then inspect the URL."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/how-to-validate-vast-wrappers.png?v=2",
          "alt": "A VAST wrapper chain fails three ways: an empty VASTAdTagURI never fetches, a chain past the depth limit returns error 302, and a chain that resolves to an empty inline returns error 303.",
          "width": 1440,
          "height": 820,
          "caption": "A green wrapper on the first hop does not mean the inline exists.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What wrappers are doing in the tag",
          "paragraphs": [
            "A wrapper is not the ad. It is a redirect that must hand the player a next VAST URL. That URL is VASTAdTagURI. Each hop can add impressions, tracking, and companions. The player stops when it reaches InLine or hits a platform depth limit.",
            "FollowAdditionalWrappers, allowMultipleAds, and followCompanions change what later hops may add. Mis-set flags look like missing creatives. They are wrapper policy, not a broken MediaFile."
          ]
        },
        {
          "type": "list",
          "heading": "What wrapper XML validation can catch before playback",
          "items": [
            "Wrapper without VASTAdTagURI.",
            "Empty or non-HTTPS redirect target.",
            "Chain depth that already exceeds typical player limits (often 3 to 5 hops).",
            "Ad that is neither InLine nor Wrapper.",
            "Wrapper ClickThrough that some VAST 4.0/4.1 players ignore."
          ]
        },
        {
          "type": "code",
          "heading": "A wrapper that should pass",
          "language": "xml",
          "code": "<VAST version=\"4.2\">\n  <Ad>\n    <Wrapper>\n      <AdSystem>Example Ad Server</AdSystem>\n      <VASTAdTagURI><![CDATA[https://ads.example.com/next-vast.xml]]></VASTAdTagURI>\n      <Impression><![CDATA[https://tracker.example.com/wrapper-imp]]></Impression>\n      <Creatives />\n    </Wrapper>\n  </Ad>\n</VAST>"
        },
        {
          "type": "code",
          "heading": "A wrapper that looks valid but should be flagged",
          "language": "xml",
          "code": "<VAST version=\"4.2\">\n  <Ad>\n    <Wrapper>\n      <AdSystem>Example Ad Server</AdSystem>\n      <Impression><![CDATA[https://tracker.example.com/wrapper-imp]]></Impression>\n    </Wrapper>\n  </Ad>\n</VAST>"
        },
        {
          "type": "list",
          "heading": "What the wrapper rule set should complain about",
          "items": [
            "VAST-2.0-wrapper-vastadtaguri because the redirect target is missing.",
            "VAST-2.0-wrapper-depth when the declared chain is already too long.",
            "VAST-2.0-ad-has-inline-or-wrapper when the Ad has neither.",
            "Player error 303 when hops succeed but the last response is empty VAST.",
            "Player error 302 when the player refuses another redirect."
          ]
        },
        {
          "type": "list",
          "heading": "Which channel to use",
          "items": [
            "The validator at vastlint.org/validate is the paste check for VASTAdTagURI and wrapper structure.",
            "The inspector at vastlint.org/inspect is the wrapper chain tester: each hop, each response, the hop that went empty.",
            "The tester at vastlint.org/tester is for the resolved InLine: media, tracking, companions.",
            "Error pages 303, 302, and 301 map the player code to the XML cause."
          ]
        },
        {
          "type": "code",
          "heading": "Use the CLI when wrapper XML should block launch",
          "language": "sh",
          "code": "vastlint check wrapper-example.xml --format json\n\nvastlint check wrapper-example.xml --fail-on-warning"
        },
        {
          "type": "paragraphs",
          "heading": "What wrapper XML validation cannot prove",
          "paragraphs": [
            "A wrapper with a well-formed VASTAdTagURI is necessary. It does not prove the next hop returns InLine, or that the CDN is up. No-fill 303 is often legitimate demand, not a tag bug.",
            "Validate the wrapper document, then inspect the live URL hop by hop. Do not treat a green XML paste as a green chain."
          ]
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "VAST inspector",
              "href": "/inspect/",
              "description": "Wrapper chain tester: hop-by-hop fetch and validation.",
              "source": "Tool"
            },
            {
              "label": "Wrapper chains guide",
              "href": "/guides/vast-wrapper-chains/",
              "description": "Depth limits, follow* attributes, latency.",
              "source": "Guides"
            },
            {
              "label": "Error 303",
              "href": "/docs/vast-error-codes/303/",
              "description": "No ads after wrappers. Empty last hop.",
              "source": "Docs"
            },
            {
              "label": "Missing VASTAdTagURI",
              "href": "/docs/missing-vastadtaguri/",
              "description": "Wrapper with no redirect target.",
              "source": "Docs"
            },
            {
              "label": "VAST validator",
              "href": "/validate/",
              "description": "Paste wrapper XML for spec checks.",
              "source": "Tool"
            },
            {
              "label": "A spec-valid video bid can still fill with empty VAST",
              "href": "https://rtblint.org/blog/video-bid-is-not-vast-proof/",
              "description": "OpenRTB can pass while the VAST inside is an empty wrapper, leftover SIMID, or a companion with no size.",
              "source": "RTBlint"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Inspect the live wrapper chain",
          "paragraph": "Paste the live VAST URL into the inspector. Use the validator when you already have a single hop of XML.",
          "href": "/inspect/",
          "label": "Open the VAST inspector"
        }
      ]
    },
    {
      "slug": "ctv-vast-readiness-four-gates",
      "title": "Spec-Valid VAST Passes One Gate. CTV Ad Ops Now Runs Four Before Launch.",
      "description": "Workshop polling on a nearly $30 billion CTV market put live-event forecasting and liveness signals ahead of creative approval. The readiness bar is structurally valid, environment-compatible, successfully executed, and observable, not XSD alone.",
      "publishedAt": "2026-08-29",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "Ad ops",
      "tags": [
        "CTV",
        "VAST",
        "Ad ops",
        "Live streaming",
        "CTV Ad Portfolio"
      ],
      "published": true,
      "featured": true,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "Connected TV is no longer an experiment channel. U.S. digital video advertising is projected to reach $81.9 billion in 2026, up 11% year over year, and CTV alone is projected at approximately $29.3 billion. Buyers still want television attention with digital accountability, but the operating question has shifted: not whether CTV can attract spend, but whether delivery, measurement, and creative can run repeatably at that scale.",
            "At IAB Tech Lab's August 2026 Ad Ops Workshop for Advanced TV, supply-chain leaders walked the full path from inventory definition through creative approval, live delivery, and outcome measurement. The through-line was a harder readiness test than most trafficking teams run today. A VAST tag can comply with the specification and still fail in its intended environment. Workshop attendees formalized what that means in practice."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/ctv-vast-readiness-four-gates.png?v=2",
          "alt": "Four gates in a row: structurally valid, environment-compatible, successfully executed, and observable. Passing the schema is only the first.",
          "width": 1440,
          "height": 820,
          "caption": "A VAST tag can comply with the specification and still fail in the environment it was sold into.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What \"ready\" actually measures",
          "paragraphs": [
            "The workshop did not treat validation as a single XSD pass. For ad ops, readiness is four conditions chained together: structurally valid, environment-compatible, successfully executed, and observable.",
            "Structurally valid is the part most teams already know: XML that matches the declared VAST version, required children present, HTTPS where the spec expects it. Environment-compatible means the creative matches the player, device class, and format path you sold. Pause and overlay inventory in the CTV Ad Portfolio travels on VAST NonLinear Ads tied to OpenRTB video objects; menu and home-screen inventory uses the Native API with video creative embedded as VAST inside the native payload. A tag that parses on a laptop but declares the wrong linearity or omits a NonLinear fallback an unaware player can render fails here even when the schema is clean.",
            "Successfully executed is playback under real latency and wrapper depth, not a curl from a desk. Observable is whether tracking, verification, and identity survive that path so reconciliation and frequency controls work downstream. Validation should begin during creative intake and partner QA, the workshop argued, not after a delivery failure or makegood."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Portfolio formats are moving from pilots to roadmaps",
          "paragraphs": [
            "The session opened on finalized CTV Ad Portfolio signaling for Pause, Screensaver, Overlay, Squeezeback, In-Scene, and Menu or Home Screen ads. Many formats already existed as publisher products; the new work makes them recognizable and transactable across buyers, sellers, and platforms.",
            "Audience polling at the workshop was small and directional, not a broad industry benchmark, but the pattern was clear. Of attendees who responded, 58% said their organizations already support at least one portfolio format. Another 33% planned to add support to their roadmap or begin evaluating technical requirements. No respondents expected to monitor adoption without acting.",
            "When asked which format they were most likely to support first, 54% selected Pause Ads, followed by Menu or Home Screen Ads at 15%. That ordering matters for VAST QA because pause inventory now carries duration, MediaFiles, optional SIMID interactivity, and quartile tracking on hardware that has never rendered a portfolio extension. Silent failure is common: an extension a player does not recognize is not a parse error and may not fire an Error ping if no native NonLinear fallback was included."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Creative approval is moving off the bidstream",
          "paragraphs": [
            "Standardizing inventory does not help if creative is still awaiting approval when a campaign should start. The Ad Management API offers a non-bidstream path to submit creative to an exchange before it enters the auction, returning structured approval status and actionable rejection reasons instead of a stalled delivery ticket.",
            "When asked what would accelerate adoption, publisher-level approval support led at 27%. More participating counterparties and consistent rejection reasons each received 18%, reinforcing that adoption depends on network participation as much as feature availability.",
            "On validation tooling, 36% of respondents were most likely to add structured VAST checks to creative intake or pre-launch QA. Another 27% selected automated workflow integration, and 27% planned to evaluate before changing their workflow. No one chose to continue with existing tools unchanged. The implied workflow is upstream: catch environment mismatch and broken media before the tag enters a live pod or SSAI stitch."
          ]
        },
        {
          "type": "list",
          "heading": "Live events reorder the sequence",
          "items": [
            "93% of buyers in IAB's 2026 spend research consider live content more valuable than other digital video, yet one-third still question whether the premium produces sufficient return.",
            "Live delivery compresses forecasting, traffic planning, creative preparation, decisioning, and infrastructure scaling into a short window: overtime, audience spikes, or unscheduled breaks create supply without time for manual intervention.",
            "When asked which Live Event Ad Playbook capability they would implement first, 46% chose structured event and inventory forecasting, 38% selected standardized live-inventory signals, and creative readiness and approval checks followed at 15%.",
            "The suggested sequence: establish a shared view of what is scheduled, identify live inventory consistently, then coordinate the systems that deliver it. Creative QA comes after the inventory story is trustworthy."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Agents need bounded readiness, not a permanent flag",
          "paragraphs": [
            "A separate workshop thread on creative readiness for agentic workflows drew a boundary around automation. A creative may be policy-approved but incompatible with a destination. It may be technically valid but not cached for a live event. Readiness therefore needs evidence, scope, authority, version, and expiration, not a single permanent approved bit.",
            "Half of respondents supported allowing an agent to apply technical fixes with human approval. Another 21% would allow approved classes of fixes automatically, and 21% preferred agents to recommend corrections. No one supported allowing an agent to modify creative content within a defined policy. The room was more comfortable automating preparation than creative decision-making.",
            "For VAST teams, that maps cleanly onto linting and structural fixes (HTTPS normalization, missing Duration, wrapper depth) versus changing the creative narrative. Machine-readable policies, bounded permissions, actionable errors, and audit trails expand automation without surrendering control."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Identity and outcomes still wait on coordination",
          "paragraphs": [
            "Mature operations also require connecting what ran with what happened afterward. On ECAPI, the Events and Conversion API framework for server-to-server marketing events, 45% of workshop respondents selected access to advertiser event data as the biggest barrier, not technical integration.",
            "On UniversalAdID and the Ad Creative ID Framework, buyer or advertiser demand and better frequency and separation controls each led at 33%, with publisher or marketplace requirements at 17%. Creative identity has to solve visible business problems before trafficking will enforce it in every tag."
          ]
        },
        {
          "type": "quote",
          "quote": "Publishing a specification is not the finish line. A standard creates value when it becomes part of real products and workflows, and when partners can rely on one another to interpret it consistently.",
          "attribution": "IAB Tech Lab, CTV Ad Ops workshop recap"
        },
        {
          "type": "list",
          "heading": "A pre-launch checklist aligned to the four gates",
          "items": [
            "Structurally valid: run spec checks on the declared VAST version, portfolio extensions, and HTTPS across media, tracking, and verification URLs.",
            "Environment-compatible: confirm NonLinear versus Linear expectations, portfolio format path, and a native NonLinear fallback where extensions may be ignored.",
            "Successfully executed: resolve the full wrapper chain under CTV latency budgets; validate final MediaFiles and mezzanine on the device classes in the line item.",
            "Observable: verify AdVerifications, tracking events, and UniversalAdId survive SSAI or wrapper hops so measurement and frequency controls match the buy.",
            "For live inventory: confirm forecasting and liveness signals are in place before you traffic the creative package."
          ]
        },
        {
          "type": "cta",
          "heading": "Run the structural gate at intake",
          "paragraph": "Paste portfolio or live-event VAST at creative intake before it enters trafficking. Fix structural and environment mismatches while rejection is cheap, not after a makegood.",
          "href": "/validate/",
          "label": "Validate VAST XML"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "CTV Ad Ops Grows Up: From Promising Capabilities to Repeatable Operations",
              "href": "https://iabtechlab.com/ctv-ad-ops-grows-upfrom-promising-capabilities-to-repeatable-operations/",
              "description": "Aug 2026 workshop recap: four-part readiness bar, portfolio adoption polls, Ad Management API, live-event LEAP priorities, agentic readiness boundaries.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB 2026 Digital Video Ad Spend and Strategy Report",
              "href": "https://www.iab.com/insights/2026-video-ad-spend-strategy/",
              "description": "$81.9B U.S. digital video and ~$29.3B CTV projections; live content value versus ROI skepticism cited in the workshop post.",
              "source": "IAB"
            },
            {
              "label": "CTV Ad Portfolio signaling guidance",
              "href": "https://iabtechlab.com/standards/ctv-ad-portfolio/",
              "description": "NonLinear VAST versus Native-with-embedded-VAST delivery paths for the six portfolio formats.",
              "source": "IAB Tech Lab"
            }
          ]
        }
      ]
    },
    {
      "slug": "vast-tester-is-not-the-inspector",
      "title": "A Live VAST URL Is Not a Paste. The Tester and the Inspector Do Different Jobs.",
      "description": "Paste XML checks the document you already have. A live tag URL is a fetch, a wrapper chain, and a different file on a different host. The tester previews that hop. The inspector walks every hop. Using the validator for both jobs is how the inline stays untested.",
      "publishedAt": "2026-08-26",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Tooling",
      "tags": [
        "VAST",
        "QA",
        "Wrappers",
        "CTV",
        "Ad ops"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "Three pages on vastlint.org get used as if they were one button. Validate pastes XML you already hold. The tester fetches a live tag URL, follows wrappers far enough to preview creative, tracking, and click URLs. The inspector walks the chain hop by hop and shows where it breaks. They share a rule catalog. They do not share a job.",
            "The mix-up is operational, not branding. A trafficker copies a VASTAdTagURI out of GAM, pastes it into a box labeled validator, and gets a green wrapper. The inline on hop three still has no Duration, an HTTP MediaFile, or an InteractiveCreativeFile the player will never load. The document they pasted was never the document that plays."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vast-tester-is-not-the-inspector.png?v=2",
          "alt": "Validate checks pasted XML with no network. The tester fetches a live URL and previews the creative. The inspector walks each wrapper hop and names where the chain breaks.",
          "width": 1440,
          "height": 820,
          "caption": "They share a rule catalog. They do not share a job.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What each page actually measures",
          "paragraphs": [
            "Validate is a document check. You paste or upload XML. The catalog runs on that tree. No network. No player. No second host. If the file in git is the file that will play, this is the right tool. CI belongs here.",
            "The tester is a live-tag check. You paste a URL. It fetches, resolves wrappers enough to show you the creative, the tracking pixels, and the click-through. That is the path when a partner says the tag works in our tool and you only have their URL.",
            "The inspector is a chain check. Same live URL, different output: every hop, every redirect, wrapper depth, and the InLine at the bottom. When fill dies as VAST error 302 or 303, this is the page. Validate will not tell you hop four 404s. The tester will show a preview if something eventually plays. The inspector names the hop that did not."
          ]
        },
        {
          "type": "code",
          "heading": "The URL you start with is often only hop one",
          "language": "xml",
          "code": "<VAST version=\"4.2\">\n  <Ad>\n    <Wrapper>\n      <VASTAdTagURI>https://ssp.example/vast?id=abc</VASTAdTagURI>\n      <Impression>https://adserver.example/imp</Impression>\n    </Wrapper>\n  </Ad>\n</VAST>"
        },
        {
          "type": "paragraphs",
          "heading": "Why hop one looks fine",
          "paragraphs": [
            "A Wrapper is allowed to be thin. Impression pixels on the wrapper are real. Duration is not on the wrapper. MediaFiles are not on the wrapper. SIMID lives on the inline InteractiveCreativeFile. OMID AdVerifications often appear only after the last redirect. Checking the wrapper against linear-creative rules is a category error.",
            "IAB recommends keeping wrapper depth bounded. The number is a chain property. You cannot observe it on a pasted wrapper document that never fetched the next URI. That is why a green paste and a dead device are compatible."
          ]
        },
        {
          "type": "list",
          "heading": "A working split",
          "items": [
            "File in the repo, CI, or a trafficking export you already unwrapped: validate.",
            "Partner sent a URL, you need to see creative, clicks, and trackers: tester.",
            "VAST 301, 302, 303, timeout, or allowMultipleAds dying mid-chain: inspector.",
            "Do not substitute /ad-tag-tester/ for either. That path is an alias, not a third job."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Run the live hop",
          "paragraphs": [
            "vastlint is independent of IAB Tech Lab. The pages cite the VAST spec because that is where Duration, wrappers, and error codes live. A green wrapper paste is not a green session. Fetch the URL. Then walk the hops."
          ]
        },
        {
          "type": "cta",
          "heading": "Test the live tag",
          "paragraph": "Paste the VAST URL the player will call. Preview creative, tracking, and clicks on the tester. If the chain is the question, open the same URL on the inspector and read every hop.",
          "href": "/tester/",
          "label": "Open the VAST tag tester"
        },
        {
          "type": "resources",
          "heading": "Next",
          "items": [
            {
              "label": "VAST inspector",
              "href": "/inspect/",
              "description": "Hop-by-hop wrapper chain. Depth, redirects, InLine handoff."
            },
            {
              "label": "Validate VAST XML",
              "href": "/validate/",
              "description": "Paste a document you already have. No fetch."
            },
            {
              "label": "How to validate VAST XML",
              "href": "/docs/validate-vast-xml/",
              "description": "Which tool for which artifact."
            }
          ]
        }
      ]
    },
    {
      "slug": "the-inline-is-a-different-host",
      "title": "The Wrapper You QA Is Not the Creative That Plays. The Inline Lives on Another Host.",
      "description": "A VAST wrapper can be spec-valid and still terminate on a different CDN, a different AdSystem, and a different MediaFile than the URL you tested. The session fails on the inline. Hop-one QA never sees that file.",
      "publishedAt": "2026-08-26",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Wrappers",
      "tags": [
        "VAST",
        "Wrappers",
        "SSAI",
        "CTV",
        "Ad ops"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "Most VAST tags in the wild are not InLine documents. They are a URI that returns a Wrapper, which returns another URI, which eventually returns the creative. The player follows that chain at playback. Your QA laptop often does not.",
            "The failure mode is stable. Someone validates the first response, files a green screenshot, and ships. The device then requests hop three, gets an HTTP MediaFile on HTTPS inventory, a missing Duration, or a 404 mezzanine, and reports a VAST error the trafficking ticket cannot reproduce from the original URL."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/the-inline-is-a-different-host.png?v=2",
          "alt": "Most VAST tags are wrappers. The creative is an InLine on a later host. QA that only opens the first document never sees the file that plays.",
          "width": 1440,
          "height": 820,
          "caption": "The player follows the chain at playback. A QA laptop often does not.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What the wrapper is allowed to omit",
          "paragraphs": [
            "A Wrapper carries VASTAdTagURI, optional Impression and tracking, and flags such as allowMultipleAds and fallbackOnNoAd. It does not have to carry Linear Duration. It does not have to carry MediaFiles. UniversalAdId, AdVerifications, and SIMID InteractiveCreativeFile typically sit on the InLine. Treating the wrapper as a complete creative is reading a cover letter as the contract.",
            "allowMultipleAds is a chain property. A wrapper that sets it false can kill a pod that looked fine on hop one. You will not see that in a paste of hop one unless you also fetch what it points at."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The host changes",
          "paragraphs": [
            "Hop one is often the ad server you traffic. Hop two is an SSP wrapper. Hop three is a CDN or a creative host you do not control. HTTPS on hop one does not imply HTTPS on hop three. Geo, user-agent, and app bundle on the device request are not the same as curl from your desk. A 200 in the office and a 403 on Fire TV are both real.",
            "SSAI stitchers add another hop: they fetch the chain, transcode, and emit a new document. Validating the pre-stitch wrapper and never the stitched output is how a living-room player sees a different MediaFile than the one in the ticket."
          ]
        },
        {
          "type": "list",
          "heading": "What to do before you call it QA",
          "items": [
            "Follow VASTAdTagURI until you have an InLine or you hit a fetch error. Count the hops.",
            "Check Duration, MediaFiles, mezzanine, and AdVerifications on the InLine, not on the first wrapper.",
            "Use the inspector when the question is which hop died. Use the tester when you need to see whether anything playable came back.",
            "Re-run the same URL from a CTV user-agent if the buy is CTV. Desk curl is not a Roku."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Walk the chain",
          "paragraphs": [
            "vastlint is independent of IAB Tech Lab and of the SSPs that mint these wrappers. The inspector fetches each hop and runs the same spec-derived catalog on every response. A green hop one is a statement about hop one."
          ]
        },
        {
          "type": "cta",
          "heading": "Inspect the wrapper chain",
          "paragraph": "Paste the live VAST URL. Read every hop, not only the first document. If you need a preview of what came back, use the tester on the same URL.",
          "href": "/inspect/",
          "label": "Open the VAST inspector"
        },
        {
          "type": "resources",
          "heading": "Next",
          "items": [
            {
              "label": "VAST tag tester",
              "href": "/tester/",
              "description": "Live URL, creative preview, tracking, click URLs."
            },
            {
              "label": "Wrapper depth",
              "href": "/docs/wrapper-depth-exceeded/",
              "description": "When the chain itself is the error."
            },
            {
              "label": "Missing VASTAdTagURI",
              "href": "/docs/missing-vastadtaguri/",
              "description": "A wrapper that cannot name the next hop."
            }
          ]
        }
      ]
    },
    {
      "slug": "acr-hdmi-measurement-without-vast",
      "title": "CTV measurement can run with no VAST tag. ACR still fingerprints HDMI when the set is a dumb display.",
      "description": "Samsung and LG automatic content recognition peaked on linear TV and HDMI in a 2024 living-room audit, including when a laptop or console used the set as a monitor. A green VAST tag does not prove the session was only measured by the creative.",
      "publishedAt": "2026-08-21",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Measurement",
      "tags": [
        "CTV",
        "ACR",
        "Measurement",
        "HDMI",
        "Smart TV"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "Connected TV QA is built around the tag. Resolve the wrappers, confirm a MediaFile, watch impression and quartile beacons. That workflow measures the creative path. It does not measure the operating system. Automatic content recognition sits in the TV firmware, hashes what is on the panel, and sends that fingerprint to a platform endpoint. No VAST document has to exist for that hop to fire.",
            "An IMC 2024 living-room audit ran that check on Samsung and LG sets in the UK and the US, two platforms the authors cite at about 23 percent and 18 percent market share. They compared linear antenna TV, the manufacturer's FAST app, third-party OTT apps, HDMI from a laptop or console, screen casting, and an idle homepage. The result that matters to anyone shipping video ads is not a fraud score. It is that the loudest ACR traffic was linear TV and HDMI, including when the set was a dumb external display."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/acr-hdmi-measurement-without-vast.png?v=2",
          "alt": "VAST measurement follows the creative and its beacons. Automatic content recognition fingerprints the TV panel, including HDMI input, and does not need a VAST document.",
          "width": 1440,
          "height": 820,
          "caption": "A valid impression and an ACR match can describe different pictures on the same set.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What the metric actually measures",
          "paragraphs": [
            "The audit is black-box network traffic between the TV and known ACR domains. It does not decrypt payloads. It does not prove which programme was identified. It does prove when the ACR client was talking. Highest volume was linear and HDMI. Other scenarios were much quieter; peaks dropped by up to 12 times, which the authors read as the client often not sending fingerprints. Third-party OTT apps such as Netflix and YouTube did not produce the ACR traffic that linear and HDMI did.",
            "LG's documentation says the client captures frames every 10 milliseconds. Observed network traffic was about every 15 seconds, which they treat as batching. Samsung talked to several of its own ACR hosts; LG talked to a single Alphonso domain that rotates a numeric label. UK hosts used EU in the name. US hosts used US, and those IPs geolocated in the United States.",
            "This is second-party measurement by the platform, not a tracker inside the creative. It is also not the hidden-webview IVT pattern, where a concealed browser forges attention metrics. ACR is the TV looking at its own framebuffer. A valid VAST impression and an ACR match can describe different objects: the ad that played, versus whatever was on the glass, including a game or a laptop window."
          ]
        },
        {
          "type": "quote",
          "quote": "Linear TV and HDMI produced the most ACR traffic. A clean VAST tag never sees that hop.",
          "attribution": "delivery triage note"
        },
        {
          "type": "paragraphs",
          "heading": "HDMI, FAST, and the two countries",
          "paragraphs": [
            "HDMI is the case buyers forget. A console or a laptop on the HDMI input still generated ACR in the audit. The user is not in a publisher app. There is no SSAI stitcher and no VAST wrapper. The panel is still a Samsung or LG, and the firmware still samples the screen. If your brand-safety or incremental-reach story assumes measurement only happens when an ad tag plays, HDMI passthrough is outside that story and still inside the platform's graph.",
            "FAST is not one behavior. In the UK, manufacturer FAST apps (Samsung TV+, LG Channels) sat with the quieter scenarios. In the US, those same apps produced ACR traffic comparable to linear. The paper's working explanation is different content agreements, not a different TV. Login status did not matter in either country: logged-in and logged-out traces looked the same. Turning off viewing information services stopped all traffic to the ACR domains they had identified. No new ACR hosts appeared after that opt-out.",
            "HbbTV overlays on broadcast are a cousin, not this mechanism. They are still not a VAST tag. Do not fold them into ACR, and do not fold ACR into a pixel-fraud post."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Two pipes, one living room",
          "paragraphs": [
            "The creative pipe is VAST, VMAP, SSAI, OMID, impression and quartile URLs. vastlint reads that pipe. The platform pipe is ACR: framebuffer, fingerprint, vendor endpoint, audience segment on the TV OS ad system. Buyers who reconcile complete rates against Samsung or LG ACR audiences as if they were the same impression will argue with both vendors and still be looking at two clocks.",
            "Pod and stitch failures hide in the creative pipe. HDMI and linear ACR hide in the platform pipe. A tag that 403s on Fire TV never reaches a quartile; ACR can still have hashed the programme that ran in that hour. A tag that plays cleanly on a phone app in the same open CTV line item never touches the Samsung ACR client in the living room. Open programmatic CTV already splits spend across TV OS and mobile. ACR is an extra split on the TV OS half: tagged playback versus screen hashing."
          ]
        },
        {
          "type": "list",
          "heading": "What to do",
          "items": [
            "Treat platform ACR as a measurement surface with its own opt-out, geography, and input path. Do not file it under VAST QA.",
            "When the buy includes Samsung or LG large screens, assume HDMI and linear can be hashed even if your tag never loaded.",
            "Do not copy a UK FAST assumption onto a US FAST line item. The audit saw ACR on US manufacturer FAST at linear-like volume.",
            "Account login is not the ACR switch in this audit. Viewing information services off was.",
            "Split reporting: tag-based completes versus platform ACR audiences. If they move together, that is a coincidence until proven.",
            "Still validate the trafficked VAST. A broken MediaFile is a different loss. The linter catching it does not census ACR."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The tag still has to play",
          "paragraphs": [
            "Paste production tags into the validator before they hit the stitcher or the exchange. vastlint checks structural consistency, MediaFile and mezzanine presence, HTTPS, wrapper depth, and spec-derived rules from VAST 2.0 through 4.4. It does not detect ACR, fraud, bots, or whether a TV hashed the programme. Independent of Samsung, LG, and of the IMC paper. A green tag means the creative document is consistent. It does not mean the living room was unmeasured."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate the creative pipe",
          "paragraph": "Run VAST tags through specification-derived rules so MediaFile, tracker, and wrapper consistency are visible. ACR on HDMI is a different hop; it will not appear in this paste.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Watching TV with the Second-Party: A First Look at Automatic Content Recognition Tracking in Smart TVs",
              "href": "https://arxiv.org/abs/2409.06203",
              "description": "Anselmi, Vekaria, D'Souza, Callejo, Mandalari, Shafiq. IMC 2024. Black-box ACR traffic on Samsung and LG in the UK and US: linear and HDMI peaks, 12 times quieter other scenarios, 10 ms capture versus 15 s batching on LG, opt-out stops ACR domains, login does not, US FAST unlike UK.",
              "source": "arXiv:2409.06203"
            },
            {
              "label": "IMC 2024 ACM record",
              "href": "https://doi.org/10.1145/3646547.3689013",
              "description": "Published proceedings version of the same measurement.",
              "source": "ACM"
            },
            {
              "label": "Audit code and data",
              "href": "https://github.com/SafeNetIoT/ACR",
              "description": "Authors' reproduction package for the ACR traffic experiments.",
              "source": "GitHub"
            }
          ]
        }
      ]
    },
    {
      "slug": "open-programmatic-ctv-two-playback-surfaces",
      "title": "Open Programmatic CTV Runs on TV Sets and Phone Apps in Nearly Equal Measure. One VAST Tag Still Has to Play on Both.",
      "description": "Pixalate's June 2026 report puts 57% of U.S. open programmatic CTV spend on large-screen devices and 43% on phones and tablets. Buyers who QA a tag on one surface are blind to the playback failures waiting on the other half of the same inventory class.",
      "publishedAt": "2026-08-20",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "CTV delivery",
      "tags": [
        "CTV",
        "VAST",
        "Programmatic",
        "SSAI",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "MediaPost reported in August on a June 2026 Pixalate study of U.S. open programmatic connected TV: large-screen devices, smart TV sets, account for 57% of that spend, and 43% runs on small-screen devices, phones, tablets, and other iOS and Android surfaces. The headline is a device split, not a fraud score or a fill-rate chart. It still matters to anyone shipping VAST, because open exchange CTV is not one player environment. It is two, traded under one label.",
            "The same article cites Pixalate on scope: open programmatic streaming buys, public RTB auctions open to any demand-side platform buyer, are roughly 18% to 19% of overall U.S. CTV ad spend, about $6 billion to $7.5 billion against industry estimates of $33.1 billion to $40.4 billion total. That is a minority of CTV dollars, but it is the slice where a generic tag meets the widest device mix without a curated deal wrapper to narrow the path."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/open-programmatic-ctv-two-playback-surfaces.png?v=2",
          "alt": "Pixalate's June 2026 study, via MediaPost, puts 57 percent of US open programmatic CTV spend on large screens and 43 percent on phones and tablets. One VAST tag has to play in both regimes.",
          "width": 1440,
          "height": 820,
          "caption": "Open CTV is traded as one category and delivered as two player stacks.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What the metric actually measures",
          "paragraphs": [
            "Pixalate's figures describe where open programmatic CTV money lands by screen class and, within large screens, by TV operating system. On large screens, Amazon Fire TV accounts for 30% of open TV programmatic ad spend, Roku for 18%, Samsung Smart TV for 5%, and Apple TV for 4%. Warner Bros. Discovery properties show up heavily in network-level open deal concentration: Food Network at 34%, CNN at 20%, Investigation Discovery at 7%, TLC at 4%, and Animal Planet at 2% among the top ten by spend.",
            "Genre and daypart skew differently by surface. Reality-unscripted and news programming pull in 41% and 23% of open programmatic ad deals respectively. New programming dominates small-screen spend at 64%. Morning hours, 6 a.m. to noon, hold a 30% share of large-screen open programmatic spend; overnight, 11 p.m. to 6 a.m., holds a 31% share on small screens.",
            "None of that is a statement about whether a given impression rendered. It is a spend and deal-composition map. The population is U.S. open programmatic CTV as Pixalate measured it in June 2026, not all CTV (private marketplace and programmatic guaranteed are excluded from the open slice, though MediaPost notes that programmatic transactions overall, including PMP and PG, represent around 84% to 88% of all U.S. CTV ad spending). The takeaway for delivery teams is simpler: when you buy open CTV programmatic, you are not buying a living-room-only path. You are buying a portfolio that is almost evenly split between TV OS players and mobile apps."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why one tag fails on two surfaces",
          "paragraphs": [
            "Operations teams often treat CTV QA as a single checklist: resolve the wrapper chain, confirm HTTPS, spot-check one MP4. That workflow assumes one dominant player class. The 57/43 split breaks the assumption. A tag that plays in a mobile app WebView or native player may still die on a Fire TV or Roku with VAST error 403, could not find a MediaFile supported by this player, because the codec, container, bitrate cap, or absence of a mezzanine file matters on the TV side and not on the phone side.",
            "The IAB VAST CTV addendum exists because web-sized renditions are not interchangeable with living-room playback. Mezzanine files, higher-resolution masters for SSAI transcoding, and explicit MediaFile typing are written for large-screen delivery paths. Mobile inventory in the same open bucket may accept a lighter progressive MP4 and never touch a stitcher. SSAI on FAST and broadcaster apps on the large-screen half expects something to transcode; a single 800 kbps web rendition that clears mobile QA gives the stitcher nothing useful and the TV player nothing better to select.",
            "Platform share compounds the problem. Fire at 30% and Roku at 18% of large-screen open spend means the TV half of your open CTV line item is concentrated on two player stacks with different manifest, codec, and interactivity histories. A tag tested only on Samsung's player or only in an Android tablet app does not prove compatibility on either dominant TV OS. Genre skew adds a planning mistake: reality and news lean large screen; new programming leans small. A creative cut for one genre mix can under-serve the other if MediaFiles are not duplicated or if mezzanine coverage is missing where SSAI sits in the path."
          ]
        },
        {
          "type": "quote",
          "quote": "Open CTV is traded as one category and delivered as two player regimes. The spend data says so in almost equal percentages.",
          "attribution": "delivery triage note"
        },
        {
          "type": "paragraphs",
          "heading": "The mechanism in the document",
          "paragraphs": [
            "The failure shows up in the VAST payload, not in the bid request headline. Wrapper depth and timeout behavior hit both surfaces, but MediaFile selection is where the split bites. A Linear creative with one progressive MP4 may validate in a browser-based tool and still omit Mezzanine, which vastlint flags at info severity with the note that ad-stitching servers may reject the tag in CTV and SSAI contexts. Interactive assumptions diverge too: SIMID and native controls on TV, lighter non-linear or static fallbacks on mobile, and legacy VPAID dependencies that TV platforms dropped years ago but mobile wrappers still tolerate.",
            "Measurement follows playback. Quartile and complete events only mean something if the player chose a MediaFile and started decoding. An impression pixel that fires on ad load while the TV player rejects every rendition is the same silent loss as a stitch timeout, except the campaign report shows delivery until someone reconciles player logs. Daypart skew makes that harder to catch in QA: morning-heavy large-screen spend and overnight-heavy mobile spend mean a tag checked at noon in a desktop inspector never sees the traffic mix that will actually run."
          ]
        },
        {
          "type": "list",
          "heading": "Checks worth running before launch",
          "items": [
            "Resolve the full wrapper chain on both a TV OS test device and a mobile app path, not only in a desktop VAST inspector.",
            "Confirm at least one TV-safe MP4 rendition plus mezzanine or stitcher-approved master when the supply path includes SSAI or broadcaster FAST apps.",
            "Match MediaFile type, width, height, and bitrate claims to the platforms in the Pixalate large-screen mix you actually buy (Fire and Roku first).",
            "Require HTTPS on every tracker and media URL; mixed content blocks TV players more aggressively than mobile WebViews.",
            "Split reporting by app surface where your ad server allows it; aggregate CTV line items hide the 403 rate on the TV half.",
            "Re-run validation on the trafficked tag after any transcode or dynamic creative step that replaces MediaFiles downstream."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do",
          "paragraphs": [
            "Treat open programmatic CTV as a dual-environment launch. The buy-side label says CTV; the spend map says 57% TV OS and 43% mobile. Your QA plan should mirror that ratio instead of assuming the living room is the whole story.",
            "Paste production tags into the validator before they reach the exchange or the stitcher. vastlint checks structural consistency, MediaFile and mezzanine presence, HTTPS, wrapper depth, and spec-derived rules from VAST 2.0 through 4.4. It does not detect fraud, bots, or whether an impression was valid. It catches malformed or inconsistent payloads that fail on one surface while appearing to pass on another."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate the tag against both playback regimes",
          "paragraph": "Run VAST tags through specification-derived rules so MediaFile, mezzanine, and tracker consistency are visible before the tag hits open CTV paths split across TV and mobile.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Study Finds More Than Half Of CTV Programmatic Served On Large Screens",
              "href": "https://www.mediapost.com/publications/article/416951/study-finds-more-than-half-of-ctv-programmatic-ser.html",
              "description": "MediaPost coverage of Pixalate's June 2026 U.S. open programmatic CTV spend split (57% large screen, 43% small screen), platform shares, genre and daypart concentration, and open vs total CTV spend context.",
              "source": "MediaPost"
            },
            {
              "label": "VAST CTV Addendum 2024",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "IAB guidance on mezzanine files, high-resolution MediaFiles, and large-screen delivery expectations in VAST.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAS vs Pixalate puts a named mobile cluster next to a quarterly open-auction share",
              "href": "/blog/ias-vs-pixalate/",
              "description": "Why Papyrus click, eCPM, and attention gaps are a different measurement from Pixalate's Q4 2025 IVT shares.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "hidden-webview-fraud-manipulates-attention-metrics",
      "title": "Hidden Webview Fraud Can Make Invalid Traffic Look More Valuable Than the Real Thing",
      "description": "IAS Threat Lab's August 2026 Papyrus report documents novel-reading apps that load concealed browser windows, automate clicks and scrolls, and produce roughly 25 times the click success rate, 4 times the eCPM, and 13 percent higher attention scores than clean traffic. Buyers optimizing on engagement metrics will bid up the worst supply unless measurement separates synthetic interaction from intent.",
      "publishedAt": "2026-08-16",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "Measurement",
      "tags": [
        "IVT",
        "Attention",
        "Mobile fraud",
        "Viewability",
        "Video measurement"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "On August 6, IAS Threat Lab published research on a mobile scheme it calls Papyrus: novel-reading apps that keep a legitimate interface on screen while hidden webviews load monetized destinations, register clicks from user taps routed into the background, and scroll pages on remote instruction. The traffic is not only invalid. In IAS analysis it looked more valuable than clean supply: nearly 25 times the click success rate, roughly 4 times the eCPM, and about 13 percent higher attention scores than non-Papyrus traffic. IAS estimates the operation may have generated close to $1 million per month in monetization impact at its peak, spanning more than 800 domains and nearly 8,000 unique host values.",
            "That inversion is the argument. Fraud that inflates the metrics buyers optimize on does not read as fraud in a dashboard. It reads as performance."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/hidden-webview-fraud-manipulates-attention-metrics.png?v=2",
          "alt": "Papyrus keeps a novel-reading interface on screen while hidden webviews load other sites, take routed taps as clicks, and scroll on remote instruction. IAS measured much higher clicks, eCPM, and attention than non-Papyrus traffic.",
          "width": 1440,
          "height": 820,
          "caption": "Invalid traffic that looks better than the residual gets bid up.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What the metrics actually measure",
          "paragraphs": [
            "Click success rate, eCPM, and attention scores are downstream of events: page loads, pointer events, scroll depth, time in view. Papyrus separates the user-visible session (reading inside the app) from the monetized session (hidden webviews driven by BootNova command-and-control infrastructure). User taps on the reading UI can be passed into concealed webviews through click modules. Separate scroll modules inflate engagement on pages the user never saw.",
            "IAS is explicit that the scheme goes beyond hidden traffic generation and actively manipulates the metrics buyers rely on. A hidden page load alone creates invalid traffic. Hidden loads plus automated clicks and scrolling distort performance and attention-based evaluation, which pushes optimizers toward the fraudulent path because the signals look like high-intent inventory.",
            "The population behind the headline numbers is Papyrus-associated supply compared with non-Papyrus traffic in IAS observation. That is not all mobile fraud and not all defended campaigns. It is a named cluster IAS filtered after identification. The magnitude still matters: if synthetic interaction lifts attention 13 percent and eCPM 4x, any bidder using those signals as quality proxies will overweight the scheme until something breaks the feedback loop."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The mechanism",
          "paragraphs": [
            "Papyrus is built around long reading sessions. Utility apps open briefly; reading apps stay foreground for minutes. That window feeds background webview activity while the visible app looks normal. BootNova workers (WebViewOut) attach webviews behind the UI through native layering (CWebViewPlugin, cover views). Embedded and server-delivered JavaScript instruments pages, captures coordinates, mutes media, auto-clicks consent dialogs, and executes scroll logic the operator can change without shipping a new app build.",
            "Destinations skew toward gaming, blog, news-style, and generative-AI content domains: synthetic web properties built for monetization rather than audience. The operation is consumer-powered rather than classic datacenter bots: real devices, real installs, real taps, but the path from tap to ad engagement is hijacked.",
            "For video and display measurement, the lesson generalizes beyond mobile webviews. Any stack that treats interaction events as proof of value without binding them to the surface the user actually watched is vulnerable to the same inflation. SSAI with client-side tracking, wrapped VAST with third-party verification pixels, OMID sessions where the creative container is not the surface receiving input: each has a version of this gap if engagement beacons fire on synthetic activity."
          ]
        },
        {
          "type": "quote",
          "quote": "Invalid traffic that looks worse than clean traffic gets filtered. Invalid traffic that looks better gets bid up. The fraud operator's job is to cross that line.",
          "attribution": "measurement triage note"
        },
        {
          "type": "paragraphs",
          "heading": "What to do",
          "paragraphs": [
            "Pre-bid IVT lists and domain blocklists catch known Papyrus destinations after someone else labels them. They do not explain why attention and click metrics lied. Structural checks still earn their place:",
            "Separate volume metrics from quality metrics in reporting. If attention and CTR move while viewability and completion stay flat, you are measuring interaction inflation, not audience gain.",
            "Audit whether verification and viewability tags are bound to the player surface that received the user's attention, not a sibling webview or invisible layer.",
            "On the tag side, validate that tracking events in VAST and VPAID successors reference consistent creative IDs and that wrapper chains do not drop AdVerifications or OMID companions that would expose the mismatch.",
            "Paste production tags into the validator before launch. vastlint checks structural consistency (required elements, tracker URLs, verification placement). It does not detect fraud or bots. It catches malformed payloads that break measurement before you can even ask whether the clicks were real."
          ]
        },
        {
          "type": "list",
          "heading": "Signals worth splitting in QA",
          "items": [
            "High click or engagement rates with flat or falling viewability/completion on the same line item",
            "Large gaps between client-reported time and verification-reported time on the same impression ID",
            "Creative loads that succeed while OMID or verification companions fail schema or URL checks",
            "Wrapper chains where Impression fires but AdVerifications never appear in the parsed document"
          ]
        },
        {
          "type": "cta",
          "heading": "Validate tracking and verification before you trust the metrics",
          "paragraph": "Run VAST 2.0 through 4.4 tags against specification-derived rules so verification companions and impression events are present and consistent. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "Papyrus: Inside a Mobile Scheme Built to Fake Clicks, Scrolls, and Attention",
              "href": "https://integralads.com/insider/papyrus-inside-a-mobile-scheme-built-to-fake-clicks-scrolls-and-attention/",
              "description": "IAS Threat Lab research published August 6, 2026. Primary for click, eCPM, attention, domain, and revenue estimates.",
              "source": "Integral Ad Science"
            },
            {
              "label": "How to validate OMID in VAST tags",
              "href": "/docs/omid/",
              "description": "Verification placement and OMID companion checks.",
              "source": "vastlint"
            },
            {
              "label": "How to validate VAST trackers before launch",
              "href": "/blog/how-to-validate-vast-trackers-before-launch/",
              "description": "Tracker URL and event consistency before traffic hits measurement.",
              "source": "vastlint"
            },
            {
              "label": "IAS vs Pixalate puts a named mobile cluster next to a quarterly open-auction share",
              "href": "/blog/ias-vs-pixalate/",
              "description": "Why Papyrus click, eCPM, and attention gaps are a different measurement from Pixalate's Q4 2025 IVT shares.",
              "source": "vastlint"
            },
            {
              "label": "Viewability vs attention compares a pixel threshold with a score built on interaction",
              "href": "/blog/viewability-vs-attention/",
              "description": "Why Papyrus could raise attention without the person watching the ad.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vast-4-4-empty-wrapper-schema-valid",
      "title": "An Empty VAST Wrapper Is Schema-Valid in 4.4. It Was Not in 2.0.",
      "description": "One compositor change in the VAST 4.4 draft schema makes AdSystem, Impression and VASTAdTagURI optional on every wrapper, lets singular elements repeat, and drops element ordering. Here is the reproduction and what it means if you gate on the XSD.",
      "publishedAt": "2026-08-09",
      "author": "Alex Sekowski",
      "readingTime": "6 min read",
      "heroKicker": "Standards",
      "tags": [
        "VAST 4.4",
        "XSD",
        "Wrapper",
        "Validation",
        "IAB Tech Lab"
      ],
      "published": true,
      "featured": true,
      "body": [
        {
          "type": "paragraphs",
          "paragraphs": [
            "A VAST wrapper with no AdSystem, no VASTAdTagURI and no Impression validates against the VAST 4.4 draft schema. The same document has been invalid in every version from 2.0 through 4.2. It is one line of XSD, and it is almost certainly a side effect of the CTV Ad Portfolio restructure rather than a decision anyone made on purpose.",
            "I have filed it with IAB Tech Lab. This post is the working, because the reproduction is short enough that anyone can check it in about a minute."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vast-4-4-empty-wrapper-schema-valid.png?v=2",
          "alt": "A VAST wrapper with no AdSystem, VASTAdTagURI, or Impression is invalid from version 2.0 through 4.2 and valid against the 4.4 draft schema because the content model is an unbounded choice with minimum zero.",
          "width": 1440,
          "height": 820,
          "caption": "The empty wrapper is the headline. Optional, repeating, and unordered children come with it.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "The change",
          "paragraphs": [
            "In vast_4.4.xsd on master, both vastInLine_type and vastWrapper_type wrap their children in a single compositor: an xs:choice with minOccurs zero and maxOccurs unbounded.",
            "That looks harmless. It is the idiom people reach for when they want to say \"these children may appear in any order\". What it actually says is stronger than that. In XSD, the cardinality on the compositor governs the content model, and the minOccurs on the individual child elements only describes a single selection from the choice. Set the choice itself to zero-or-more and every constraint underneath it stops binding.",
            "So the children still declare minOccurs=\"1\". They are still, in effect, optional."
          ]
        },
        {
          "type": "code",
          "heading": "The compositor in question",
          "language": "xml",
          "code": "<!-- vast_4.4.xsd, vastWrapper_type and vastInLine_type -->\n<xs:choice minOccurs=\"0\" maxOccurs=\"unbounded\">\n  <xs:element name=\"AdSystem\"     type=\"vastAdSystem_type\"/>\n  <xs:element name=\"VASTAdTagURI\" type=\"vastURIElement_type\"/>\n  <xs:element name=\"Impression\"   type=\"vastImpression_type\"/>\n  <xs:element name=\"Creatives\"    type=\"vastCreatives_type\"/>\n  <!-- ... -->\n</xs:choice>"
        },
        {
          "type": "paragraphs",
          "heading": "Three consequences, not one",
          "paragraphs": [
            "The empty wrapper is the headline, but the compositor gives up three separate guarantees at once. Each is reproducible with xmllint against the published schema."
          ]
        },
        {
          "type": "list",
          "heading": "What now validates in 4.4",
          "items": [
            "Everything is optional. An empty <Wrapper/> validates. So does an empty <InLine/>, with no AdSystem, no AdTitle, no Impression and no Creatives.",
            "Everything repeats. maxOccurs=\"unbounded\" on the choice means any branch can be selected repeatedly, so three <AdSystem> elements in one InLine validate, even though AdSystem has always been exactly one.",
            "Order stops mattering. 4.2 used xs:sequence, so the order was fixed. A choice imposes none, so <Impression> before <AdSystem> validates."
          ]
        },
        {
          "type": "code",
          "heading": "Reproduction: all three validate against the published 4.4 schema",
          "language": "xml",
          "code": "<!-- 1. empty wrapper -->\n<VAST version=\"4.4\" xmlns=\"http://www.iab.com/VAST\">\n  <Ad id=\"a\"><Wrapper/></Ad>\n</VAST>\n\n<!-- 2. empty inline -->\n<VAST version=\"4.4\" xmlns=\"http://www.iab.com/VAST\">\n  <Ad id=\"a\"><InLine/></Ad>\n</VAST>\n\n<!-- 3. AdSystem three times -->\n<VAST version=\"4.4\" xmlns=\"http://www.iab.com/VAST\">\n  <Ad id=\"a\">\n    <InLine>\n      <AdSystem>A</AdSystem>\n      <AdSystem>B</AdSystem>\n      <AdSystem>C</AdSystem>\n    </InLine>\n  </Ad>\n</VAST>"
        },
        {
          "type": "code",
          "heading": "Check it yourself",
          "language": "bash",
          "code": "curl -sO https://raw.githubusercontent.com/InteractiveAdvertisingBureau/vast/master/vast_4.4.xsd\nxmllint --noout --schema vast_4.4.xsd empty-wrapper.xml\n# empty-wrapper.xml validates\n\n# the same shape against 4.2\nxmllint --noout --schema vast_4.2.xsd empty-wrapper-42.xml\n# Element 'Wrapper': Missing child element(s). Expected is ( AdSystem )."
        },
        {
          "type": "paragraphs",
          "heading": "What 4.2 actually required",
          "paragraphs": [
            "The contrast is worth being precise about, because the requirement did not live where you might expect. In 4.2, Wrapper_type extends AdDefinitionBase_type, and it is the base type that carries the required fields: AdSystem exactly once, Impression once or more. Wrapper_type then adds VASTAdTagURI as required and Creatives as optional. Both use xs:sequence.",
            "Impression in particular has been required on wrappers since 2.0. That is a twenty-year-old constraint, and the wrapper is exactly where it matters most, because a wrapper that fires no impression is a measurement hole in the middle of a chain."
          ]
        },
        {
          "type": "quote",
          "quote": "The schema went from expressing a content model to enumerating a vocabulary. Those are different jobs, and only one of them can gate anything.",
          "attribution": "vastlint standards note"
        },
        {
          "type": "paragraphs",
          "heading": "Why this matters if you gate on the XSD",
          "paragraphs": [
            "Plenty of teams treat the published XSD as an acceptance gate: ad server ingest checks, partner certification, QA rigs that reject anything the schema will not accept. For those, 4.4 currently passes wrapper responses that cannot deliver an ad and cannot record an impression.",
            "It also sharpens a question the working group was already asking in a separate thread about whether the XSD is meant to be usable as a validator at all. My answer has not changed: it is not, and it never fully was. The prose has always carried requirements the schema does not express, which is the reason a rule-based validator exists in the first place. But there is a difference between a schema that is incomplete and a schema that is more permissive than the version it supersedes.",
            "The practical takeaway for anyone shipping 4.4 today: do not loosen your own checks to match the draft. Keep requiring AdSystem, Impression and VASTAdTagURI on wrappers, because the prose still does and every prior version did."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The likely fix",
          "paragraphs": [
            "If the intent was order-independence, xs:all expresses that while keeping per-element cardinality intact. XSD 1.0 limits xs:all particles to maxOccurs one, so repeating elements like Impression need handling, but the required ones stay required.",
            "If the intent really was a fully open content model, then the schema and the prose have diverged and the annotation should say so out loud, so that nobody builds a gate on top of it expecting otherwise.",
            "Either way it is a small patch. I have offered to write it."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate a 4.4 tag against the prose, not just the schema",
          "paragraph": "vastlint checks VAST 2.0 through the 4.4 draft against rules derived from the specification text, not only the XSD, so a wrapper missing AdSystem or Impression still fails. Paste a tag and see. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "IAB Tech Lab VAST issue #58",
              "href": "https://github.com/InteractiveAdvertisingBureau/vast/issues/58",
              "description": "The filed report, with the full reproduction and the 4.2 comparison table.",
              "source": "GitHub"
            },
            {
              "label": "vast_4.4.xsd on master",
              "href": "https://github.com/InteractiveAdvertisingBureau/vast/blob/master/vast_4.4.xsd",
              "description": "The published draft schema. See vastInLine_type and vastWrapper_type.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VAST 4.4: what actually shipped",
              "href": "/docs/vast-4-4/",
              "description": "The full technical breakdown of the 4.4 draft, content model by content model.",
              "source": "vastlint"
            },
            {
              "label": "VAST 4.3 to 4.4 migration guide",
              "href": "/docs/vast-4-3-to-4-4/",
              "description": "Element-by-element changes with a migration checklist.",
              "source": "vastlint"
            },
            {
              "label": "Wrapper chains and where they break",
              "href": "/guides/vast-wrapper-chains/",
              "description": "What a wrapper has to carry for a chain to resolve and measure correctly.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "podcast-measurement-2-3-vast-audio-tracking",
      "title": "Podcast Measurement Counts Downloads. VAST Counts Events. Version 2.3 Sharpens One and Leaves the Other Alone.",
      "description": "The Podcast Technical Measurement Guidelines v2.3 went out for public comment on 21 July and close on 19 August. They stay anchored to server side log analysis because most podcast apps never confirm playback. An audio ad tag is a VAST document, VAST counts from the client, and the two systems have been describing the same ad break with different arithmetic since DAAST folded into VAST 4.1. The video podcast clause is where they finally collide.",
      "publishedAt": "2026-08-08",
      "author": "Alex Sekowski",
      "readingTime": "10 min read",
      "heroKicker": "Audio and podcast",
      "tags": [
        "Audio",
        "DAAST",
        "Measurement",
        "VAST tracking",
        "Standards"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Two counting systems, one ad break",
          "paragraphs": [
            "IAB Tech Lab released version 2.3 of the Podcast Technical Measurement Guidelines on 21 July 2026, with a 30 day public comment window that closes on 19 August. The guidelines are the reason podcast numbers from different measurement vendors can be compared at all, and the reason they exist in their current form is a constraint that has not moved in a decade: most podcast applications never tell the server whether anyone played the file. There is no client to ask. So the industry counts what the server can see, which is a request for bytes.",
            "That approach is stated plainly in the release. Server side log analysis remains the backbone, because client side playback confirmation is not available across the open RSS ecosystem. Everything downstream follows from it. A download is inferred from a byte threshold rather than observed from a player, duplicates are collapsed inside a time window, and known invalid traffic is filtered by list rather than by behaviour.",
            "Now look at the ad inside that episode. If it was trafficked programmatically, it arrived as a VAST document, because DAAST was deprecated and folded into VAST 4.1 in 2018 and audio has been a first class media type in VAST ever since. VAST counts differently. It counts an impression when a client fires a pixel, a start when playback begins, quartiles as the ad progresses, and a complete when it ends. Every one of those numbers comes from a player that decided to make an HTTP request.",
            "So the same ad break is measured twice, by two systems, with two definitions of the event, and nothing in either specification reconciles them. None of that is new. Version 2.3 adds a clause that makes the gap visible to people who had never had to think about it."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/podcast-measurement-2-3-vast-audio-tracking.png?v=2",
          "alt": "IAB podcast measurement counts a request for bytes because most apps never report playback. VAST audio counts player events. Podcast measurement 2.3 sharpens the download count and does not turn it into VAST events.",
          "width": 1440,
          "height": 820,
          "caption": "A download and a quartile are different objects, and version 2.3 does not merge them.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "list",
          "heading": "What version 2.3 actually changes",
          "items": [
            "Listener is replaced with podcast consumer throughout, which is terminology cleanup with a real consequence: the metric was never a person, and calling it one invited comparisons to audience measurement that the method does not support.",
            "New guidance on measuring streaming video podcasts, the distribution path where a real player exists and the download model stops describing what happened.",
            "Updated guidance for URL prefix measurement and for changes to RSS enclosure URLs, the two places where a measurement vendor sits between the feed and the file.",
            "Expanded invalid traffic considerations, which in a log based system means better heuristics rather than better observation.",
            "Clearer application of the different measurement window approaches, so two vendors counting the same episode over different windows can at least say so.",
            "Improved handling of duplicate downloads and platform driven anomalies, the category that covers prefetching, retries and aggressive caching by large podcast apps.",
            "Version 3.0 is already in development and is aimed at streaming video podcasts, targeted for 2027."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The video podcast clause is the one that touches VAST",
          "paragraphs": [
            "An audio podcast delivered over open RSS has no player to instrument, which is why the download model exists. A video podcast on a streaming platform, a CTV app or a video service has one. It has a player, a playback timeline, and in most cases an ad serving stack that already speaks VAST. The same show, the same episode, sometimes the same ad, is measured as a download on one path and as a VAST impression with quartiles on the other.",
            "That divergence has a predictable outcome for anyone selling across both. The numbers will not match, and the mismatch will be attributed to measurement methodology, because measurement methodology is the visible difference. Some of it genuinely is methodology. A download counted at a byte threshold and an impression counted at a fired pixel are different events and will never produce the same number, no matter how clean the plumbing.",
            "A meaningful share of the gap comes from somewhere else entirely: tags that do not fire. The download side cannot detect that, because the download was counted before the ad ever ran. The VAST side can, and can do it before the campaign starts rather than after the discrepancy report lands."
          ]
        },
        {
          "type": "code",
          "heading": "An audio ad as VAST sees it",
          "language": "xml",
          "code": "<VAST version=\"4.2\" xmlns=\"http://www.iab.com/VAST\">\n  <Ad id=\"audio-spot-1\">\n    <InLine>\n      <AdSystem version=\"1.0\">example-audio-adserver</AdSystem>\n      <AdTitle>30s host read replacement</AdTitle>\n      <AdServingId>c8d2-hostread-0031</AdServingId>\n      <Impression><![CDATA[https://track.example/imp?cb=[CACHEBUSTING]]]></Impression>\n      <Creatives>\n        <Creative id=\"1\" sequence=\"1\">\n          <UniversalAdId idRegistry=\"Ad-ID\">HOSTREAD01</UniversalAdId>\n          <Linear>\n            <Duration>00:00:30</Duration>\n            <TrackingEvents>\n              <Tracking event=\"start\"><![CDATA[https://track.example/start]]></Tracking>\n              <Tracking event=\"firstQuartile\"><![CDATA[https://track.example/q1]]></Tracking>\n              <Tracking event=\"midpoint\"><![CDATA[https://track.example/mid]]></Tracking>\n              <Tracking event=\"thirdQuartile\"><![CDATA[https://track.example/q3]]></Tracking>\n              <Tracking event=\"complete\"><![CDATA[https://track.example/complete]]></Tracking>\n            </TrackingEvents>\n            <MediaFiles>\n              <MediaFile delivery=\"progressive\" type=\"audio/mpeg\" bitrate=\"128\" width=\"0\" height=\"0\">\n                <![CDATA[https://cdn.example/spot-128.mp3]]>\n              </MediaFile>\n            </MediaFiles>\n          </Linear>\n        </Creative>\n      </Creatives>\n    </InLine>\n  </Ad>\n</VAST>"
        },
        {
          "type": "paragraphs",
          "heading": "What that document gets wrong in practice",
          "paragraphs": [
            "Audio ad tags accumulate a specific set of defects, and they persist longer than video defects do because nobody is watching a screen when they happen. A broken video ad produces a black frame somebody notices. A broken audio ad produces silence, or the previous segment continuing, and the listener assumes the episode simply had no ad.",
            "The MediaFile element is the usual site. VAST requires a media type on it, and an audio creative served with a video mime type, or with no type at all, will be skipped by a player that filters on type before it downloads anything. Dynamic insertion platforms that transcode on the fly are particularly good at emitting the wrong one, because the transcode target and the declared type are set in different parts of the pipeline.",
            "Duration is the second. It is a required element on a Linear creative, it has a fixed HH:MM:SS format, and an ad server that emits a bare number of seconds produces a document that fails to parse in strict players and silently rounds in permissive ones. In audio that error is invisible until a reconciliation two weeks later shows a completion rate that cannot be right.",
            "Then the trackers themselves. Mixed content, HTTP tracking URLs on an HTTPS delivery path, unencoded macros, and wrapper chains that resolve to an endpoint returning an HTML error page with a 200 status. All of those are ordinary VAST failures. None of them are audio specific. All of them are more expensive in audio because the feedback loop that would surface them does not exist."
          ]
        },
        {
          "type": "list",
          "heading": "What a parser settles on an audio tag, before anything plays",
          "items": [
            "Whether the response is well formed XML at all, or an error page with a success status, which remains the single most common thing a working looking ad tag endpoint returns.",
            "Whether the declared VAST version on the root element matches the elements actually used, including DAAST era markup that survived a migration and now sits in a document claiming 4.x.",
            "Whether every Linear creative carries a Duration in HH:MM:SS form rather than a bare integer or an empty element.",
            "Whether MediaFile carries a type attribute, and whether that type is an audio type consistent with what the CDN actually serves.",
            "Whether the tracking event set is complete enough to support the reporting the buyer was sold, which is the check that matters when the download side of the ledger cannot corroborate anything.",
            "Whether every tracking and impression URL is HTTPS and macro correct, and whether wrapper chains terminate within a sane depth rather than looping.",
            "Whether an ad pod or VMAP structure declares breaks that a dynamic insertion platform can actually fill at the offsets it names."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The reconciliation you can actually do",
          "paragraphs": [
            "You cannot make a download equal an impression. The two definitions are not convertible, and version 2.3 does not pretend otherwise: the guidance is that everyone counts the same way, not that the counts converge across methods. Anthony Katsur put the goal as measurement only working at scale if everyone is counting the same way, which is a statement about consistency inside a method rather than agreement across methods.",
            "What you can do is remove the variable that is not methodology. If the VAST tag is valid, the discrepancy between the log count and the event count is explained by the difference in definitions, and that is a conversation both sides can have with numbers. If the VAST tag is broken, the discrepancy is explained by the tag, and no amount of methodology discussion will find it, because the log side has no visibility into whether the ad played and the event side is reporting the absence of events as if it were the absence of listeners.",
            "So the case for validating audio tags has nothing to do with audio being complicated. It is the simplest surface VAST supports. It is also the only one where no other part of the stack will raise its hand."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Before 19 August",
          "paragraphs": [
            "The comment window closes on 19 August 2026, and the constituency most likely to skip it is the one that traffics the ads rather than the one that counts the episodes. That is a shame, because the video podcast section is where a technical comment would land best. A guideline that describes how to measure a streaming video podcast is describing an environment with a player in it, and once there is a player there is a VAST document, and once there is a VAST document the question of whether it fired is answerable rather than inferred.",
            "If you run audio inventory, the useful thing to do this month is smaller than a comment letter. Take the tags you are already serving, run them through a parser, and find out how many of them would have been caught by a check nobody was running."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate an audio tag the same way you validate video",
          "paragraph": "Paste an audio VAST tag into the validator for structural, media file, macro and tracking findings, including the DAAST era markup that survives migrations. It runs locally in the browser and nothing is stored.",
          "href": "/validate/",
          "label": "Open the validator"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "IAB Tech Lab releases Podcast Technical Measurement Guidelines v2.3 for public comment",
              "href": "https://www.prnewswire.com/news-releases/iab-tech-lab-releases-podcast-technical-measurement-guidelines-v2-3-for-public-comment-302830182.html",
              "description": "The 21 July 2026 announcement, the 19 August comment deadline, the terminology and video podcast changes, and the note that version 3.0 targets streaming video podcasts in 2027.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Podcast measurement guidelines coverage",
              "href": "https://podnews.net/press-release/iab-tech-lab-v23-public",
              "description": "Trade coverage of the same release, with the server side log analysis rationale stated in full.",
              "source": "Podnews"
            },
            {
              "label": "Digital Audio Ad Serving Template",
              "href": "https://iabtechlab.com/standards/digital-audio-ad-serving-template-daast/",
              "description": "The DAAST standard page, including its deprecation and the merge of audio support into VAST 4.1.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VMAP and DAAST validation in vastlint core",
              "href": "/blog/vmap-and-daast-validation-in-vastlint-core",
              "description": "What the validator checks on ad break structures and legacy audio markup, and why DAAST era documents still turn up in production.",
              "source": "vastlint"
            },
            {
              "label": "How to validate VAST trackers before launch",
              "href": "/blog/how-to-validate-vast-trackers-before-launch",
              "description": "The tracker level checks that apply identically to audio: HTTPS, macro encoding, wrapper depth and endpoints that return a 200 with the wrong body.",
              "source": "vastlint"
            },
            {
              "label": "VAST rule catalog",
              "href": "/docs/rules/",
              "description": "Every rule vastlint checks, including the media file, duration and tracking rules that apply to audio creatives.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "adcp-3-1-format-capabilities-vast-duration",
      "title": "AdCP 3.1 Turns Creative Formats Into Declared Capabilities. The Duration Is Still a Number in a JSON File.",
      "description": "The 3.1 release gives creative agents a canonical way to advertise what they can build: stable capability ids, format kinds, and duration bounds that can be open ended on one side. Under specified selectors now fail closed instead of matching by loose overlap, which is a real improvement. None of it opens the VAST document, so the one field both sides think they agreed on is the one nobody has read.",
      "publishedAt": "2026-08-08",
      "author": "Alex Sekowski",
      "readingTime": "10 min read",
      "heroKicker": "Agentic creative",
      "tags": [
        "AdCP",
        "Agentic",
        "Creative formats",
        "VAST validator",
        "Standards"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The format layer got a vocabulary",
          "paragraphs": [
            "AdCP 3.1 is described in its own release notes as production hardening for real agent operations, which is what a specification says when the gaps were found by running buys against real publishers rather than by reading the schema. It is additive over 3.0, and the patch line has not slowed down: four releases landed between 3 and 8 August alone. The creative half of it is the part worth reading if you ship video.",
            "The change is that a creative agent now declares what it can produce, in a machine readable way, instead of a buyer guessing from prose. Capabilities carry a supported formats array, each entry has a stable capability id that is local to the agent but durable over time, and a buyer targets that id directly when it asks for a creative to be built. Format selection stopped being string matching against a name somebody typed.",
            "Duration got a proper model at the same time. Hosted audio and video formats can express a range with one side open, so a bound of up to sixty seconds is expressible without inventing a lower bound nobody meant, and inventory with a fixed slot uses an exact duration instead of a range collapsed to a single point. That distinction sounds pedantic until you have argued with a partner about whether a thirty second slot means exactly thirty or at most thirty.",
            "And selectors that do not fully specify a format now fail closed rather than matching by loose overlap. Of everything in the release, that is the change most likely to save someone a campaign. A protocol that silently picks something plausible when the request was ambiguous produces a creative nobody asked for, and nobody finds out until delivery."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/adcp-3-1-format-capabilities-vast-duration.png?v=2",
          "alt": "AdCP 3.1 records creative format capabilities, including duration, as declared JSON. That declaration is not a check that the VAST tag or the media file actually has that duration.",
          "width": 1440,
          "height": 820,
          "caption": "A buyer can be told a format is capable of a duration the file never delivers.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "heading": "What that gets you, precisely",
          "paragraphs": [
            "Everything above is negotiation. It fixes what the two agents believe they agreed to build, before anything is built, which is the right moment to fix it. A buyer agent that targets a capability id and receives a manifest back holds a record of the agreement that a human can audit later.",
            "What none of it establishes is the creative itself. For video the creative is a VAST document, and AdCP carries it as an asset with a delivery type of either a URL that returns VAST XML or an inline string containing it. In the first case the bytes have not been fetched. In the second they are sitting in the manifest and still nobody has parsed them.",
            "So the format layer and the asset layer make claims at two different altitudes, and the two can disagree without either side noticing. The capability says the agent produces spots of at most sixty seconds. The asset says the duration is a certain number of milliseconds, qualified in the schema with if known. The tag says something in an element called Duration. Three assertions, one of which is the actual instruction to the player."
          ]
        },
        {
          "type": "code",
          "heading": "Three numbers that are allowed to disagree",
          "language": "json",
          "code": "// capability, declared by the creative agent\n{\n  \"capability_id\": \"video_hosted_16x9\",\n  \"format_kind\": \"hosted_video\",\n  \"duration_ms_range\": [null, 60000]\n}\n\n// asset, declared in the creative manifest\n{\n  \"asset_type\": \"vast\",\n  \"delivery_type\": \"url\",\n  \"url\": \"https://adserver.example/vast?pl=[PLACEMENT]\",\n  \"vast_version\": \"4.2\",\n  \"duration_ms\": 30000\n}\n\n// the document the player actually reads\n<Linear>\n  <Duration>00:01:05</Duration>\n</Linear>"
        },
        {
          "type": "paragraphs",
          "heading": "Nothing in that exchange raises an error",
          "paragraphs": [
            "The capability is satisfied by the asset, because thirty thousand milliseconds is under the sixty second bound. The asset validates against the JSON Schema, because thirty thousand is an integer and the field is optional anyway. The manifest is accepted, the buy is confirmed, and the tag returns a sixty five second creative into a slot that will cut it off at thirty, or reject it outright depending on the player.",
            "Nothing has gone wrong in the protocol. AdCP exchanges creative metadata, which is what it says it does, and a metadata protocol has no business becoming a video ad parser. The gap is that the loop never closes. Something has to open the document and compare it against the claims, and until 3.1 there was no clean statement of which claims to compare it against. Now there is, which makes the absent check easier to notice.",
            "This matters more than it did two years ago because of who is writing the document. A generative creative agent produces VAST the same way it produces text: by generating something shaped like what it has seen. Shape is not correctness. A document can carry a plausible Duration, a plausible tracking set, a MediaFile URL that resolves to nothing, and a version attribute that contradicts the elements underneath it, and a schema check on the manifest that references it sees none of that."
          ]
        },
        {
          "type": "list",
          "heading": "The mismatches a parser settles in one pass",
          "items": [
            "Declared duration against the Duration element, which is the check the format layer now makes meaningful because there is finally an authoritative bound to compare against.",
            "Declared VAST version against the version attribute on the root element, and against the elements actually used, since a document claiming 4.2 while using 3.0 era markup parses differently depending on who reads it.",
            "Declared tracking events against the TrackingEvents actually present, so a manifest promising quartile reporting cannot be fulfilled by a tag that only carries an impression.",
            "A VPAID claim of false against a document that still ships an application/javascript media file, which is the deprecation everyone declared complete and nobody finished.",
            "Whether the endpoint behind a URL delivery asset returns VAST XML at all, rather than an HTML error page with a success status.",
            "Whether wrapper chains terminate, and within what depth, since a manifest asset is one URL and the tag behind it can be four redirects deep before anything renders.",
            "Whether media file renditions exist that satisfy the placement the format kind describes, rather than a single rendition that happens to be first in the list."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The wire rules that will break an existing integration",
          "paragraphs": [
            "Separately from formats, 3.1 changed how the envelope works, and two of those changes will break implementations that were written carefully.",
            "The first is idempotency. An idempotency key is now required on every task request, reads included, with staged enforcement: sellers on 3.1 should reject reads that omit it, and 3.2 will require rejection. Reads are the requests nobody thought needed a replay guard, which is exactly why the enforcement is staged rather than immediate.",
            "The second is envelope flattening, and it inverts an instinct. The protocol envelope no longer nests the body under a payload key. Envelope fields and body fields are siblings at the root, and servers are required to tolerate envelope fields they do not recognise. Strict validation is called out as non conformant, with the mechanisms named directly: strict MCP framework modes, strict model validation, and generated schemas that set additional properties to false. If you turned strictness on because that is what careful engineers do, you built a client that fails against a conformant server.",
            "Version negotiation landed in the same release. Every request and response carries a version at release precision, sellers advertise the releases they support, and a buyer pinning something unsupported gets a typed error naming what would have worked. That is a mechanism the bid stream still lacks entirely, which is a separate argument we made on the OpenRTB side."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where a validator sits in this",
          "paragraphs": [
            "The vastlint MCP server answers capability discovery as an AdCP agent on the governance protocol, with a content standards specialism, idempotency support and a replay window. That is a deliberately narrow declaration. It does not plan media, it does not build creatives, and it does not negotiate. It answers one question, which is whether a document does what somebody said it does.",
            "The reason to expose that as a protocol surface rather than a dashboard is the same reason 3.1 exists at all. In an agentic pipeline there is no human between the manifest and the delivery. A broken tag that a trafficker would have caught in an afternoon runs for a flight, and the report that eventually surfaces it describes it as underdelivery rather than as a parse failure. A check the agent can call is a check that happens. A check on a screen is a check that happens when someone remembers.",
            "The formal verification programme AdCP has planned for 3.1, where implementations publish verifiable conformance output against a shared test corpus, is the same idea applied to the protocol itself. It is a good instinct and it stops at the protocol boundary. Conformance to AdCP proves the manifest is well formed. It proves nothing about the creative the manifest points at, and it was never meant to."
          ]
        },
        {
          "type": "cta",
          "heading": "Close the loop on a manifest you already accepted",
          "paragraph": "Paste a VAST tag or a tag URL into the validator and compare what the document does against what the creative manifest claimed. Structural, media file, macro and tracking findings, running locally in the browser with nothing stored.",
          "href": "/validate/",
          "label": "Open the validator"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "AdCP release notes",
              "href": "https://docs.adcontextprotocol.org/docs/reference/release-notes",
              "description": "The 3.1.0 entry covering canonical format capabilities, capability ids, duration ranges, fail closed selectors, the idempotency requirement, envelope flattening and version negotiation.",
              "source": "Ad Context Protocol"
            },
            {
              "label": "adcontextprotocol/adcp releases",
              "href": "https://github.com/adcontextprotocol/adcp/releases",
              "description": "The 3.1.x patch line, including the four releases between 3 and 8 August 2026.",
              "source": "GitHub"
            },
            {
              "label": "AdCP can declare a VAST tag. It cannot check one.",
              "href": "/blog/adcp-vast-asset-declared-vs-verified",
              "description": "The asset level version of the same argument: every field on a VAST asset is a claim about a document nobody has parsed.",
              "source": "vastlint"
            },
            {
              "label": "Agentic buying needs a harness",
              "href": "/blog/agentic-buying-needs-a-harness",
              "description": "Why creative validation has to be a tool an agent can call rather than a dashboard a human checks.",
              "source": "vastlint"
            },
            {
              "label": "The agentic protocols shipped a version handshake. A bid request still has nowhere to say which OpenRTB it is.",
              "href": "https://rtblint.org/blog/agentic-version-negotiation-openrtb-gap/",
              "description": "The bid stream half of the version negotiation argument, and what AdCP 3.1 built that OpenRTB still lacks.",
              "source": "rtblint"
            },
            {
              "label": "VAST rule catalog",
              "href": "/docs/rules/",
              "description": "Every rule vastlint checks, including the duration, version, VPAID and tracking rules referenced here.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ctv-capacity-headroom-new-formats-delivery",
      "title": "CTV Sells 65 Percent of Its Ad Capacity. The Headroom Sits in the Formats With the Shortest Delivery Track Record.",
      "description": "Omdia published a $0.21 per viewing hour monetisation benchmark for ad-supported CTV on 29 July. The two utilisation figures behind it point at different problems, and the larger half of the upside can only come from pause, screensaver, overlay, squeezeback and in-scene inventory. Those are the formats whose VAST payload shipped two weeks ago.",
      "publishedAt": "2026-07-31",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "CTV economics",
      "tags": [
        "CTV",
        "Ad load",
        "CTV Ad Portfolio",
        "VAST errors",
        "Monetisation"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "A benchmark, and what it is measuring",
          "paragraphs": [
            "Omdia published Video Advertising KPI Benchmarks: Monetization on 29 July 2026. The headline number is that ad-supported connected TV services could average $0.21 per hour of viewing if every available advertising slot were sold, measured across hybrid VoD, AVoD, FAST and broadcaster VoD, and derived from 2025 advertising loads in the UK, the US, Australia, Brazil, Canada, France, Germany and Mexico.",
            "Hour of viewing is a better unit than the industry usually gets. Ad load per hour differs by a factor of several between a FAST channel that runs near broadcast density and an ad-light subscription tier that runs four minutes, so revenue per user or revenue per impression compares almost nothing when you put those two services in the same table. Normalising on viewing time makes the comparison mean something.",
            "The report carries two utilisation figures alongside the benchmark. Services are running at roughly 65 percent of their commercial capacity, and at 32 percent of the maximum regulatory advertising capacity that applies to broadcast linear television. Omdia puts the resulting upside at two to three times."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Those two percentages are not the same gap",
          "paragraphs": [
            "Most of the trade coverage ran them together. They describe different problems and they have different fixes.",
            "Sixty-five percent of commercial capacity is a fill problem. The slots exist, the service is willing to sell them, and they go unsold. Closing that gap alone is worth roughly one and a half times, not two to three.",
            "Thirty-two percent of linear's regulatory ceiling is a load problem. It says streaming shows far fewer ad minutes per hour than a broadcaster is legally permitted to show, which is a decision about the product rather than a failure of the sales team. Getting from 32 percent toward that ceiling is where the rest of the two to three times lives.",
            "So the larger half of the upside requires more advertising minutes per viewing hour, not just better fill on the minutes already there. That is the part worth thinking about carefully if you ship tags for a living."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "You cannot get there with more mid-rolls",
          "paragraphs": [
            "Streaming runs at a third of linear's permitted load for a reason, and the reason is not that anyone forgot. Ad-supported tiers compete on tolerability against an ad-free tier of the same service, one click away in the same account settings. Tripling mid-roll minutes is a churn experiment that most of these services have already run at smaller increments and stopped running.",
            "If the minutes cannot come from interrupting content, they have to come from advertising time that sits outside the content: the pause screen, the idle screensaver, an overlay during play, a squeezeback around the frame, an in-scene placement, and QR codes attached to any of them.",
            "That is the same list IAB Tech Lab standardised in the CTV Ad Portfolio. The signaling guidance was finalised on 22 July 2026 and the creative payloads landed in the VAST repository on 17 July, in one pull request carrying both a VAST 4.4 draft schema and a set of VAST 2.0 extension documents.",
            "The answer to where the two to three times comes from and the answer to what the standards body shipped two weeks ago are the same list. That is not a coincidence, it is the industry routing around a constraint it already understands. It does mean the revenue headroom is concentrated in exactly the formats with the least delivery history."
          ]
        },
        {
          "type": "quote",
          "quote": "Unsold capacity is recoverable. The break comes round again next hour. A slot that filled and then failed is gone, and in the seller's own reporting it looks identical to a slot nobody bid on.",
          "attribution": "vastlint"
        },
        {
          "type": "paragraphs",
          "heading": "Sold is not played, and hour of viewing is measured after the fact",
          "paragraphs": [
            "The $0.21 ceiling is explicitly defined as every available slot being sold. The realised figure is booked revenue divided by viewing hours, and revenue books against a tracked impression, not against a win notice.",
            "Everything between those two events is the VAST path. Fetch the tag, resolve however many wrappers are in the chain, pick a MediaFile the device can actually decode, render it, fire the impression and the quartiles. A failure anywhere in that sequence produces an Error ping with a code in it and nothing else that anyone downstream counts.",
            "The slot still consumed its position in the break. The viewing hour still elapsed. No impression was booked. In a monetisation-per-hour view that slot is non-revenue viewing time, which is the same thing the report is calling unsold capacity.",
            "Which is the point. The 35 percentage points Omdia measures as unfilled commercial capacity contain an unknown quantity of slots that were sold and did not deliver, and the prescribed remedy of growing the advertiser base does nothing whatsoever for that portion. More demand on a path that drops one in fifty responses produces more revenue and the same drop rate."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Which failures scale with ad load, and which scale worse",
          "paragraphs": [
            "Some VAST failures are per-impression and grow linearly as you add slots. A creative with no playable MediaFile fails at the same rate whether it is the first ad of the hour or the ninth.",
            "Pod-level failures do not behave that way. A pod has one deadline, set by the break length or by the stitching window, and every slot in it draws down the same budget. A wrapper chain that resolves comfortably in a two-slot pre-roll starts colliding with that deadline at six slots, because the chains resolve in sequence against a fixed wall clock.",
            "That is the failure mode to watch as load rises: the same tags, the same partners, the same chain depth, and a timeout rate that climbs because you changed the pod and not the tag."
          ]
        },
        {
          "type": "code",
          "heading": "VAST error codes, and how each behaves as slots per hour go up",
          "language": "text",
          "code": "102  VAST version not supported\n     New formats push responses onto 4.x paths. Device fleets that\n     parse 2.0 fine will reject them. Scales with format mix, not slots.\n\n301  Timeout of VAST URI provided in Wrapper\n302  Wrapper limit reached\n     Superlinear in pod depth. One shared deadline, sequential chains.\n     Adding slots shortens the budget available to every chain in the pod.\n\n403  Could not find a MediaFile supported by this player\n     A pause ad now carries video, image and sometimes an interactive\n     SIMID file. A player that ignores the extension it arrived in has\n     no renditions at all, not a degraded one.\n\n201  Player expecting different linearity\n     A portfolio format delivered as NonLinearAds into a slot the\n     player opened expecting Linear. Rises with format mix.\n\n501  NonLinear dimensions do not align with the display area\n     Rare while NonLinear meant a small overlay banner. Squeezeback,\n     in-scene and QR all resolve a rectangle against the ad view.\n     This becomes a common code, not an exotic one.\n\n900  Undefined error\n     What most players report when they meet a payload shape they were\n     not built for. Rises first, and tells you least."
        },
        {
          "type": "paragraphs",
          "heading": "The new formats have two delivery paths and neither has a track record",
          "paragraphs": [
            "The 17 July pull request shipped the portfolio twice. The VAST 4.4 draft schema carries the formats natively, one AdCOM signal per Extension element. The VAST 2.0 extension documents carry the same six formats and the same QR metadata inside a single named container, alongside the media, because VAST 2.0 is what parses on the long tail of devices that will still be in living rooms when 4.4 is final.",
            "Both are current. They are not interchangeable, and a validator built for one reports nothing at all on the other. We wrote that up separately.",
            "The delivery consequence is easy to underestimate. A pause ad used to be a JPEG in a NonLinear StaticResource. It is now a creative with a duration, a MediaFiles list, optional interactive content and quartile tracking. Every failure mode that has ever applied to a linear creative now applies to a pause screen, on hardware that has never rendered one, through an extension mechanism whose whole design property is that unaware players ignore it silently.",
            "Silent is the operative word. An extension a player does not recognise is not a parse error and does not fire an Error ping. It renders the native NonLinear fallback if the ad server included one, and nothing if it did not."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the first year of a format is the expensive one to get wrong",
          "paragraphs": [
            "A mid-roll that fails costs one impression against a baseline that is years deep and well understood. Nobody reprices mid-roll inventory because of it.",
            "A new format that fails in its first year costs the renewal. Buyers have no baseline to average against, so early delivery evidence is the entire evidence base, and a pause ad that did not render is not read as an integration bug. It is read as a fact about pause ads.",
            "Omdia's own recommendation names the dependency. Reaching the benchmark, the report says, requires growing the advertiser base to maximise fill rates and improving advertising context protocols. The first half is a sales problem. The second half is a specification and conformance problem, and it is the one that determines whether the inventory the sales team sells actually arrives."
          ]
        },
        {
          "type": "list",
          "heading": "What to verify before you raise ad load",
          "items": [
            "Test the pod, not the tag. Chain depth that resolves inside a two-slot break can miss the deadline at six. Measure wrapper resolution time against the actual pod duration you are moving to, not against a single-impression timeout.",
            "Decide which portfolio encoding each partner expects, and ask rather than assume. The 4.x per-signal pattern and the VAST 2.0 container pattern are both live and a parser built for one sees nothing in the other.",
            "Always send a native NonLinear fallback resource alongside a 2.0 portfolio extension. Without it, a player that ignores the extension renders nothing and reports nothing.",
            "Treat error 501 as a launch blocker for squeezeback, in-scene and QR. Those formats resolve a rectangle against the ad view, and a rectangle that does not fit is the failure mode the code was written for.",
            "Split your error reporting by format before you scale the format. An aggregate error rate that looks fine because mid-rolls dominate the denominator will hide a pause-ad path that is failing most of the time.",
            "Watch code 900 specifically during the first weeks of a new format. Undefined error is what a player reports when it meets a payload shape it was not built for, so it rises first and explains least.",
            "Reconcile unfilled against sold-and-errored on the same report. If those two numbers live in different systems, the gap the benchmark describes is not measurable in your own data either."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The part that is in your control",
          "paragraphs": [
            "Fill rate depends on demand, on floors, on how many buyers have your inventory whitelisted, and on macroeconomic conditions nobody in ad ops sets. It is worth pursuing and it is largely someone else's job.",
            "Whether a tag that wins renders correctly is entirely an engineering property of the tag, the chain and the player, and it is knowable before launch rather than after. That asymmetry is why the delivery half of this deserves attention out of proportion to how often it gets discussed. It is the half you can fix on a Tuesday.",
            "The benchmark is genuinely useful and the headroom is genuinely there. Just be clear that the industry is about to push its growth through the newest, least tested formats in the catalogue, on the most fragmented device population in digital advertising, and that the metric everyone will use to score it cannot see the difference between an empty slot and a broken one."
          ]
        },
        {
          "type": "cta",
          "heading": "Check a CTV Ad Portfolio tag before you scale the format",
          "paragraph": "Paste a tag into the validator for structural, media file, macro and tracking findings, plus the CTV Ad Portfolio and VAST 4.4 rules on the 4.x signaling path. It runs locally in the browser and nothing is stored.",
          "href": "/validate/",
          "label": "Open the validator"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "Omdia: $0.21 per viewing hour sets monetization benchmark for ad-supported CTV",
              "href": "https://omdia.tech.informa.com/pr/2026/july/0point21-dollar-per-viewing-hour-sets-monetization-benchmark-for-ad-supported-ctv",
              "description": "The 29 July 2026 announcement of Video Advertising KPI Benchmarks: Monetization, including the $0.21 HOV benchmark, the 65 percent commercial capacity and 32 percent regulatory capacity figures, and the markets covered.",
              "source": "Omdia"
            },
            {
              "label": "Report: Ad-supported CTV missing monetisation potential",
              "href": "https://www.advanced-television.com/2026/07/29/reports-0-21-per-viewing-hour-benchmark-for-ad-supported-ctv/",
              "description": "Trade coverage of the same report, with the two to three times revenue framing.",
              "source": "Advanced Television"
            },
            {
              "label": "CTV Ad Portfolio",
              "href": "https://iabtechlab.com/standards/ctv-ad-portfolio/",
              "description": "The standard defining Pause, Screensaver, Overlay, Squeezeback, In-Scene and QR formats. Signaling guidance finalised 22 July 2026.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "The CTV Ad Portfolio also shipped a VAST 2.0 path. It is a different payload.",
              "href": "/blog/ctv-ad-portfolio-vast-2-0-extensions",
              "description": "The two encodings that landed in the same pull request, why a validator built for one reports nothing on the other, and the CreativeId binding rule.",
              "source": "vastlint"
            },
            {
              "label": "A pause ad used to be a JPEG. VAST 4.4 changes that.",
              "href": "/blog/vast-4-4-draft-schema-ctv-ad-portfolio",
              "description": "The draft schema behind the native 4.x delivery path for the portfolio formats.",
              "source": "vastlint"
            },
            {
              "label": "The revenue math of broken VAST",
              "href": "/blog/vast-failures-revenue-math",
              "description": "The per-impression version of the same argument: what a one percent silent failure rate costs at CTV prices, failure by failure.",
              "source": "vastlint"
            },
            {
              "label": "The 65 percent is a bid request problem before it is a demand problem",
              "href": "https://rtblint.org/blog/ctv-capacity-gap-bid-request-quality/",
              "description": "The buy-side half of the same report: why unsold and unparseable land in the same bucket in a seller's fill rate.",
              "source": "rtblint"
            },
            {
              "label": "VAST rule catalog",
              "href": "/docs/rules/",
              "description": "Every rule vastlint checks, including the CTV Ad Portfolio and VAST 4.4 rules.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ctv-ad-portfolio-vast-2-0-extensions",
      "title": "The CTV Ad Portfolio Also Shipped a VAST 2.0 Path. It Is a Different Payload.",
      "description": "The pull request that landed the VAST 4.4 draft schema on 17 July contained two other files nobody has written about: standardised extension documents that deliver Pause, Screensaver, Overlay, Squeezeback, In-Scene and QR code metadata through VAST 2.0. The payload does not match the 4.x pattern, and validators built for one will not see the other.",
      "publishedAt": "2026-07-30",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "Standards",
      "tags": [
        "CTV Ad Portfolio",
        "VAST 2.0",
        "Extensions",
        "AdCOM",
        "Validation"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Three files, not one",
          "paragraphs": [
            "The VAST repository merged pull request 57 on 17 July 2026, from a branch called 4.4Development, titled CTV Ad Portfolio Updates. The file everyone looked at was vast_4.4.xsd, the draft schema we wrote about here five days later.",
            "It was not the only file in that pull request. Two others landed alongside it: extensions/ctv_ad_portfolio.md and extensions/ctv_qrcode.md. Neither is a draft. Both define standardised extension payloads for VAST 2.0, and between them they cover the same six formats and the same QR code metadata as the draft schema, through a completely different mechanism.",
            "That is not a redundancy. It is a reach decision, and it is probably the more consequential half of the release."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the standards body targeted a spec from 2008",
          "paragraphs": [
            "VAST 4.4 is a working draft under discussion. VAST 4.2 and 4.3 are final but unevenly supported. VAST 2.0 is the version that parses essentially everywhere, including on the long tail of CTV devices that will still be in living rooms when 4.4 is finalised.",
            "The problem is that VAST 2.0's NonLinear element has almost nothing in it. Its whole vocabulary is StaticResource, IFrameResource, HTMLResource, TrackingEvents, NonLinearClickThrough and AdParameters. A pause ad delivered through native VAST 2.0 is a JPEG, with no video, no duration, no interactive creative file and therefore no quartile tracking.",
            "The CTV Ad Portfolio extension solves that without touching the schema. It adds an Extension element under InLine/Extensions with type=\"ctv_ad_portfolio\", and puts a MediaFiles container inside it. Video files, image files, SIMID interactive creative files, a Duration, tracking events, icons, click tracking. The delivery model that 4.4 adds natively, back-ported into the version that already ships.",
            "Players that do not recognise the extension ignore it, which is exactly what VAST extensions are for. The document also asks ad servers to include a native NonLinear StaticResource as a fallback where practical, so an unaware player still renders something rather than firing an error."
          ]
        },
        {
          "type": "quote",
          "quote": "One release, two encodings of the same signals. Tooling that recognises the 4.x pattern treats the 2.0 pattern as unstructured extension data, and reports nothing at all.",
          "attribution": "vastlint standards note"
        },
        {
          "type": "paragraphs",
          "heading": "The payload is not the 4.x payload",
          "paragraphs": [
            "This is the part that matters for anyone who has already built against the signaling guidance. The 4.x pattern described in the finalised guidance carries one AdCOM signal per Extension element, each marked ext=\"adcom\". The VAST 2.0 extension carries all of them inside a single named container, as plain child elements, alongside the media.",
            "Same four signals, same AdCOM lists, same integers, different XML. A parser looking for Extension@type=\"plcmt\" finds nothing in a 2.0 document, and a parser looking for Extension@type=\"ctv_ad_portfolio\" finds nothing in a 4.x one."
          ]
        },
        {
          "type": "code",
          "heading": "The same pause ad, signalled two ways",
          "language": "xml",
          "code": "<!-- 4.x pattern: one Extension per AdCOM signal -->\n<Extensions>\n  <Extension type=\"plcmt\" ext=\"adcom\"><plcmt>5</plcmt></Extension>\n  <Extension type=\"pos\" ext=\"adcom\"><pos>7</pos></Extension>\n  <Extension type=\"playbackmethod\" ext=\"adcom\"><playbackmethod>9</playbackmethod></Extension>\n  <Extension type=\"attr\" ext=\"adcom\"><attr>19</attr></Extension>\n</Extensions>\n\n<!-- VAST 2.0 extension: one container, signals plus media -->\n<Extensions>\n  <Extension type=\"ctv_ad_portfolio\">\n    <CreativeId>creative-pause-qr-001</CreativeId>\n    <plcmt>5</plcmt>\n    <pos>7</pos>\n    <playbackmethod>9</playbackmethod>\n    <attr>19</attr>\n    <attr>21</attr>\n    <Duration>00:00:15</Duration>\n    <MediaFiles>\n      <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\" bitrate=\"8000\" codec=\"H.264\">\n        <![CDATA[https://cdn.example.com/pause/brand_cine_1080p.mp4]]>\n      </MediaFile>\n    </MediaFiles>\n  </Extension>\n</Extensions>"
        },
        {
          "type": "paragraphs",
          "heading": "CreativeId is doing load-bearing work",
          "paragraphs": [
            "There is a structural problem the extension has to solve and it is worth understanding before you generate one. In VAST 2.0 the Extensions container hangs off InLine, not off Creative. So an extension that describes a specific creative has no inherent binding to it.",
            "The document's answer is a CreativeId child element whose value matches the Creative@id attribute, required whenever the response contains more than one Creative. If it is omitted, the extension applies to the only NonLinearAds creative in the response.",
            "Which means a multi-creative response that omits CreativeId is not a parse error. It is a silent misattribution: the media files, the duration, the format signal and the creative attributes all get applied to whichever creative the receiving platform decides to apply them to. Nothing in the XML is malformed. The wrong ad renders in the wrong slot, or the right ad renders with the wrong declared format, and the tag validates.",
            "The QR extension takes the opposite approach and avoids the problem: it goes under Creative/CreativeExtensions, so it is already scoped to its creative. The document notes that if you do put QR metadata in an InLine-level Extension instead, it should carry a creative identifier, and that Creative/CreativeExtensions is the preferred placement."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The QR extension, and the coordinate system people will get wrong",
          "paragraphs": [
            "CreativeExtension type=\"tl_qrcode\" carries four things: QrCodeScanUrl, an optional QrCodeImageUrl, a QrCodePosition with xPosition and yPosition, and a QrCodeSize with size. Positions and size are percentages, and the QR code is assumed square.",
            "The percentages are relative to the ad view, not the screen. The document works the example: an overlay lower third occupying a 1920 by 324 ad view at the bottom of a 1920 by 1080 screen resolves xPosition=\"10.0%\" to 192 pixels within the ad view and yPosition=\"10.0%\" to 32.4 pixels within it, while size=\"15.0%\" resolves to a 288 by 288 square because it is measured against the ad view width. Anyone who assumes screen coordinates puts the code somewhere else entirely, and on a lower third the vertical error is the difference between inside the ad and outside it.",
            "The other thing to internalise is that QrCodeScanUrl is not a clickthrough. The document is explicit that it does not replace ClickThrough or NonLinearClickThrough, that the two may differ, and that a scan destination is often a CTV-specific coupon or attribution endpoint while the clickthrough points at a general landing page. It also asks that measurement distinguish four separate things: the impression, the QR code rendering, the scan, and downstream advertiser-site activity. Presence of a QR code is not exposure, and exposure is not a scan."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What vastlint did with these, and what we changed",
          "paragraphs": [
            "We shipped seventeen rules for the CTV Ad Portfolio and the 4.4 draft on 25 July, including value checks for plcmt, pos, playbackmethod and the motion attributes, and structural checks for the QR block. Every one of them was written against the 4.x pattern, and the 2.0 path had no coverage at all.",
            "Running the extension documents own examples through that build was not a good look. None of the AdCOM value checks fired, because the integers were not where the rules looked for them. None of the QR checks fired, because the block sits in Creative/CreativeExtensions on a 2.0 document. What did fire was the generic extension check, reporting that a MediaFiles element inside an Extension is in an unusual place, which is true in general and wrong here: in this extension that is precisely where it belongs.",
            "The squeezeback example collected one more, a version mismatch, because it declares version 2.0 while carrying a SIMID interactive creative file. Strictly that is correct, SIMID is a 4.x capability. In context it is the entire point of the extension, which exists to deliver 4.x capability inside a 2.0 document. A rule that is right in general was wrong on this path.",
            "That was a gap and it was ours, so we closed it. The value and QR checks now reach the 2.0 container, the generic extension and version rules skip standardised IAB containers, and six new rules cover the failure modes the container introduces on its own. The catalog goes from 212 rules to 218. All five VAST 2.0 examples published in the two extension documents now validate clean.",
            "One of those six is worth more than the others. VAST 2.0 hangs Extensions off InLine rather than Creative, so a multi-creative response with no CreativeId binds the media and the format signals to whichever creative the receiving platform happens to pick. Nothing else in the document is malformed, which is why it needs a rule of its own rather than a schema check.",
            "While fixing it we found a second defect of our own making. Our attr check accepted only 21, 22 and 23, the three motion attributes. AdCOM 1.0-202607 added 19 Contains advertiser QR Code and 20 Support alpha channel transparency in the same family, and IAB declares 19 in its examples, so we were reporting the reference implementation as wrong. The accepted set is now 19 through 23."
          ]
        },
        {
          "type": "code",
          "heading": "Before and after on the IAB's own VAST 2.0 examples",
          "language": "text",
          "code": "Before                                    After\n\nStatic Screensaver Ad     2 warnings      0 findings\n  extension-misplaced-element (x2)\n\nVideo Pause Ad            1 info          0 findings\n  adcom-attr-not-motion on attr 19\n\nSIMID Squeezeback Ad      4 warnings      0 findings\n  extension-misplaced-element (x3)\n  version-mismatch\n\nPause Ad with QR Code     0 findings      0 findings\n  (no checks were reachable)              (signals and QR both validated)"
        },
        {
          "type": "paragraphs",
          "heading": "The values are a live binding to a document that moves",
          "paragraphs": [
            "Both extension documents make the same deliberate choice: they do not reproduce the AdCOM enumeration tables. They link to them, and they say that if a referenced AdCOM list is updated, implementations should follow the updated list without requiring a change to the extension document.",
            "As a spec-maintenance decision that is clearly right. It stops four copies of the same table drifting apart. As an operational fact it means the meaning of an integer inside your VAST response is defined by a separate repository on a separate release cadence, and you are expected to track it.",
            "Worth knowing what that repository did this month. AdCOM 1.0-202607 was tagged on 16 July, the day before this pull request merged, and it is the release that actually adds plcmt 5 through 9, pos 8 through 17, playbackmethod 8 through 11, and creative attributes 19 through 23. It also rewords five playback methods that already existed, and it carries a Content object with seven field names that were renamed by accident in March and corrected on the main branch on 22 July without the tag being re-cut.",
            "So the honest summary of the binding is: follow the current list, and be aware that the current list and the current release are not always the same document."
          ]
        },
        {
          "type": "list",
          "heading": "If you are shipping CTV Ad Portfolio formats through VAST 2.0",
          "items": [
            "Decide which encoding each partner expects, and ask rather than assume. The 4.x per-signal pattern and the 2.0 container pattern are both current and they are not interchangeable.",
            "Always send CreativeId when the response has more than one Creative. It is the only thing binding the extension to its creative, and omitting it fails silently rather than loudly.",
            "Include a native NonLinear fallback resource wherever practical, so a player that ignores the extension still has something to render instead of firing an error.",
            "Treat QR position and size as ad-view relative, and check that the resolved rectangle fits inside the ad view and does not cover an AdChoices icon or a player control.",
            "Keep QrCodeScanUrl and the clickthrough separate in your reporting, and do not let a rendered QR code be counted as a scan.",
            "Pin the AdCOM release you validate enum values against, and diff it when a new one is tagged. The integers in your VAST response are defined somewhere you do not control."
          ]
        },
        {
          "type": "cta",
          "heading": "Check a CTV Ad Portfolio tag",
          "paragraph": "Paste a tag into the validator for the structural, media file, macro and tracking findings, plus the CTV Ad Portfolio and 4.4 rules on the 4.x signaling path. It runs locally in the browser and nothing is stored.",
          "href": "/validate/",
          "label": "Open the validator"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "CTV Ad Portfolio for VAST 2.0",
              "href": "https://github.com/InteractiveAdvertisingBureau/vast/blob/master/extensions/ctv_ad_portfolio.md",
              "description": "The extension document defining Extension type=\"ctv_ad_portfolio\", its CreativeId binding rule, the MediaFiles delivery model and the AdCOM signal elements. Merged 17 July 2026.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "CTV QR Code Creative Extension for VAST 2.0",
              "href": "https://github.com/InteractiveAdvertisingBureau/vast/blob/master/extensions/ctv_qrcode.md",
              "description": "The tl_qrcode CreativeExtension: scan URL, image URL, ad-view-relative position and size, and the measurement guidance separating rendering from scanning.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "A pause ad used to be a JPEG. VAST 4.4 changes that.",
              "href": "/blog/vast-4-4-draft-schema-ctv-ad-portfolio",
              "description": "The third file in the same pull request, and the rules we shipped for it.",
              "source": "vastlint"
            },
            {
              "label": "CTV Ad Portfolio signaling and VAST validation",
              "href": "/blog/ctv-ad-portfolio-signaling-vast-validation",
              "description": "The finalised signaling guidance and what it asks a VAST response to declare.",
              "source": "vastlint"
            },
            {
              "label": "AdCOM 1.0-202607: new enums, five redefined playback methods, and two releases carrying the wrong field names",
              "href": "https://rtblint.org/blog/adcom-1-0-202607-enums-and-content-rename/",
              "description": "What the integers in these extensions actually mean, what changed on 16 July, and why the tagged release and the current document disagree.",
              "source": "rtblint"
            },
            {
              "label": "VAST rule catalog",
              "href": "/docs/rules/",
              "description": "Every rule vastlint checks, including the CTV Ad Portfolio and VAST 4.4 rules shipped on 25 July.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "adcp-vast-asset-declared-vs-verified",
      "title": "AdCP Can Declare a VAST Tag. It Cannot Check One.",
      "description": "The AdCP creative protocol has a first-class VAST asset: delivery type, version, tracking events, VPAID support, captions. Every one of those fields is a claim about a document nobody has parsed, and a generative creative agent produces documents that look right for the same reason it produces text that reads right. Which claims a parser settles, and why a validator is the feedback signal that closes the loop.",
      "publishedAt": "2026-07-29",
      "author": "Alex Sekowski",
      "readingTime": "10 min read",
      "heroKicker": "Agentic creative",
      "tags": [
        "AdCP",
        "Agentic",
        "AI creative",
        "VAST validator",
        "Standards"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The manifest has a VAST asset type now",
          "paragraphs": [
            "Most coverage of agentic advertising stops at the deal. An agent discovers inventory, negotiates terms, confirms a media buy, and the story ends there. It does not end there. Something has to ship a creative, and for video that something is a VAST tag, which is why the AdCP creative protocol carries a VAST asset as a first-class type alongside hosted video, images, and trackers.",
            "The asset is deliberately thin. Only the discriminator is required. Everything else is optional metadata, and the schema is explicit about why there is no width or height on it: a VAST response can return several renditions at different dimensions, and the player picks one per device at serve time, so dimensional and codec constraints live on the format and requirements layer rather than on the asset.",
            "Two delivery types are defined, and the distinction matters for validation. A url asset points at an endpoint that returns VAST XML. An inline asset carries the XML in a content string. In the first case nobody knows what the tag says until someone fetches it. In the second the bytes are right there in the manifest and still nobody has parsed them."
          ]
        },
        {
          "type": "code",
          "heading": "A VAST asset as it appears in a creative manifest",
          "language": "json",
          "code": "{\n  \"assets\": {\n    \"video_main\": {\n      \"asset_type\": \"vast\",\n      \"delivery_type\": \"url\",\n      \"url\": \"https://adserver.example/vast?pl=[PLACEMENT]&cb=${CACHEBUSTER}\",\n      \"vast_version\": \"4.2\",\n      \"vpaid_enabled\": false,\n      \"duration_ms\": 30000,\n      \"tracking_events\": [\"impression\", \"start\", \"firstQuartile\", \"midpoint\", \"thirdQuartile\", \"complete\"],\n      \"captions_url\": \"https://cdn.example/spot.vtt\"\n    }\n  }\n}"
        },
        {
          "type": "paragraphs",
          "heading": "Every field there is a claim, not a fact",
          "paragraphs": [
            "Read that asset as a set of assertions about a document nobody has opened. The version is asserted. The duration is asserted, and the schema even qualifies it with if known. The tracking event list is asserted. VPAID support is asserted. The captions URL is asserted to exist and to be a captions file.",
            "None of those assertions are checked by accepting the manifest. A seller agent that validates the manifest against the JSON Schema has confirmed the shape of the claim and nothing about the tag. The gap is not a flaw in AdCP: a protocol for exchanging creative metadata is not a video ad parser, and it should not try to be. But it does mean the interesting failures all land outside the schema."
          ]
        },
        {
          "type": "list",
          "heading": "What only fetching and parsing the tag can settle",
          "items": [
            "Whether the document is well-formed XML at all, or an HTML error page with a 200 status, which is the single most common thing a supposedly working ad tag endpoint returns.",
            "Whether the declared vast_version matches the VAST attribute on the root element, and whether the tag uses elements from a version it does not declare.",
            "Whether the tracking_events the manifest promised actually exist in the tag. A declared complete event with no Tracking node for it is a measurement gap the buyer will discover in reporting.",
            "Whether Impression is present and non-empty. It is required by the specification and routinely omitted by templates that assume something downstream will inject it.",
            "Whether Duration is formatted as HH:MM:SS rather than bare seconds, and whether it agrees with the duration_ms in the manifest.",
            "Whether every media file and tracking URL is https. Players block mixed content outright, and this is invisible in a manifest that only carries the tag endpoint.",
            "Whether a wrapper chain terminates in an InLine ad inside the depth the player allows, and whether each wrapper carries a VASTAdTagURI at all.",
            "Whether the macros in the endpoint survive substitution. The schema accepts VAST-style square-bracket and dollar-brace placeholders as-is and tells buyers not to pre-encode the delimiters, because players match the literal token. A pipeline that percent-encodes them helpfully produces a tag that never resolves."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The version enum stops at 4.2",
          "paragraphs": [
            "One detail is worth flagging for anyone building against the creative protocol today. The VAST asset requirements schema enumerates acceptable versions as 2.0, 3.0, 4.0, 4.1, and 4.2. VAST 4.3 has been final for years and is the version CTV signaling guidance assumes, and a 4.4 draft schema is already circulating.",
            "The practical consequence is a mismatch that no side is wrong about. A seller declaring requirements through AdCP cannot express 4.3 today, so a buyer shipping a 4.3 tag either downgrades the declaration to 4.2 or leaves the field off entirely. Both options put a true statement about the creative outside the protocol, and both are indistinguishable from a genuine 4.2 tag when the manifest is all you have.",
            "This is exactly the class of drift a parser resolves in one call. Read the root element, report the real version, compare it to what was declared, and stop guessing."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Trackers get decomposed, which is useful and lossy",
          "paragraphs": [
            "AdCP does not stop at the tag. It also models individual trackers as their own asset types: a VAST tracker asset for a single Tracking event URL, a DAAST tracker for the audio equivalent, and a pixel tracker for renderer-fired beacons whose event enum mirrors the OpenRTB Native event registry. That decomposition is genuinely useful, because it lets a measurement vendor be attached per event rather than per creative.",
            "It is also lossy in one direction. A decomposed tracker declares that a URL should fire on an event. It says nothing about whether the assembled VAST document places that URL in a node the player will actually read, whether the URL is duplicated across a wrapper chain so the event fires twice, or whether the event name survives the mapping between the flattened AdCP enum and the real VAST elements. Impression, Error, VideoClicks, and ViewableImpression live in dedicated VAST elements rather than under TrackingEvents, and the AdCP enum flattens them into one list by design.",
            "Reassembly is where measurement breaks, and reassembly happens after the manifest is accepted."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "A model that writes a VAST tag writes a plausible VAST tag",
          "paragraphs": [
            "The reason this matters more in an agentic pipeline than it did in a human one is the failure mode of the thing now producing the tag. A creative agent generating VAST XML is doing pattern completion over documents it has seen. Pattern completion is very good at shape and indifferent to constraint, so what comes out looks right in the way a forged signature looks right.",
            "The specific defects are predictable once you know that. Correct element names in the wrong nesting. Duration written as 30 because most numbers in most documents are bare numbers. A tracking event list copied from a different creative, so the manifest promises six events and the document contains four. Attributes that do not exist in any version of the specification but read like they should. Elements from 4.2 inside a document declaring 3.0, because the training data does not separate versions the way a parser does. A UniversalAdId left at the placeholder value that appears in every example tag ever published. http URLs, for the same reason.",
            "None of those are stupid mistakes. They are exactly the mistakes a system optimising for plausibility makes, and they are invisible to every check that operates above the document: the JSON Schema validates the manifest, the manifest declares the tag is 4.2, and the tag says whatever it says.",
            "Asking a second model to review the first one does not fix it either. A reviewing model has the same relationship to the specification as the writing model, which is that it has read a lot of tags and holds no ground truth. Two plausibility engines agreeing is not verification."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "A validator is the feedback signal that closes the loop",
          "paragraphs": [
            "What a parser gives an agent is the one thing the agent cannot produce for itself: a verdict that does not depend on how convincing the output looks. A VAST document either parses or it does not. The required elements are either present or absent. The declared version either matches the root element or it does not. Those are decidable questions with no interpretation in them, which makes them cheap to answer and impossible to argue with.",
            "That turns generation into a loop instead of a gamble. The agent writes a tag, calls the validator, and gets back a list of rule ids with the line and the element each one fired on. It repairs those specific defects and calls again. Because the errors are structural rather than stylistic, the loop usually converges in one or two passes: a missing Impression node is not a matter of taste, and neither is a Duration format.",
            "This is the same property that makes VAST validity usable as a verifiable reward when training a model, which we have written about separately. The argument here is the inference-time half of it. At training time a rule-based checker can score an output without a human in the loop; at generation time that same checker is the grounding signal that stops a plausible tag from shipping as a correct one. One verifier, two uses.",
            "The asymmetry is what makes it worth wiring up. Generating creative is expensive and confident. Checking it is cheap and correct. Putting the cheap correct thing in front of the expensive confident thing is the whole design, and it is the same reason coding agents run tests instead of asking a model whether the code compiles."
          ]
        },
        {
          "type": "list",
          "heading": "Where the check belongs in the creative task loop",
          "ordered": true,
          "items": [
            "build_creative or any generative step: validate what the creative agent produced before it becomes a manifest. A generated tag is a template output, and template outputs fail structurally in the same handful of ways every time.",
            "sync_creatives: this is the natural gate. The seller is already deciding whether to accept the creative, and it is the last point where a rejection costs nothing but a retry. Fetch the tag, parse it, and reject on structural failure rather than on schema shape alone.",
            "preview_creative: a preview that renders is weak evidence, because one player tolerating a tag says little about the next. A parse result is stronger evidence and cheaper to produce.",
            "get_creative_delivery: when delivery numbers look wrong, re-validate the tag as it is being served rather than the tag as it was submitted. Endpoints change behaviour without anyone editing a manifest."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why this is the seller agent's problem",
          "paragraphs": [
            "In a human workflow a broken tag gets caught by an ad ops person who has seen it before and knows what a missing Impression node does to a report. In an agentic workflow that person is not in the loop, and the agent on the other side has no memory of last quarter.",
            "So the gate has to be somewhere in the protocol path, and sync_creatives is the obvious place: the seller is already deciding whether to accept the creative, and a rejection there costs a retry rather than a campaign. A seller that rejects on parse failure closes the loop even when the buyer's agent never opened it.",
            "Both agentic stacks land in the same position on this. IAB Tech Lab's AAMP extends the existing rails and keeps VAST as the video envelope. AdCP defines new agent-native tasks and still ends at a VAST tag. Neither specification validates the creative payload, and neither claims to. That work belongs to whoever wants the impression to render."
          ]
        },
        {
          "type": "cta",
          "heading": "Put the parse step in the agent loop",
          "paragraph": "The agentic integration guide covers wiring the vastlint MCP server into AdCP creative pipelines, AAMP buyer agents, A2A orchestrators, and plain MCP clients, with working configuration for each.",
          "href": "/docs/agentic/",
          "label": "Read the agentic integration guide"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "AdCP VAST asset schema",
              "href": "https://github.com/adcontextprotocol/adcp/blob/main/static/schemas/source/core/assets/vast-asset.json",
              "description": "The vast asset type: delivery_type url or inline, vast_version, tracking_events, vpaid_enabled, accessibility URLs, provenance.",
              "source": "AdCP"
            },
            {
              "label": "AdCP creative protocol documentation",
              "href": "https://docs.adcontextprotocol.org/docs/creative/creative-manifests",
              "description": "Creative manifests, asset types, formats, and the task reference for build_creative, sync_creatives, and preview_creative.",
              "source": "AdCP"
            },
            {
              "label": "AAMP: Agentic Advertising Management Protocols",
              "href": "https://iabtechlab.com/standards/aamp-agentic-advertising-management-protocols/",
              "description": "The IAB Tech Lab stack, which keeps VAST as the video delivery envelope under its agentic layers.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "How AdCP connects to VAST",
              "href": "/docs/adcp/",
              "description": "The layer map: what AdCP automates, and why the VAST tag is still the last mile."
            },
            {
              "label": "VAST version support and error 102",
              "href": "/docs/vast-versions/",
              "description": "What a version mismatch does in a real player, and why declared version and actual version drift apart."
            },
            {
              "label": "VPAID is deprecated",
              "href": "/docs/vpaid-deprecated/",
              "description": "Why a vpaid_enabled claim of true deserves a second look in 2026."
            },
            {
              "label": "VAST validity is a verifiable reward",
              "href": "/blog/vast-validity-is-a-verifiable-reward/",
              "description": "The training-time half of the same argument: why ad-tag validity is one of the few adtech signals a rule-based checker can score without a human or a learned judge."
            },
            {
              "label": "VAST as a reward signal for ML and agents",
              "href": "/docs/vast-reward-signal/",
              "description": "What a verifier has to return to be usable in a training or repair loop: stable rule ids, positions, and dense partial credit."
            }
          ]
        }
      ]
    },
    {
      "slug": "ai-creative-provenance-vast-c2pa",
      "title": "Provenance Is a Claim. The Tag Is the Only Thing That Ships.",
      "description": "AdCP now carries structured provenance for AI-generated creative: IPTC-aligned source types, the model that made it, how much human oversight there was, and C2PA watermark state. None of it travels inside the VAST document the player receives. What survives the handoff, and what to validate so the claim can still be reconciled.",
      "publishedAt": "2026-07-29",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Provenance",
      "tags": [
        "Provenance",
        "AdCP",
        "C2PA",
        "AI creative",
        "Compliance"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The manifest learned to describe how the ad was made",
          "paragraphs": [
            "Generative video went from demo to production inventory faster than the delivery stack adapted, and the agentic protocols are the first place the industry has written down what an AI-made creative should disclose about itself. AdCP has a provenance object that attaches to a creative manifest, to an individual asset, or to a content-standards artifact.",
            "It is more specific than a boolean. A digital source type classifies AI involvement along IPTC-aligned lines. An ai_tool object names the model, its version, and the provider. A human_oversight enum grades involvement from none, through prompt_only, selected, and edited, to directed. A declared_by object records who made the claim and in what role: creator, advertiser, agency, platform, or tool. Timestamps separate when the content was produced from when the claim was attached, which exists because claims get added retroactively for compliance.",
            "The schema also refuses to do something it easily could have done, and the refusal is the most honest sentence in it. Asserting human oversight does not by itself relieve a disclosure obligation, because the carve-outs in regulation have factual prerequisites a schema cannot evaluate. There is a separate C2PA watermark classification distinguishing a watermark cryptographically bound to a manifest from one that exists independently of any manifest."
          ]
        },
        {
          "type": "quote",
          "quote": "Provenance is a claim by the declaring party. Receiving parties should verify claims independently via their own detection tools.",
          "attribution": "AdCP provenance schema"
        },
        {
          "type": "paragraphs",
          "heading": "Now follow the claim into delivery",
          "paragraphs": [
            "A provenance object lives in the creative manifest, which is an agent-to-agent artifact. The thing a player receives is a VAST document, and VAST has no provenance element. There is no field for a model name, no field for an oversight level, no field for a C2PA manifest reference, and no field for the disclosure obligation the manifest was tracking.",
            "So the claim stops at the boundary. Downstream, three things carry identity instead: the creative identifier in Creative id and adId, the Universal Ad ID, and whatever a verification vendor sees through AdVerifications. Everything the provenance object said about how the video was produced is, from the player's point of view, unavailable.",
            "That is survivable, but only if the identifiers that would let anyone reconnect the two halves are actually present and stable. In practice they often are not. A Universal Ad ID left as the placeholder value, a creative id that changes between wrapper hops, an AdVerifications block that no player can parse: each one breaks the link between the served impression and the manifest that described it."
          ]
        },
        {
          "type": "list",
          "heading": "What has to hold for a provenance claim to mean anything at delivery",
          "items": [
            "A real Universal Ad ID, with a registry and a value that is not the unknown placeholder, consistent across every hop of the wrapper chain.",
            "Stable creative identifiers. If the id differs between the manifest, the wrapper, and the inline ad, reconciliation becomes a manual exercise.",
            "A parseable AdVerifications block with a JavaScript resource and verification parameters that survive whatever the ad server did to the tag, since this is the only channel a third party can use to observe anything at render time.",
            "Extensions that are well-formed, because vendor-specific provenance metadata, if anyone carries it, will ride there and a malformed Extensions node can take the surrounding parse with it.",
            "Media files that match what was described. A manifest asserting a generated video of a given duration and a tag serving something else is a provenance failure even if nobody used the word.",
            "Disclosure assets that actually render, when a disclosure is required. An overlay, a companion, or burned-in text is a creative element with its own failure modes, not a metadata field."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The regulatory clock is the reason this stops being theoretical",
          "paragraphs": [
            "The EU AI Act's transparency obligations under Article 50 apply from 2 August 2026. Two of its requirements bear directly on advertising creative. Providers of systems generating synthetic audio, image, video, or text must mark outputs in a machine-readable format that makes them detectable as artificially generated. Deployers of systems producing deepfake content must disclose that the content is artificially generated or manipulated, and advertising using synthetic depictions of real or realistic-looking people, places, or events is squarely in scope.",
            "Note the shape of the first obligation: machine-readable and detectable. A human-visible label alone does not satisfy it. That is precisely what C2PA-style signing and watermarking are for, and precisely what a VAST document does not currently carry.",
            "This is engineering commentary rather than legal advice, and the compliance analysis for any specific campaign depends on facts that are not in the payload. But the direction is not ambiguous. Something machine-readable will have to travel with synthetic creative, and the delivery envelope for video advertising has no slot for it yet."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do before the standards catch up",
          "paragraphs": [
            "The useful posture is to treat the manifest claim and the served tag as two records that must be reconcilable, and to make reconciliation cheap on purpose.",
            "Keep the provenance object with the creative in your own systems, keyed on the identifier that survives delivery, which in practice means the Universal Ad ID. Validate the tag at acceptance so the identifiers you are keying on are present and well-formed before anything serves. Re-validate what is actually being served rather than what was submitted, because endpoints change without manifests changing. And when a disclosure is required, verify it as a rendered creative element, not as a field that was set to true somewhere upstream.",
            "None of that requires a new standard. It requires the same discipline the rest of the creative stack already needs, applied to a claim that currently has nowhere to live."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What would actually close the gap",
          "paragraphs": [
            "Two additions would make provenance survive delivery. A defined place in VAST for a content credentials reference, so a player or verification vendor could locate a C2PA manifest for the media it is about to render. And a normative binding between the creative identifier in the manifest and the identifier in the served document, so the two records are joinable without a spreadsheet.",
            "Both are small, and both are the kind of thing that gets specified after enough people hit the problem. In the meantime the checkable part is the tag, which is the one artifact in this chain that every party receives and every party can parse."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate the tag that carries the claim",
          "paragraph": "vastlint parses a VAST document against the version it declares and reports Universal Ad ID, verification, wrapper, and identifier problems by rule id, in the browser, from the CLI, or as an MCP tool call inside an agent loop.",
          "href": "/docs/agentic/",
          "label": "Read the agentic integration guide"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "AdCP provenance schema",
              "href": "https://github.com/adcontextprotocol/adcp/blob/main/static/schemas/source/core/provenance.json",
              "description": "digital_source_type, ai_tool, human_oversight, declared_by, declared_at, and the caveat that provenance is a claim to be verified independently.",
              "source": "AdCP"
            },
            {
              "label": "AdCP generative creative documentation",
              "href": "https://docs.adcontextprotocol.org/docs/creative/generative-creative",
              "description": "How generative assets are produced and described inside the creative protocol.",
              "source": "AdCP"
            },
            {
              "label": "EU AI Act Article 50",
              "href": "https://artificialintelligenceact.eu/article/50/",
              "description": "Transparency obligations for providers and deployers, including machine-readable marking of synthetic content and deepfake disclosure. Applies from 2 August 2026.",
              "source": "EU"
            },
            {
              "label": "C2PA specification",
              "href": "https://c2pa.org/specifications/",
              "description": "Content Credentials: signed manifests and the watermark action taxonomy AdCP references.",
              "source": "C2PA"
            },
            {
              "label": "Universal Ad ID validation",
              "href": "/docs/universal-ad-id/",
              "description": "Why the identifier that would anchor a provenance claim is so often a placeholder."
            },
            {
              "label": "OMID and AdVerifications",
              "href": "/docs/omid/",
              "description": "The one channel in VAST a third party can use to observe a creative at render time."
            }
          ]
        }
      ]
    },
    {
      "slug": "live-event-ad-insertion-vast-vmap",
      "title": "A Live Ad Break Opens on a Cue. VMAP Was Designed for a Schedule.",
      "description": "Live sports and event streaming break most of the assumptions VAST and VMAP were built on: the break is announced seconds before it starts, its length is fixed by the transport stream, every viewer hits it at once, and nothing can be retried. Where the creative side actually fails, and what to check before the next event window.",
      "publishedAt": "2026-07-29",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "Live events",
      "tags": [
        "Live",
        "VMAP",
        "SSAI",
        "Ad pods",
        "CTV"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The break you cannot reschedule",
          "paragraphs": [
            "Ad insertion for a live event is the same protocol stack as ad insertion for an on-demand episode, running under conditions it was not designed for. Three of those conditions do most of the damage.",
            "The break is not on a timetable. It is announced by an SCTE-35 cue message inserted into the transport stream by the broadcast operation, usually with a short pre-roll interval before the splice point. Everything downstream, ad request, auction, VAST resolution, creative selection, transcode check and manifest manipulation, has to finish inside that interval.",
            "The break has a fixed length that the stream is going to honour whether or not you fill it. Underfill is slate or dead air on a live feed with an audience watching. Overfill means a truncated ad or a late return to content, which on a sports feed means missing the restart.",
            "And every viewer on the feed arrives at the same instant. On demand, a million viewers spread their mid-rolls across the day. Live, a million viewers hit the same cue inside the same second, so anything that is a slow leak in VOD becomes a spike with no recovery window.",
            "None of that is a VAST problem in the sense of a spec defect. VAST and VMAP do their job. But several defaults that are harmless on demand become expensive live, and they are all checkable in advance."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "VMAP describes a schedule. A live break has none.",
          "paragraphs": [
            "VMAP exists to describe where ad breaks sit inside a piece of content: a preroll, a midroll at eleven minutes, a postroll. Every AdBreak carries a required timeOffset attribute telling the player when to insert. That model assumes the breaks are known before playback starts.",
            "For a live feed they are not. The producer decides. The cue arrives. So the working pattern is not a static VMAP served once at stream start, it is a VMAP document generated per cue, or the stitcher calling the ad server directly on cue receipt with the break parameters attached to the request. The static-playlist mental model is where a lot of live integrations go wrong, because it is the one every VMAP tutorial teaches.",
            "This is what a per-cue break looks like. The timeOffset is the real presentation timestamp of the splice point, computed from the cue, and the break identity travels in breakId so the tracking can be reconciled against the broadcast log afterwards."
          ]
        },
        {
          "type": "code",
          "heading": "One AdBreak, generated when the cue arrives",
          "language": "xml",
          "code": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<vmap:VMAP xmlns:vmap=\"http://www.iab.net/videosuite/vmap\" version=\"1.0\">\n  <vmap:AdBreak timeOffset=\"00:41:12.480\" breakType=\"linear\" breakId=\"cue-88421\">\n    <vmap:AdSource id=\"q3-break-2\" allowMultipleAds=\"true\" followRedirects=\"true\">\n      <vmap:AdTagURI templateType=\"vast4\">\n        <![CDATA[https://ads.example.com/live?pod=q3-break-2&dur=120&cb=[CACHEBUSTING]]]>\n      </vmap:AdTagURI>\n    </vmap:AdSource>\n    <vmap:TrackingEvents>\n      <vmap:Tracking event=\"breakStart\"><![CDATA[https://t.example.com/break?e=start&id=cue-88421]]></vmap:Tracking>\n      <vmap:Tracking event=\"breakEnd\"><![CDATA[https://t.example.com/break?e=end&id=cue-88421]]></vmap:Tracking>\n    </vmap:TrackingEvents>\n  </vmap:AdBreak>\n</vmap:VMAP>"
        },
        {
          "type": "paragraphs",
          "heading": "timeOffset has five legal forms, and none of them mean \"now\"",
          "paragraphs": [
            "The legal values are a timecode of the form hh:mm:ss or hh:mm:ss.mmm, a percentage, the keyword start, the keyword end, and a position marker of the form #m. That is the whole vocabulary. There is no value that means \"whenever the cue fires,\" which is exactly why the document has to be generated with a real timecode in it rather than templated once with a placeholder.",
            "Two things go wrong here often enough to be worth naming. The first is a placeholder that never got substituted, which produces a value the player cannot parse and a break that never opens. The second is repeatAfter on a break whose timeOffset is start or end, which is a copy-paste from a VOD template: those positions occur exactly once per playback, so the repeat has no effect and the mid-stream breaks the author thought they had scheduled do not exist.",
            "vastlint reports the first as VMAP-1.0-adbreak-timeoffset-format at error severity and the second as VMAP-1.0-repeatafter-conflict at warning severity. Both are static checks. Neither requires the event to be running."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The wrapper chain is spending a budget it did not set",
          "paragraphs": [
            "A VAST wrapper is a redirect. Each hop in the chain is a full network round trip from the resolving party to another ad server, and only after the last hop returns an InLine response does anyone have a media file to fetch.",
            "In on-demand playback that latency is absorbed. The player has buffer, the viewer is not going anywhere, and a chain of four or five hops resolves in time that nobody notices. In a live break the same chain is spending the cue pre-roll interval, which was not allocated for it and is shared with the transcode and manifest work that has to happen after the creative is chosen.",
            "vastlint's default maximum chain depth is five, which reflects what players and SSPs commonly enforce. That default is a spec-compliance ceiling, not a live-operations target. A chain that resolves reliably in a VOD test harness can exhaust a live decisioning window entirely, and the outcome is not a slow ad, it is no ad, because the stitcher has to splice something at the cue point whether or not the auction finished.",
            "The practical move before an event is to measure the chain depth and resolution time of every tag in the rotation, not to assume the number is small. Wrapper chains grow through intermediaries without anyone editing a tag."
          ]
        },
        {
          "type": "list",
          "heading": "The error codes that describe a live failure after the fact",
          "items": [
            "301: wrapper timeout or wrapper resolution failure. In live this is the signature failure. The chain did not return before the window closed.",
            "302: wrapper limit reached. The chain was longer than the resolver's configured maximum, which is often lower on a live path than on a VOD path.",
            "303: no ads after wrappers. Often a legitimate no-fill, but on a live break it still costs you a filled slot, so it belongs in the same report as the errors.",
            "401 and 402: media file not found, and media file timeout. On a live splice the CDN is being asked for the same asset by every stitcher session at once, which is precisely when a cold object is expensive.",
            "403 and 405: unsupported media, and a problem displaying a supported media file. These are the codec and container mismatches that a stitcher discovers at splice time rather than at trafficking time."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Duration is a contract with the transport stream",
          "paragraphs": [
            "The Duration element inside Linear is required, and in VOD it functions mostly as a hint: the player uses it for the countdown, the skip timer and companion scheduling, and if the media file runs a second longer than declared nothing catastrophic happens.",
            "In a live break it is a contract. The stitcher is assembling a fixed-length segment of stream from the durations it was told, and it is doing that before it has watched the file. If the declared Duration and the actual media length disagree, the assembled break does not line up with the splice point. Short means dead air at the end of the pod. Long means the return to content is late, or the last ad is cut off, which also means its complete event never fires and it is not billable.",
            "On the buy side this is why OpenRTB grew a field for exact acceptable durations rather than a range. The rqddurs array in the bid request says the seller will take a 15 or a 30 and nothing in between, and the spec text names the reason directly: the live TV use case, where non-exact durations produce dead air. A creative whose VAST declares 30 and whose file runs 28 satisfies the auction and breaks the stream.",
            "Which makes the declared Duration one of the few VAST values worth verifying against the actual asset rather than trusting, particularly for creatives that were trafficked for on-demand campaigns and later swept into a live rotation."
          ]
        },
        {
          "type": "quote",
          "quote": "On demand, a bad tag is a slow leak you can investigate tomorrow. On a live break it is one hundred percent of two minutes of inventory, and there is no tomorrow for that audience.",
          "attribution": "vastlint field note"
        },
        {
          "type": "paragraphs",
          "heading": "There is no second request",
          "paragraphs": [
            "A live pod is a sequence of ads delivered against one break with a hard end time. If the ad in slot two fails to resolve, there is no realistic path to requesting a replacement, because the time that would take is time the break does not have. The pod either has a fallback already in hand or it plays slate.",
            "That raises the cost of ordering ambiguity. When some Ad elements in a response carry a sequence attribute and others do not, playback order is undefined, and the player or stitcher resolves it however it resolves it. In VOD that produces an occasional out-of-order pod that nobody notices. In a live break with per-slot pricing and competitive separation rules, an undefined order can put two competing advertisers back to back on a national feed.",
            "vastlint reports mixed sequencing as VAST-2.0-ad-sequence at warning severity. It is a warning because the tag still serves. Treat it as an error in a live rotation.",
            "Running a pod with a typo'd macro and mixed sequencing through the validator produces the findings below. Every one of these is static, and every one of these would be a live failure discovered during the event."
          ]
        },
        {
          "type": "code",
          "heading": "vastlint findings on a two-slot live pod",
          "language": "text",
          "code": "error    VAST-4.1-adservingid-present       InLine is missing AdServingId (x2)\nerror    VAST-4.0-universaladid-present     Creative is missing UniversalAdId (x2)\nwarning  VAST-2.0-ad-sequence               ordering across the pod is ambiguous\nwarning  VAST-2.0-linear-tracking-quartiles no quartile tracking events (x2)\nwarning  VAST-2.0-macro-unknown             [CACHEBUSTNG] is not an IAB macro\ninfo     VAST-4.1-mezzanine-recommended     no Mezzanine; stitchers may reject (x2)\ninfo     VAST-2.0-adsystem-no-version       AdSystem has no version attribute (x2)"
        },
        {
          "type": "paragraphs",
          "heading": "Every viewer arrives in the same second",
          "paragraphs": [
            "The macro finding in that list is the one whose cost scales with the audience. A cachebusting macro with a typo in it is never substituted, so the literal token stays in the URL and every request from every device is byte-identical.",
            "On demand, identical tracking URLs arriving over hours mostly still get counted, because they are separated in time and by IP. On a live break they arrive as one burst of identical requests to the same endpoint, which is the exact traffic shape that caches, proxies and dedupe logic are built to collapse. The impressions do not fail loudly. They are absorbed, and the discrepancy surfaces days later as a reconciliation argument with no evidence trail.",
            "The same reasoning applies to any macro the pipeline is supposed to expand and does not. vastlint reports unrecognised tokens as VAST-2.0-macro-unknown, lowercase macro names as VAST-2.0-macro-lowercase, and unencoded macros inside a URI parameter as VAST-2.0-macro-uri-unencoded. In a live context these stop being hygiene findings and become measurement findings.",
            "Worth noting that server-side insertion changes who expands the macro in the first place. In a fully server-side path the beacons fire from the stitcher's data centre, so the IP and user agent on the tracker belong to the stitcher rather than the viewer, and any macro the player would normally have filled has to be filled by the stitcher instead."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The mezzanine finding is not decoration",
          "paragraphs": [
            "The Mezzanine element carries a high-quality source file intended for transcoding rather than direct playback, and vastlint reports its absence at info severity with the note that ad-stitching servers may reject the tag in CTV and SSAI contexts.",
            "For client-side VOD that severity is right. For a live stitched break it understates the risk. A stitcher needs a rendition that matches the encoding profile of the content stream so the splice is seamless, and if the tag offers only renditions that do not match, the platform either transcodes at insertion time, which costs part of the window, or declines the creative. Neither outcome shows up as a VAST error. It shows up as a slot that filled with something else.",
            "Live is the case where trafficking a mezzanine is worth the storage, and where the info-level finding deserves to be promoted to a gate in whatever check runs before a rotation goes live."
          ]
        },
        {
          "type": "list",
          "heading": "Before the next live window",
          "items": [
            "Validate the generated VMAP, not the template. The bug is almost always an unsubstituted timeOffset or a repeatAfter inherited from a VOD playlist, and both are invisible in the template.",
            "Measure wrapper chain depth and resolution time for every tag in the live rotation. The compliance ceiling is five hops; the live budget is whatever the cue pre-roll interval leaves after transcode and manifest work.",
            "Verify declared Duration against the actual media length for any creative entering a live pod, especially creatives promoted from an on-demand campaign.",
            "Require a Mezzanine, or confirm with the stitching platform that your renditions match its encoding profile. Do this before the event, not from the incident channel during it.",
            "Treat mixed sequencing across the pod as a blocking error rather than a warning, because undefined ordering plus competitive separation rules is a client conversation.",
            "Sweep every URL in the rotation for unknown, lowercase and unencoded macros. Burst traffic is where deduplication eats identical requests.",
            "Validate what the stitcher emits, not only what you author. The tag that runs during the break has been rewritten at least once on its way there."
          ]
        },
        {
          "type": "cta",
          "heading": "Check a live rotation before the cue fires",
          "paragraph": "Paste a VAST tag or a generated VMAP document into the validator and it reports the wrapper, duration, macro, sequencing and mezzanine findings with the spec reference and fix guidance for each. It runs locally in the browser and nothing is stored.",
          "href": "/validate/",
          "label": "Open the validator"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "VMAP 1.0.1 specification",
              "href": "https://www.iab.com/guidelines/digital-video-multiple-ad-playlist-vmap/",
              "description": "The AdBreak, AdSource and TrackingEvents definitions quoted here, including the legal timeOffset forms.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "SCTE 35: Digital Program Insertion Cueing Message",
              "href": "https://www.scte.org/standards/library/catalog/scte-35-digital-program-insertion-cueing-message/",
              "description": "The cue message that opens a live break, and the source of the pre-roll interval the whole ad decisioning path has to fit inside.",
              "source": "SCTE"
            },
            {
              "label": "SSAI rewrites your VAST. Validate what comes out, not what went in.",
              "href": "/blog/ssai-vast-stitch-time-failures",
              "description": "The companion piece on what a stitcher does to a tag between authoring and playback, and where to validate in that pipeline.",
              "source": "vastlint"
            },
            {
              "label": "VMAP validation rules",
              "href": "/docs/vmap/",
              "description": "Every VMAP rule vastlint checks, with severities and examples.",
              "source": "vastlint"
            },
            {
              "label": "Wrapper chains and depth limits",
              "href": "/guides/vast-wrapper-chains/",
              "description": "How chains grow, what enforces the ceiling, and how to measure resolution time.",
              "source": "vastlint"
            },
            {
              "label": "VAST error codes",
              "href": "/docs/vast-error-codes/",
              "description": "The 301, 302, 303, 401, 402, 403 and 405 codes referenced above, with the causes behind each.",
              "source": "vastlint"
            },
            {
              "label": "Live event ad insertion is a burst, not a stream",
              "href": "https://rtblint.org/blog/live-event-ad-insertion-openrtb/",
              "description": "The buy-side half of the same break: which OpenRTB fields describe live content, why rqddurs exists, and the field that changed meaning in June 2026.",
              "source": "rtblint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ad-format-guidelines-v2-mediafile-claims",
      "title": "The Video Encoding Guidelines Got Their First Rewrite Since 2022. VAST Only Carries the Claim.",
      "description": "Two documents were finalized on 22 July 2026. The signaling one got the coverage. The other, Ad Format Guidelines for Digital Video and CTV v2.0, sets the bitrate ladder, the codec floor, the loudness target and the mezzanine rules, and VAST declares conformance to all of it without proving any of it. What the XML can settle, and what needs the file.",
      "publishedAt": "2026-07-26",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Standards",
      "tags": [
        "Ad Format Guidelines",
        "MediaFile",
        "Mezzanine",
        "CTV",
        "Validation"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The other document that shipped on 22 July",
          "paragraphs": [
            "Two documents came out of the CTV Ad Portfolio process on the same day. The signaling guidance is the one that got written about, including here: it defines how a pause ad or a squeezeback gets traded, and the VAST 4.4 draft schema landed alongside it. The second document is Ad Format Guidelines for Digital Video and CTV v2.0, and it is the first substantial revision of that guidance since June 2022.",
            "It is a different kind of document. Signaling describes the transaction. The guidelines describe the bytes: which codec, which bitrate at which resolution, how loud, what the mezzanine has to be. Produced by the Ad Format Hero Taskforce with contributions from Disney, Google, NBCUniversal and Magnite, it is the closest thing the industry has to a delivery contract for a video ad file.",
            "VAST sits between the two and carries neither. What VAST carries is a set of attributes that assert what the file is. The player reads those attributes, picks a rendition, and starts playback. Nothing between the transcode and the screen checks whether the assertion is true."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What v2.0 actually specifies",
          "paragraphs": [
            "Worth reading in full if you own an encoding pipeline, because most of the numbers moved. The ready-to-serve ladder expanded from three options to four, with a dedicated CTV and HD column, and the ranges are now split by environment rather than given as single values."
          ]
        },
        {
          "type": "list",
          "heading": "The numbers to pin to your transcode config",
          "items": [
            "Ready-to-serve H.264 ladder: 640x360 at 1.5 to 3 Mbps, 854x480 and 960x540 at 2 to 4 Mbps, 1280x720 at 2 to 5 Mbps, 1920x1080 at 4 to 10 Mbps, 3840x2160 at 15 to 30 Mbps. The lower end of each range is for online video, web and mobile. The upper end is for CTV.",
            "Video codec: H.264 (AVC) High Profile is required. H.265/HEVC, VP9 and AV1 are optional and primarily CTV.",
            "Audio: AAC-LC required at 128 to 192 kbps stereo, 48 kHz preferred and 44.1 kHz acceptable. Dolby Digital Plus 5.1 is optional for CTV at 256 to 384 kbps.",
            "Loudness: -24 LKFS plus or minus 2 under ATSC A/85 in the US, -23 LUFS plus or minus 1 under EBU R128 in the EU, true peak at or below -6 dBTP.",
            "Mezzanine: .mov preferred over .mp4, Apple ProRes preferred with DNxHD and DNxHR accepted, native resolution with no upscaling, 8-bit minimum and 10-bit preferred, PCM audio, and no leaders or slate.",
            "Frame rates 23.976, 24, 25, 29.97, 30, 50, 59.94 and 60. Aspect ratios 16:9, 1:1, 9:16 and 2.39:1.",
            "Companion creative around 200 kB for most ads, static display under 350 kB."
          ]
        },
        {
          "type": "quote",
          "quote": "In version 4.x, a single VAST tag identifies all four file versions outlined in this document necessary for smooth ad playback experience.",
          "attribution": "Ad Format Guidelines for Digital Video and CTV, v2.0"
        },
        {
          "type": "paragraphs",
          "heading": "That sentence is the whole problem",
          "paragraphs": [
            "The guidelines nominate VAST as the place where conformance to all four renditions is expressed. So the XML is where an ad server, an SSAI stitcher and a player each learn what they are about to fetch. And every one of those attributes is an unverified claim.",
            "A MediaFile declares delivery, type, width, height, either bitrate or a minBitrate and maxBitrate pair, and in 4.1 and later a codec and a fileSize. Player selection logic is built directly on those numbers: pick the rendition closest to the display, under the bandwidth ceiling, in a supported container. If the numbers are wrong, the player does not fail, it selects wrong. A file declared at 1920x1080 and 800 kbps will be chosen for a living-room screen and will look like it was chosen for a phone.",
            "The failure mode is the one that makes CTV expensive: nothing errors. The impression bills. The discrepancy shows up weeks later in a quality conversation with no evidence attached, because the only shared record of what the file was supposed to be is a PDF and an XML attribute nobody checked."
          ]
        },
        {
          "type": "code",
          "heading": "A declaration that no player will reject and no guideline would pass",
          "language": "xml",
          "code": "<MediaFiles>\n  <MediaFile delivery=\"progressive\" type=\"video/mp4\"\n             width=\"1920\" height=\"1080\" bitrate=\"800\" codec=\"avc1.640028\">\n    <![CDATA[https://cdn.example.com/spot-1080p.mp4]]>\n  </MediaFile>\n</MediaFiles>"
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "That fragment is structurally valid VAST. It passes an XSD. It will play. It is also 800 kbps at 1080p, against a guideline range of 4 to 10 Mbps for that resolution, and it is the only rendition offered, so a CTV player has nothing better to fall back to and a mobile player has nothing lighter. There is no Mezzanine, so an SSAI platform has nothing to transcode from and will either reject the ad or re-encode the already-compressed rendition.",
            "Three separate guideline violations, all of them legible from the XML alone, none of them a VAST spec error."
          ]
        },
        {
          "type": "list",
          "heading": "What the XML can settle on its own",
          "items": [
            "Declared bitrate against declared dimensions. A 1080p rendition claiming 800 kbps, or a 360p rendition claiming 12 Mbps, is either a bad transcode or a bad declaration, and both are worth failing a build over.",
            "Whether a ladder exists at all. One rendition means no adaptive choice for any player on any connection. The guidelines expect four ready-to-serve versions.",
            "Mezzanine presence and completeness. vastlint raises VAST-4.1-mezzanine-recommended when MediaFiles has no Mezzanine, which ad-stitching servers reject in CTV and SSAI contexts, and VAST-4.1-mezzanine-delivery, -type, -width and -height when the element is there but underspecified.",
            "Bitrate declaration coherence. VAST-3.0-minmaxbitrate-pair catches a minBitrate without its maxBitrate, and VAST-3.0-bitrate-conflict catches a file declaring both a fixed bitrate and a range, which leaves the player to guess which one is real.",
            "The structural floor. VAST-2.0-mediafile-delivery, -type and -dimensions cover the attributes a selection algorithm cannot work without, and VAST-2.0-mediafile-delivery-enum catches a delivery value that is neither progressive nor streaming.",
            "Transport. VAST-2.0-mediafile-https flags a media file on plaintext HTTP, which mixed-content policy blocks outright on secure inventory regardless of how good the encode is.",
            "Aspect ratio sanity. Declared width and height that reduce to none of 16:9, 1:1, 9:16 or 2.39:1 will be letterboxed or cropped by somebody downstream, and which one you get is not specified anywhere."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the XML cannot settle, and pretending otherwise helps nobody",
          "paragraphs": [
            "A VAST validator reads XML. It does not open the mp4. Four of the requirements in v2.0 are invisible to it, and they are not minor ones.",
            "Loudness is the obvious case. The -24 LKFS target exists because viewers reach for the remote when an ad is louder than the programme, and nothing in a VAST document says how loud the file is. Codec profile is the second: codec=\"avc1.640028\" claims High Profile at Level 4.0, and an encoder that actually emitted Main Profile produces the same attribute string with a different reality. Bit depth and the no-slate rule for mezzanines are the other two.",
            "Those need the asset. The honest split is to run declaration checks in CI, where they are free and catch the majority of what actually breaks, and probe the file once at creative ingest, where it is cheap because it happens per creative rather than per impression."
          ]
        },
        {
          "type": "code",
          "heading": "The ingest-time probe the XML cannot replace",
          "language": "bash",
          "code": "# what the file actually is\nffprobe -v error -select_streams v:0 \\\n  -show_entries stream=codec_name,profile,width,height,bit_rate,r_frame_rate \\\n  -of json spot-1080p.mp4\n\n# integrated loudness and true peak, against -24 LKFS / -6 dBTP\nffmpeg -i spot-1080p.mp4 -af ebur128=peak=true -f null - 2>&1 | tail -20"
        },
        {
          "type": "paragraphs",
          "heading": "Why this lands now rather than in a quarter",
          "paragraphs": [
            "The six CTV Ad Portfolio formats change the shape of the creative. A pause ad can now carry video rather than a JPEG, an overlay occupies a corner rather than the frame, a squeezeback shares the screen with resized content. Each of those has different encoding implications, and the guidelines were rewritten in the same cycle for exactly that reason.",
            "At the same time the buying side is being automated. An agentic buyer negotiating a pause ad will not open the tag and eyeball the renditions, and the format signal it trades on says which format was bought, not whether the file behind it conforms to the guideline that governs that format. The gap between the signal and the asset is the gap a validator exists to close.",
            "None of this requires waiting for VAST 4.4 to be published. Every check above works against 4.0 through 4.3 tags in production today."
          ]
        },
        {
          "type": "list",
          "heading": "The audit worth running this week",
          "items": [
            "Pull a sample of live tags and list every declared bitrate against its declared resolution. Anything outside the v2.0 range for its tier is a finding, in either the encode or the declaration.",
            "Count renditions per creative. Anything shipping one MediaFile to CTV inventory is shipping no fallback.",
            "Check for Mezzanine on every tag that reaches an SSAI path, and confirm delivery, type, width and height are all present when it is.",
            "Grep for http:// in media file URLs. It is still there more often than anyone expects.",
            "Add an ffprobe and ebur128 pass to creative ingest for the four things the XML cannot see, and record the result next to the tag so a discrepancy conversation has evidence in it."
          ]
        },
        {
          "type": "cta",
          "heading": "Check what your tag declares",
          "paragraph": "Paste a tag into the validator to see the MediaFile and Mezzanine findings with the spec reference and fix guidance for each. It runs locally in the browser and nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "Ad Format Guidelines for Digital Video and CTV",
              "href": "https://github.com/InteractiveAdvertisingBureau/Ad-Format-Guidelines-for-Digital-Video-CTV",
              "description": "The v2.0 document with the ready-to-serve ladder, codec, audio, loudness and mezzanine specifications quoted above. Finalized 22 July 2026 after a second comment round closed 16 July.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "CTV Ad Portfolio",
              "href": "https://iabtechlab.com/standards/ctv-ad-portfolio/",
              "description": "The programme both documents came out of, including the signaling guidance finalized the same day.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Mezzanine files in VAST",
              "href": "/docs/mezzanine/",
              "description": "What the element requires, why SSAI platforms reject tags without one, and the rules that cover it.",
              "source": "vastlint"
            },
            {
              "label": "A pause ad used to be a JPEG. VAST 4.4 changes that.",
              "href": "/blog/vast-4-4-draft-schema-ctv-ad-portfolio",
              "description": "The signaling half of the 22 July release, and the draft schema that landed with it.",
              "source": "vastlint"
            },
            {
              "label": "SSAI rewrites your VAST",
              "href": "/blog/ssai-vast-stitch-time-failures",
              "description": "Why the mezzanine requirement matters at stitch time, and what to validate on the way out.",
              "source": "vastlint"
            },
            {
              "label": "The revenue math of broken VAST",
              "href": "/blog/vast-failures-revenue-math",
              "description": "What silent delivery failures cost at CTV scale, which is the case for gating on any of this.",
              "source": "vastlint"
            },
            {
              "label": "ATSC A/85 and EBU R128",
              "href": "https://tech.ebu.ch/docs/r/r128.pdf",
              "description": "The loudness standards the guidelines defer to for the US and EU targets.",
              "source": "EBU"
            }
          ]
        }
      ]
    },
    {
      "slug": "vast-4-4-draft-schema-ctv-ad-portfolio",
      "title": "A Pause Ad Used to Be a JPEG. VAST 4.4 Changes That.",
      "description": "The IAB CTV Ad Portfolio signaling guidance was finalised on 22 July 2026, and the VAST 4.4 draft schema alongside it rewrites a part of the spec that had barely moved since 2008. What changed, what it does to pause ad economics at $25 to $40 CPM, and how to treat each source.",
      "publishedAt": "2026-07-25",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "Standards",
      "tags": [
        "VAST 4.4",
        "CTV Ad Portfolio",
        "AdCOM",
        "SIMID",
        "Validation"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Two documents, one process",
          "paragraphs": [
            "On 17 July a file called vast_4.4.xsd landed in the IAB Tech Lab VAST repository, from a branch called 4.4Development, in a pull request titled \"CTV Ad Portfolio Updates.\" Five days later, on 22 July, the CTV Ad Portfolio signaling guidance was finalised, after a comment period that closed 5 June.",
            "Both matter, and they sit at different points in the same process. The signaling guidance is a finished standard you can build against today. The schema is explicitly labelled a working draft, in its own annotation: \"IAB VAST (Video Ad Serving Template), Version 4.4 - DRAFT for working group discussion.\"",
            "That is a normal and healthy state for a spec still being worked through, and it is the right label. It also means tooling should treat the two sources differently, which is the decision this post is about."
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vast-4-4-changes.png",
          "alt": "Diagram of the VAST 4.4 changes. The top two thirds show the six CTV Ad Portfolio formats as screen layouts with their signal values: Pause, Screensaver, Overlay, Squeezeback and In-Scene carry AdCOM plcmt 5 to 9 with their pos and playbackmethod values, and Menu is drawn separately because it transacts through the OpenRTB Native object and does not use the NonLinear model, carrying its video as a VAST tag inside video.vasttag. Below that, the NonLinear content model before and after: 4.3 carried resource children, AdParameters and click tracking, while 4.4 adds MediaFiles, Duration, NonLinearCustomClick and Icons on top of those. A closing note covers the typed AdCOM children on Extension and the four QR children on CreativeExtension. The footer states that the signaling guidance is final while the 4.4 XSD is a working-group draft, and that the guidance's own examples still declare version 4.2.",
          "width": 1440,
          "height": 1800,
          "caption": "The six CTV Ad Portfolio formats and the signals that address them, the NonLinear content model before and after, and the typed Extension children that carry bid-request context into the creative.",
          "credit": "Source: IAB Tech Lab CTV Ad Portfolio signaling implementation guidelines, VAST 4.4 draft XSD and AdCOM 1.0. The specification is IAB Tech Lab's. Diagram by vastlint.org, an independent open-source project, not affiliated with or endorsed by IAB Tech Lab."
        },
        {
          "type": "paragraphs",
          "heading": "Why a pause ad schema is worth two days of anyone's time",
          "paragraphs": [
            "US CTV ad spend is heading for roughly $38 billion in 2026, up from about $33 billion last year. This is also the year the CTV upfront, at $17.73 billion, passes primetime linear TV upfront at $16.98 billion for the first time. The pivot everyone forecast is arriving on schedule.",
            "Almost all of that spend is pre-roll and mid-roll. Interruptive inventory. And ad load is the one lever streamers cannot keep pulling, because subscribers notice and subscribers leave.",
            "The six formats in the CTV Ad Portfolio are the alternative. Pause, Screensaver, Overlay, Squeezeback, In-Scene and Menu monetise moments that were previously worth nothing: the viewer hitting pause, the idle home screen, the lower third during play. New inventory that adds no interruption at all.",
            "The pricing backs that up. Hulu pause ads reportedly clear in the $25 to $40 CPM range, which puts them alongside standard programmatic premium AVOD at $25 to $45. A pause ad clears at roughly what a mid-roll clears at, on inventory that costs the publisher nothing in viewer tolerance.",
            "Until now, every one of these formats ran on a bespoke integration. Publisher by publisher, custom fields, custom creative specs, no programmatic scale. That is the problem the Ad Format Hero initiative set out to fix, and it is a genuinely good piece of standards work: hundreds of format submissions from dozens of companies, sorted down to six that cover most of the market. The stated design goal tells you a lot about the care that went in: \"no one should be able to accidentally purchase a pause ad.\" Buyers opt in deliberately."
          ]
        },
        {
          "type": "quote",
          "quote": "The signaling guidance is a finished standard. The schema is still in working-group discussion. Good tooling gives each of those a different amount of weight.",
          "attribution": "vastlint standards note"
        },
        {
          "type": "paragraphs",
          "heading": "The XML change that makes it possible",
          "paragraphs": [
            "Going through the diff, the thing that stands out is how long NonLinearAds sat untouched. Seventeen years, essentially unchanged since VAST 2.0.",
            "Before this, a pause ad was a JPEG. That was the whole vocabulary: one StaticResource, an iframe, or an HTML blob. No video, no duration, and therefore no quartile tracking.",
            "The 4.4 draft gives NonLinear the same MediaFiles container Linear has always had, holding MediaFile, Mezzanine, InteractiveCreativeFile and ClosedCaptionFiles. Video and cinemagraph assets in a pause slot. Duration, so quartiles actually fire. Icons under NonLinearAds for an AdChoices disclosure. And NonLinearCustomClick, missing from every published XSD since 3.0.",
            "The Duration change matters more than it looks. Without it there is no quartile tracking and no overlayViewDuration, which means a buyer cannot verify how long the ad was on screen. Selling a $35 CPM against a format with no duration measurement is a hard conversation."
          ]
        },
        {
          "type": "code",
          "heading": "The new NonLinear, with the fallback that keeps it renderable",
          "language": "xml",
          "code": "<NonLinear width=\"1920\" height=\"1080\">\n  <Duration>00:00:15</Duration>\n  <MediaFiles>\n    <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\">\n      <![CDATA[https://cdn.example.com/pause-fallback.mp4]]>\n    </MediaFile>\n    <InteractiveCreativeFile type=\"text/html\" apiFramework=\"SIMID\">\n      <![CDATA[https://cdn.example.com/pause-simid.html]]>\n    </InteractiveCreativeFile>\n  </MediaFiles>\n</NonLinear>"
        },
        {
          "type": "paragraphs",
          "heading": "Ship a fallback or lose the impression",
          "paragraphs": [
            "The split between MediaFile and InteractiveCreativeFile is the part worth flagging to anyone building creative for these slots. MediaFile is a renderable asset. InteractiveCreativeFile is a separate interactive layer that needs the player to execute SIMID. If the player cannot run SIMID it renders the MediaFile instead. If there is no MediaFile, it fires the error URI and the impression is gone.",
            "SIMID support across CTV devices is nowhere near universal, and there is no credible public number for how far it reaches. You do not need one to do the arithmetic. At a $30 pause CPM, every percentage point of your device base that cannot execute SIMID and has no fallback to render is 30 cents per thousand impressions you never see, with nothing in your logs to explain it. On a hundred million monthly pause impressions, one percent is $30,000 a month. Five percent is $150,000.",
            "The guidance spells the fallback rule out explicitly, which reads like the working group anticipating exactly this failure and heading it off."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Three integers that change what publishers can sell",
          "paragraphs": [
            "Most of this release is plumbing. One part is not, and it is three new AdCOM Creative Attributes describing motion: 21 Static Visual, 22 Limited Motion (Cinemagraph), 23 Full-Motion Video.",
            "Consider what a publisher could express before. MIME types and protocols describe what a placement can decode. Nothing described what experience it expects. A streamer whose pause slot renders an MP4's first frame as a still image, or one designed for subtle cinemagraph motion rather than full video, had two options: block MP4 entirely and lose every buyer who would have complied, or accept motion creative and hope.",
            "Now the publisher sets battr: [22, 23] to block motion while still accepting MP4 delivery, and the DSP declares what it actually sent with attr. Both sides can check. That opens up demand that was previously unbuyable on those placements, and if you are on the sell side it is the piece worth implementing first."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why a VAST element now carries bid-request values",
          "paragraphs": [
            "VAST elements do not normally carry OpenRTB enumerations. In 4.4 they do, and the reason becomes obvious once you follow where the tag ends up.",
            "The VAST response outlives the bid object. An SSAI stitcher or a measurement vendor sitting downstream of the auction never sees the bid, only a creative. Without the format context it has no way to know whether it is about to render a fullscreen pause ad or a lower-third overlay, and no way to verify the creative matches what was bought. So the DSP echoes the context back into the creative, one signal per Extension, marked ext=\"adcom\".",
            "Given how much CTV inventory now moves through server-side stitching, that is the pragmatic call."
          ]
        },
        {
          "type": "code",
          "heading": "The signal round-trip",
          "language": "xml",
          "code": "<Extensions>\n  <Extension type=\"plcmt\" ext=\"adcom\"><plcmt>7</plcmt></Extension>\n  <Extension type=\"pos\" ext=\"adcom\"><pos>14</pos></Extension>\n  <Extension type=\"playbackmethod\" ext=\"adcom\"><playbackmethod>2</playbackmethod></Extension>\n  <Extension type=\"attr\" ext=\"adcom\"><attr>23</attr></Extension>\n</Extensions>"
        },
        {
          "type": "list",
          "heading": "The values, since the guidance spreads them across four tables",
          "items": [
            "plcmt gains 5 Pause, 6 Screensaver, 7 Overlay, 8 Squeezeback, 9 In-Scene. Values 1 to 4 predate the portfolio.",
            "playbackmethod gains 8 and 9 for Pause with sound on and off, 10 and 11 for Screensaver. Overlay, Squeezeback and In-Scene reuse the existing 1 and 2.",
            "pos extends past the old 0 to 7 ceiling: 7 and 8 for fullscreen and partial Pause and Screensaver, 5/9/10/14/15 for Overlay geometry, 11/12/13/16/17 for Squeezeback layouts. Highest value in the document is 17.",
            "attr gains the three motion attributes above, 21 through 23."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "QR codes get a standard, and the timing is interesting",
          "paragraphs": [
            "Pause and screensaver slots are the obvious home for a QR code. The viewer is not mid-content, the remote is in hand, and there is no rush. The draft adds four typed elements for scan URL, image URL, position and size.",
            "What makes the timing interesting is that eMarketer's Industry KPIs reported CTV QR scan rates falling sharply through Q4 2025, while survey work still puts roughly three quarters of viewers willing to scan a relevant TV QR code. If people are willing but scan rates are dropping, execution is the problem: codes too small, badly placed, on screen too briefly, in slots where nobody is holding a phone.",
            "Standardising position and size in the creative payload is a sensible response, and it is the kind of thing that only gets fixed once it is machine-readable. There is a subtlety worth knowing about: Icon types its xPosition and yPosition as vastIntegerOrPercent_type, so xPosition=\"120\" is valid there and has been for years. QrCodePosition types the same-named attributes as vastPercent_type. CTV screens vary too much in resolution for pixels to mean anything, so percentages are clearly the right choice, but anyone generating QR blocks by copying existing icon code will produce something that looks fine and is not."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "How we decided to treat the draft",
          "paragraphs": [
            "Because the schema is still in discussion, there are two places where vastlint waits rather than enforces. Neither is a problem with the draft; both are the kind of detail that gets settled during working-group discussion.",
            "The draft is scoped to the CTV work. Some 4.2 elements are not carried over: AltText, BlockedAdCategories, Expires, IconClickFallbackImage and IconClickFallbackImages. Nothing in the CTV Ad Portfolio guidance touches any of them, so we read their absence as scope rather than deprecation. vastlint models 4.4 as 4.3's content model plus the additions, and does not derive removals from a document still in progress.",
            "The draft is also stricter on Extension than 4.2, making @type required and restricting custom children to the ##other namespace. In 4.2, type is optional and custom children use processContents=\"skip\". Enforcing the stricter form today would flag a lot of deployed vendor extensions, so we are holding off until the schema settles."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Three example typos, contributed back",
          "paragraphs": [
            "Working through the guidance turned up three small things in its example XML: a Screensaver sample with an unbalanced closing tag, an Overlay sample carrying attr 20 where the document defines 21 through 23, and a template still reading version=\"INSERT VAST VERSION\".",
            "Typos in sample markup, nothing structural, and a decent argument for why validators exist. We sent them upstream so they get cleaned up. Worth knowing if you are copying markup out of that document, which most implementers will be."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Keep 4.2 or 4.3 in your version attribute for now",
          "paragraphs": [
            "This is the practical takeaway, and it is the opposite of what you would expect from a new version number.",
            "Every VAST example in the final guidance declares version=\"4.2\". Not one declares 4.4. They use the new NonLinear content model while sitting on a version string the ecosystem has supported since 2019, which matches the deployed base. A player that version-gates strictly will reject a 4.4 tag outright, so you would gain nothing by moving early.",
            "Build the new content model. Keep the old version string."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What we shipped",
          "paragraphs": [
            "vastlint now recognises version=\"4.4\" and validates the CTV Ad Portfolio content model, with 17 new rules in a dedicated category. The catalog is 212 rules.",
            "The severity design follows the lifecycle split at the top of this post. Rules from the finalised guidance carry normal weight. Rules from the draft schema alone stay at warning or info, so the tooling stays useful without getting ahead of the working group. The only errors are constructs malformed under any reading of any version: a non-integer AdCOM payload, a QR position in pixels.",
            "The new NonLinear content model is accepted on any VAST 4.x document rather than only on 4.4, because the guidance's own examples ship it on 4.2 tags. VAST 3.0 and below are unchanged, with a regression fixture guarding it. When 4.4 finalises we re-examine a handful of severities and the tooling catches up in an afternoon."
          ]
        },
        {
          "type": "cta",
          "heading": "Check a CTV Ad Portfolio tag",
          "paragraph": "Paste a pause, overlay or squeezeback tag into the validator and see which of the 17 CTV Ad Portfolio rules fire, with the spec reference and fix guidance for each. Nothing is stored.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "VAST 4.4: what actually shipped",
              "href": "/docs/vast-4-4/",
              "description": "The full technical breakdown, including every content-model change and where the draft schema is wrong.",
              "source": "vastlint"
            },
            {
              "label": "VAST 4.3 to 4.4 migration guide",
              "href": "/docs/vast-4-3-to-4-4/",
              "description": "Element-by-element changes with a migration checklist.",
              "source": "vastlint"
            },
            {
              "label": "CTV Ad Portfolio",
              "href": "https://iabtechlab.com/standards/ctv-ad-portfolio/",
              "description": "The IAB Tech Lab standard, finalised 22 July 2026 after public comment closed 5 June.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Ad Format Guidelines for Digital Video and CTV",
              "href": "https://github.com/InteractiveAdvertisingBureau/Ad-Format-Guidelines-for-Digital-Video-CTV",
              "description": "The signaling implementation guidelines, including the format-to-signal reference table and the SIMID declaration pattern.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST repository",
              "href": "https://github.com/InteractiveAdvertisingBureau/vast",
              "description": "Where vast_4.4.xsd landed on 17 July 2026, via PR #57 from the 4.4Development branch.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "CTV ad market will more than double by end of 2026",
              "href": "https://www.emarketer.com/content/ctv-ad-market-will-more-than-double-by-end-of-2026",
              "description": "The forecast behind the $38 billion figure and the year CTV upfront spend passes primetime linear.",
              "source": "eMarketer"
            },
            {
              "label": "CTV QR code scan rates fell sharply in Q4 2025",
              "href": "https://www.emarketer.com/content/industry-kpis--ctv-qr-code-scan-rates-fell-sharply-q4-2025",
              "description": "Context for why standardising QR geometry in the creative payload matters now.",
              "source": "eMarketer"
            },
            {
              "label": "The IAB standardized signaling for CTV's new ad formats",
              "href": "/blog/ctv-ad-portfolio-signaling-vast-validation",
              "description": "Our July piece on the signaling work while it was still in public comment.",
              "source": "vastlint"
            },
            {
              "label": "Why SIMID creatives keep failing validation in 2026",
              "href": "/blog/simid-creatives-failing-validation-2026",
              "description": "The interactive layer these formats now lean on, and how it fails.",
              "source": "vastlint"
            }
          ]
        }
      ],
      "updatedAt": "2026-08-02",
      "featured": true
    },
    {
      "slug": "vast-failures-revenue-math",
      "title": "The Revenue Math of Broken VAST: What Silent Delivery Failures Cost at CTV Scale",
      "description": "Error 102, stripped verification, and misattributed SSAI beacons are engineering problems with a revenue denominator. At 2026 CTV prices, a one percent silent failure rate on 100 million monthly impressions is real money, and the expensive inventory fails more often than the cheap kind. The unit economics, failure by failure.",
      "publishedAt": "2026-07-16",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Revenue",
      "tags": [
        "CTV",
        "Revenue",
        "CPM",
        "SSAI",
        "Measurement"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The engineering post and the P&L post are about the same event",
          "paragraphs": [
            "We recently published two engineering pieces: what happens when a player meets a VAST version it does not support, and what an SSAI stitcher does to a tag between QA and the screen. Both describe failures that are silent by construction. The ad plays, the dashboards stay green, and the missing pieces are measurement, verification, and attribution rather than pixels.",
            "This post is the translation for the people who own the number. Silent technical failures do not show up as incidents. They show up as fill rate, discrepancy write-offs, IVT credits, and CPM decay, usually one to three quarters after the engineering event that caused them. The mapping from one to the other is not mysterious. It is arithmetic."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Start with the price of one impression",
          "paragraphs": [
            "CTV inventory in 2026 trades in tiers. FAST and broad AVOD inventory clears around 15 to 25 dollars CPM. Premium AVOD runs 25 to 45 dollars. Live sports adjacency and audience-targeted buys reach 45 to 85 dollars. Divide by a thousand and a single impression is worth between 1.5 and 8.5 cents.",
            "That sounds too small to manage until you multiply by delivery volume. A mid-size streamer or FAST channel doing 100 million ad impressions a month at a blended 30 dollar CPM books 3 million dollars of monthly ad revenue. Every one percent of impressions that fails to deliver, or delivers without the metadata the price depended on, is 30,000 dollars a month, 360,000 a year. And one percent is a polite assumption: DoubleVerify's global benchmarks find that without adequate protections more than one in four CTV impressions would fail minimum criteria for fraud-free, viewable, brand-safe delivery."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Failure one: the slot goes empty. Visible, priced, survivable",
          "paragraphs": [
            "A hard failure, a version rejection firing error 102, a wrapper chain that times out, a media file the device cannot decode, means no ad renders. The direct cost is the clearing price of that impression, plus the degraded price of whatever backfill caught the slot after the waterfall burned a few hundred milliseconds.",
            "This is the failure finance already sees, because it has a name on the dashboard: fill rate. It is also the least dangerous failure, precisely because it is visible. An error code generates a report, a report generates a ticket, and the loss stops growing. If all your VAST problems were error 102, you would not need this article."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Failure two: the ad plays but the proof does not. Invisible, repriced",
          "paragraphs": [
            "The quiet version-mismatch failure strips AdVerifications, UniversalAdId, and category metadata while the video plays normally. Nothing is unfilled. What changes is the buyer's side of the ledger: the impression arrives unverifiable, the measurement vendor logs it as unmeasured, and the buyer's count diverges from yours.",
            "That divergence has two revenue consequences. The first is reconciliation: when your ad server and the buyer's measurement disagree, the invoice settles toward the buyer's number, and the gap becomes a discrepancy write-off that never appears in any error report. The second is slower and larger: inventory that persistently fails verification gets repriced. Buyers do not file tickets about your stripped OMID. Their algorithms shade bids on inventory that cannot prove itself, their allow lists quietly drop you from PMPs that require measurement, and the deal renewal comes in lower. CPM decay is the lagging indicator of silent technical failure, and by the time it is visible in the average, the cause is two quarters old."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Failure three: your beacons look like a bot farm. Misclassified, discounted",
          "paragraphs": [
            "The SSAI failure has the worst exchange rate of the three. When a stitcher fires tracking beacons without forwarding device context, the traffic pattern it produces, one data-center IP emitting thousands of impressions with a server user agent, is exactly what fraud detection is built to catch. The impressions were real. The classification is invalid traffic.",
            "The market context makes misclassification expensive. Pixalate's Q4 2025 benchmarks put US CTV invalid traffic at 19 percent, 21 percent globally, and DoubleVerify reported a 140 percent year-over-year surge in CTV fraud schemes in early 2026. Buyers are paying for IVT filtering and acting on it. Impressions flagged invalid are refunded or credited, and the path that produced them gets scored down as a supply source. Getting a delivery path un-flagged after a vendor has classified it is slow, manual, partner-by-partner work. The engineering fix, forwarding X-Forwarded-For and the device user agent on every server-fired beacon, costs a configuration change. The classification it prevents costs a percentage of everything the path delivers."
          ]
        },
        {
          "type": "quote",
          "quote": "Buyers do not complain about broken measurement. They reprice it. The discount arrives without a meeting, without a ticket, and without a line item saying why.",
          "attribution": "vastlint operations note"
        },
        {
          "type": "paragraphs",
          "heading": "Why the revenue-weighted failure rate is worse than the average",
          "paragraphs": [
            "Failure rates get reported per impression. Revenue does not arrive per impression, it arrives per CPM tier, and the failure modes concentrate in the expensive tiers. Live sports is the 45-to-85-dollar inventory, and it is also the most operationally hostile delivery there is: SSAI stitching under live latency, ad pods assembled seconds before air, transcodes on the fly. Premium PMP deals are the inventory that carries verification requirements, which is exactly the metadata a version downgrade strips.",
            "So the distribution of failures is correlated with price. A blended one percent error rate can hide four percent on the inventory that produces a third of revenue. If you weight your error telemetry by clearing price instead of impression count, the number that comes out is the one that belongs in a revenue conversation, and it is reliably uglier than the one in the QA report."
          ]
        },
        {
          "type": "list",
          "heading": "What to put on the revenue dashboard",
          "items": [
            "Revenue-weighted delivery failure rate: error events multiplied by the clearing price of the impression they killed, not a flat error percentage.",
            "Discrepancy percentage by partner and by delivery path, tracked monthly. A widening gap on one partner is a technical failure wearing an accounting costume.",
            "IVT classification rate by delivery path, split client-side versus SSAI. A gap between the two is beacon attribution, not audience quality.",
            "Fill rate by pod position and by tier, so a backfill cascade in premium pods is visible separately from run-of-network noise.",
            "CPM trend on verification-required deals versus open auction. If the gap narrows, buyers have stopped believing your measurement."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The asymmetry that makes prevention cheap",
          "paragraphs": [
            "Everything above is expensive on the loss side and nearly free on the prevention side. Validating a tag before it enters rotation costs milliseconds. Validating what the stitcher serves costs a scheduled job. Catching a version downgrade in CI costs a failing check in a pull request. Against a single month of one percent silent failure at CTV prices, the entire validation program pays for itself with the first incident it prevents.",
            "The engineering teams already have the tools. What they usually lack is the mandate, because the cost lands in a different department's spreadsheet. If you own the revenue number, the cheapest money you will recover this year is sitting between your QA process and your delivery path."
          ]
        },
        {
          "type": "cta",
          "heading": "Put a gate between broken tags and booked revenue",
          "paragraph": "vastlint validates tags at onboarding, in CI, and against served SSAI output, so version downgrades, stripped verification, and malformed trackers surface as failing checks instead of quarter-end discrepancies.",
          "href": "/validate/",
          "label": "Validate a VAST tag"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "CTV CPM Benchmarks 2026",
              "href": "https://www.namediaexperts.com/blog-posts/ctv-advertising-benchmarks-2026-cpm-vcr-roas",
              "description": "The 2026 tier pricing used above: FAST, premium AVOD, live sports, and audience-targeted CPM ranges.",
              "source": "NA Media Experts"
            },
            {
              "label": "Q4 2025 North America IVT and Ad Fraud Benchmarks",
              "href": "https://www.globenewswire.com/news-release/2026/03/09/3251883/0/en/Pixalate-Releases-Q4-2025-North-America-Invalid-Traffic-IVT-Ad-Fraud-Benchmarks-Connected-TV-CTV-IVT-Rate-in-United-States-at-19.html",
              "description": "US CTV invalid traffic at 19 percent, the market backdrop that makes beacon misclassification costly.",
              "source": "Pixalate"
            },
            {
              "label": "CTV Fraud Schemes Surge 140% Globally",
              "href": "https://doubleverify.com/company/newsroom/global-study-ctv-fraud-schemes-surge-140-globally",
              "description": "DoubleVerify's 2026 study on the growth of CTV fraud and the share of impressions failing minimum delivery criteria.",
              "source": "DoubleVerify"
            },
            {
              "label": "What Actually Happens When Your Player Doesn't Support a VAST Version",
              "href": "/blog/vast-version-not-supported",
              "description": "The engineering half of failure two: which metadata a version mismatch silently strips.",
              "source": "vastlint"
            },
            {
              "label": "SSAI Rewrites Your VAST. Validate What Comes Out, Not What Went In",
              "href": "/blog/ssai-vast-stitch-time-failures",
              "description": "The engineering half of failure three: macros, beacon headers, and stitch-time rewrites.",
              "source": "vastlint"
            },
            {
              "label": "Bid request quality is a revenue line",
              "href": "https://rtblint.org/blog/bid-request-quality-auction-economics/",
              "description": "The same translation exercise one layer up the stack, for the OpenRTB bid stream.",
              "source": "rtblint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vast-version-not-supported",
      "title": "What Actually Happens When Your Player Doesn't Support a VAST Version",
      "description": "Error 102 is the loud failure, and it is the rare one. Most version mismatches play the ad and silently drop verification, identity, and tracking metadata instead. Where VAST version support is actually decided, what each failure mode looks like, and how to catch the quiet ones before they cost revenue.",
      "publishedAt": "2026-07-15",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "VAST versions",
      "tags": [
        "VAST versions",
        "Error 102",
        "CTV",
        "Wrappers",
        "VAST validator"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "One question, three different failures",
          "paragraphs": [
            "Ask what happens when an ad stack meets a VAST version it does not support, and most people picture an error code. That answer exists: VAST error 102, the version-not-supported signal the spec has carried since VAST 3.0. In production it is the rarest of three outcomes. The common outcomes are quieter. Either the player renders the ad and silently ignores the parts of the document it does not understand, or something upstream downgraded the tag to an older version before the player ever saw it, shedding features along the way.",
            "All three outcomes cost money. Only one of them tells you it happened. This post walks through where version support is actually decided, what each failure looks like on a real stack, and how to catch the two silent ones."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where version support is decided",
          "paragraphs": [
            "A VAST document declares its version exactly once, in the version attribute on the root VAST element. The player reads that attribute and chooses its parsing behavior from it. That is the entire in-band negotiation. There is no handshake, no capability exchange, and no fallback protocol inside VAST itself.",
            "The real negotiation happens one layer up, in OpenRTB. A video bid request lists the versions the player accepts in imp.video.protocols, using the AdCOM protocols list: VAST 2.0 is value 2, VAST 3.0 is value 3, and VAST 4.0 through 4.2 with their wrapper variants run from 7 to 14. A buyer that respects the list never sends an unsupported version. A buyer that ignores it, or a request that omits it, is how a 4.2 document arrives at a player built for 2.0.",
            "The third decision point is configuration. Ad servers and SSPs let you choose which VAST version they render out, and many default to 2.0 or 3.0 on purpose, because old versions play everywhere. Version support is therefore decided three times, by three different parties, and any one of them can create the mismatch."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The loud failure: error 102",
          "paragraphs": [
            "When a player checks the version attribute and refuses to proceed, the spec gives it error code 102: VAST version of response not supported. The player substitutes 102 into the [ERRORCODE] macro, fires the Error tracker, abandons the ad, and falls through to whatever the waterfall has next. The impression never fires, so the buyer logs a lost opportunity and the publisher logs an unfilled or refilled slot.",
            "Error 102 has one virtue: it is visible. It shows up in error reporting, ad server dashboards break it out, and both sides can see the disagreement and fix it. The fix is alignment work, either the demand side stops sending versions the player cannot read, or the player upgrades.",
            "Two neighboring codes matter for diagnosis. Error 100 is an XML parsing failure and 101 is a schema validation failure. Players without a strict version check often surface a version problem as 100 or 101 instead, when an element from a newer version trips their parser. If a partner's 100s spike right after you move to a newer VAST version, you are usually looking at a version problem wearing a parsing costume."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The quiet failure: the ad plays, the features don't",
          "paragraphs": [
            "Most modern players do not hard-reject on version. They parse the elements they know and skip the rest. Google's IMA SDK reads the version attribute and applies version-appropriate parsing across 2.0 through 4.3. Roku's RAF accepts 4.2 and 4.3 documents but silently ignores some newer fields. For players like these, an unsupported version does not fail. It degrades.",
            "The degradation pattern is consistent: the media file plays, and the money-adjacent metadata disappears."
          ]
        },
        {
          "type": "list",
          "heading": "What silently disappears when a 4.x tag meets an older parser",
          "items": [
            "AdVerifications and OMID measurement. VAST 4.1 moved verification out of Extensions into a first-class element, so an older parser never sees it. Viewability and IVT measurement vanish while the ad plays normally.",
            "UniversalAdId, added in 4.0. Creative deduplication and cross-platform frequency capping lose their key.",
            "Mezzanine, added in 4.0. SSAI stitchers lose the mastering-quality source they transcode from and fall back to whatever MediaFile survives.",
            "ClosedCaptionFiles, added in 4.2. Caption files are dropped without any accessibility warning.",
            "Category with its authority attribute. Brand safety classification quietly falls back to nothing.",
            "SIMID interactivity, formalized in 4.3. Interactive layers simply do not render, while the underlying video still plays."
          ]
        },
        {
          "type": "quote",
          "quote": "Error 102 costs you one impression and files a report about it. The quiet failure costs you measurement, verification, and dedup on every impression while the dashboards stay green.",
          "attribution": "vastlint operations note"
        },
        {
          "type": "paragraphs",
          "heading": "Wrappers multiply the mismatch",
          "paragraphs": [
            "A wrapper chain is not one VAST document. It is one document per hop, and each hop declares its own version. A 4.2 wrapper can point to a 3.0 wrapper that resolves to a 2.0 inline, and nothing in the spec forbids it. The effective feature set of the chain is the minimum of the versions along it, applied hop by hop by whatever parses each document.",
            "That has two operational consequences. Verification injected at the wrapper level survives only if the player understands the wrapper's version. And a downgrade anywhere in the chain, say an SSP re-rendering to 2.0 for compatibility, strips 4.x features for everything downstream, no matter how carefully the inline creative was authored."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why old versions still dominate",
          "paragraphs": [
            "The economics explain the state of the ecosystem. Serving VAST 2.0 or 3.0 is the lowest common denominator: it plays on everything, so nothing visibly breaks, so the integration ticket never gets opened. That is why, seventeen years after VAST 2.0 shipped, a large share of production tags still declare 2.0 or 3.0 even when the buy paid for a 4.x feature set.",
            "The asymmetry is the trap. A version rejection is an incident with an error code and an owner. Silent feature loss is invisible, so every rational participant downgrades toward compatibility, and the industry keeps trading 4.x features that are stripped before they reach glass. If you bought OMID verification or rely on UniversalAdId dedup, the version your stack actually delivers end to end is not a detail. It is whether you got what you paid for."
          ]
        },
        {
          "type": "list",
          "heading": "The playbook",
          "items": [
            "Declare the version you actually use. If the document contains 4.x elements, the root attribute must say so. IMA and other SDKs pick parsing rules from that attribute, and a 4.1 element inside a document declaring version 3.0 may be silently ignored.",
            "Know your player matrix before trafficking. IMA parses 2.0 through 4.3, RAF tops out with partial 4.2 and 4.3 handling, and every CTV platform has its own quirks. The per-platform guides on this site list what each SDK reads and drops.",
            "Populate and respect imp.video.protocols in the bid stream. The protocols list exists so this negotiation happens before the tag is sent, not after it fails.",
            "Validate what the transcoder emits, not what you authored. If an SSP, ad server, or SSAI stitcher re-renders your tag, pull the served document and validate that, because the downgrade happens between your QA and the device.",
            "Pin validation to the version you traffic and run it in CI, so a partner-side version change shows up as a failing check instead of a quarter-end revenue question."
          ]
        },
        {
          "type": "cta",
          "heading": "Check a tag against its declared version",
          "paragraph": "vastlint validates version-specific rules across VAST 2.0 through 4.3: elements that do not exist in the declared version, attributes that arrived later than the version claims, and version-illegal combinations that players resolve by silently dropping features.",
          "href": "/validate/",
          "label": "Validate a VAST tag"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "VAST 4.3 specification",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The current spec, including the version attribute contract and the error code table.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Understand VAST error codes",
              "href": "https://support.google.com/admanager/answer/4442429",
              "description": "Google Ad Manager's operational breakdown of VAST errors, including 100, 101, and 102.",
              "source": "Google"
            },
            {
              "label": "VAST Versions Compared: 2.0-4.3",
              "href": "/docs/vast-versions/",
              "description": "What each version added, the compatibility matrix, and which version to use in 2026.",
              "source": "vastlint"
            },
            {
              "label": "VAST error code reference",
              "href": "/docs/vast-error-codes/",
              "description": "Every VAST error code with causes and fixes, including the 1xx version and parsing family.",
              "source": "vastlint"
            },
            {
              "label": "VAST and OpenRTB: how the two specs meet",
              "href": "https://rtblint.org/guides/vast-and-openrtb/",
              "description": "The bid-stream side of version negotiation, including imp.video.protocols.",
              "source": "rtblint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ssai-vast-stitch-time-failures",
      "title": "SSAI Rewrites Your VAST. Validate What Comes Out, Not What Went In",
      "description": "In CTV, the tag you authored is not the tag that runs. Server-side ad insertion unwraps your wrapper chain, transcodes your media, rewrites your trackers, and fires your beacons from a data center. Five stitch-time failure modes, and the points in the pipeline where validation actually prevents them.",
      "publishedAt": "2026-07-15",
      "updatedAt": "2026-09-26",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "CTV delivery",
      "tags": [
        "SSAI",
        "CTV",
        "VAST macros",
        "Measurement",
        "Tracking"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The tag you authored is not the tag that runs",
          "paragraphs": [
            "Most CTV ad delivery now runs through server-side ad insertion. A stitcher sits between the ad server and the device, fetches your VAST on the server, splices the creative directly into the content stream, and hands the device one continuous video. The device may never see your XML at all.",
            "Almost all VAST QA happens on the document you built: the tag is validated at authoring time, certified with a partner, and archived in a ticket. Between that QA and the glass, the stitcher unwraps it, transcodes it, rewrites it, and often takes over firing its trackers. Each of those transformations is a place where a valid tag becomes a broken delivery, and none of them show up in the QA you did upstream."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What a stitcher actually does to your VAST",
          "paragraphs": [
            "The stitcher fetches the tag server-side and walks the wrapper chain itself, so redirect latency and depth limits play out in a data center rather than on the device. It selects a media file, or transcodes one, to match the content stream's resolution, bitrate, and codec. VAST 4.0 added the Mezzanine element for exactly this consumer: a mastering-quality source the stitcher can transcode cleanly instead of upscaling a compressed MediaFile.",
            "Then it handles tracking, in one of two modes. In client-side beaconing, the stitcher passes tracking metadata to the player SDK and the device fires events. In server-side beaconing, the stitcher fires impressions and quartiles itself on the device's behalf. Every failure mode below traces back to one of these transformations."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Failure one: macros nobody expanded",
          "paragraphs": [
            "VAST 4.1 standardized the macro vocabulary: [TIMESTAMP], [CACHEBUSTING], [DEVICEUA], [IFA], and the rest. In client-side playback the player expands them at fire time. In SSAI the stitcher has to do it, and the handoff is where it breaks. The classic symptom is a [tracker URL that arrives at the ad server](https://pixellint.org/docs/template-vs-fired-urls/) with the literal string [CACHEBUSTING] or [TIMESTAMP] still in it.",
            "Unexpanded macros are not cosmetic. A missing cache buster means intermediaries dedupe distinct impressions. A missing timestamp breaks sequential attribution. A device macro left literal means the measurement vendor receives a beacon it cannot attribute to any device class. Validate the macro syntax in every tracker URL before the tag enters a stitcher's cache, and audit served beacons for literal bracket strings after."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Failure two: beacons from a data center",
          "paragraphs": [
            "In server-side beaconing mode, your impression pixel fires from the stitcher's infrastructure: a cloud IP and a server user agent. To every downstream system that was built for client-fired beacons, that traffic pattern is indistinguishable from a bot farm, because mechanically it is one.",
            "IAB Tech Lab's SSAI guidance defines the fix: the stitcher forwards the original device context on every beacon, X-Forwarded-For for the device IP and X-Device-User-Agent for the device UA, plus the standardized VAST macros carrying device identity. When those headers are missing, ad servers cannot dedupe across devices, IVT filters flag the traffic, measurement vendors discard it, and CPMs follow. If you buy or sell through SSAI, beacon header forwarding is a certification item, not a nice-to-have."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Failure three: the schedule is not the playback",
          "paragraphs": [
            "A stitcher knows when it inserted an ad into the stream. It does not necessarily know whether the device kept playing. Pure server-side quartile firing reports what the schedule intended, not what the viewer saw: a user who backs out at second three can still generate a server-fired complete.",
            "This is why the Media Rating Council's SSAI guidance pushes measurement toward client-side confirmation, and why serious CTV pipelines run hybrid beaconing, with the device confirming playback events even when the server manages the rest. When you evaluate an SSAI partner, the question to ask is precise: which events fire from the server, which from the device, and what happens to quartiles when the session dies mid-pod."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Failure four: verification and interactivity go blind",
          "paragraphs": [
            "AdVerifications carries JavaScript that expects to execute in a client runtime and observe rendering. There is no browser inside a stitcher. Unless the device-side player integrates the OM SDK for CTV and executes the verification resource, OMID measurement on an SSAI path is a field in the XML and nothing else. The same applies to interactive layers: a SIMID creative needs a client player that loads it, and a stitcher that flattens the ad into the stream has nowhere to run it.",
            "The failure is contractual as much as technical. Deals get signed on measured viewability against inventory where the delivery path cannot execute the measurement. If verification matters to the buy, the SSAI path needs an explicit answer for where the verification code runs."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Failure five: the cache serves yesterday's tag",
          "paragraphs": [
            "Stitchers cache aggressively, both transcoded creatives and resolved VAST documents, because stitch-time budgets are tight. The cost is staleness: a campaign that ended, a tracker that rotated, or a creative that was replaced can keep serving from cache until eviction. If your trackers are versioned or your creatives legally time-boxed, the stitcher's cache TTL is part of your compliance surface. Ask for it in writing."
          ]
        },
        {
          "type": "list",
          "heading": "Where validation actually helps",
          "items": [
            "At creative onboarding, before the tag enters anyone's cache: full spec validation, version-appropriate structure, and macro syntax in every tracker URL.",
            "Before stitch execution: confirm a Mezzanine or transcode-suitable MediaFile exists, wrapper depth fits the stitcher's fetch budget, and every tracker is https.",
            "On the served output: pull what the stitcher actually delivers and validate that document, because unwrapping and re-rendering can drop elements your QA verified upstream.",
            "On the beacon stream: sample served beacons for literal macro brackets, missing forwarding headers, and data-center-only IPs on impression events.",
            "An Error tracker in the tag, always, so that when something does fail at stitch time, it reports instead of vanishing."
          ]
        },
        {
          "type": "cta",
          "heading": "Lint the tag at every handoff",
          "paragraph": "The CI guide covers running vastlint at onboarding, before cache insertion, and against served output, so the document that reaches the stitcher is the document you certified.",
          "href": "/docs/validate-vast-in-ci/",
          "label": "Validate VAST in CI"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "VAST Macros in SSAI Environments",
              "href": "https://iabtechlab.com/wp-content/uploads/2020/11/IABTechLab_SSAI_VAST_Macros_v1.0-Nov-2020.pdf",
              "description": "The IAB Tech Lab guidance on macro expansion and device context forwarding for server-side beacons.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Solving Tech Challenges in SSAI",
              "href": "https://iabtechlab.com/solving-tech-challenges-in-ssai-takeaways-from-recent-workshop/",
              "description": "Workshop takeaways on where SSAI implementations diverge and what standardization is still missing.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Server-side Ad Insertion and OTT Guidance",
              "href": "https://mediaratingcouncil.org/sites/default/files/Standards/083021%20SSAI%20and%20OTT%20Guidance%20%20FINAL.pdf",
              "description": "MRC's measurement requirements for SSAI delivery, including client-side confirmation.",
              "source": "Media Rating Council"
            },
            {
              "label": "VAST macros reference",
              "href": "/docs/vast-macros/",
              "description": "The standardized macro list, expansion rules, and validation checks vastlint runs on tracker URLs.",
              "source": "vastlint"
            },
            {
              "label": "Where CTV Ad Revenue Leaks: Protocol, Infrastructure, and Standards Failures",
              "href": "/blog/ctv-revenue-loss-protocol-infrastructure-standards",
              "description": "The wider map of CTV delivery loss that stitch-time failures sit inside.",
              "source": "vastlint"
            },
            {
              "label": "Why CTV VAST Tags Still Fail After QA",
              "href": "/blog/why-ctv-vast-tags-fail-after-qa",
              "description": "The upstream half of this story: why authoring-time QA misses delivery-time failures.",
              "source": "vastlint"
            },
            {
              "label": "SSAI vs CSAI compares a beacon fired by the stitcher with a beacon fired by the device",
              "href": "/blog/ssai-vs-csai/",
              "description": "Who fires the impression, and why the same URL is a different measurement.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "ctv-ad-portfolio-signaling-vast-validation",
      "title": "The IAB Standardized Signaling for CTV's New Ad Formats. The VAST Payload Is Still Unverified.",
      "description": "IAB Tech Lab closed public comment on standardized signaling for the CTV Ad Portfolio in June 2026, adding a common way to trade Pause, Overlay, Squeeze Back, and Menu ads across AdCOM, VAST, and Native. The signal says which format was bought. It does not verify that the VAST payload conforms, and agentic buyers will trade these formats before a human reads the tag.",
      "publishedAt": "2026-07-11",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "CTV standards",
      "tags": [
        "CTV",
        "VAST validator",
        "IAB",
        "Agentic",
        "Standards"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The IAB just finished defining how CTV's new formats get bought and sold",
          "paragraphs": [
            "On June 5, 2026, IAB Tech Lab closed the public comment period on standardized signaling for its CTV Ad Portfolio. The changes are now merging into the GitHub specifications. They are not a new format spec. They are the missing trading vocabulary for formats the portfolio already named, and they touch three core standards at once: AdCOM, VAST, and the Native Ads specification.",
            "This is the concrete deliverable behind a line in the Tech Lab agentic roadmap that most people skimmed past. The roadmap committed to completing the signals for programmatic trading in OpenRTB, VAST, and SIMID by Q2 2026. The CTV Ad Portfolio signaling is a large part of what that sentence meant. Q2 is now over, and the work shipped."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the signaling actually adds",
          "paragraphs": [
            "For years, connected TV advertising meant one programmatic shape: a linear video ad that interrupts the stream, served as a VAST tag with MediaFiles and tracking. The CTV Ad Portfolio names a set of formats that do not fit that shape. Pause ads appear when the viewer stops playback. Overlay ads sit in the lower third while content keeps running. Squeeze back ads shrink the program into an L or a frame to share the screen. Menu and screensaver ads live in the platform interface, outside video playback entirely.",
            "Buyers and sellers already ran these as custom deals, trafficked by hand, because there was no standard way to say inside a bid which format was on offer. The new signaling adds that vocabulary. A seller can now declare, in a machine-readable field, that an impression is a pause ad rather than a mid-roll, and a buyer can bid on it as such. As IAB Tech Lab CEO Anthony Katsur put it, standard formats are only part of the equation, and you need a clear way to signal what is actually being bought and sold."
          ]
        },
        {
          "type": "list",
          "heading": "The formats getting a standard programmatic signal",
          "items": [
            "Pause ad: a static or video experience shown when the viewer pauses content with the remote.",
            "Overlay ad: a non-linear unit in the lower third or a corner while the program continues to play.",
            "Squeeze back ad: the program resizes into an L-shape, frame, or double box so an ad can share the screen.",
            "Screensaver ad: an OS or app-initiated experience shown during idle time.",
            "Menu ad: a unit placed in the home screen or navigation UI, outside video playback.",
            "In-scene insertion: branded elements composited into the content itself, closer to product placement than a spot."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "This lands on the agentic buying stack immediately",
          "paragraphs": [
            "Two agentic standards stacks are already in production, and both resolve a video buy to a VAST tag. IAB Tech Lab's AAMP wires OpenRTB, AdCOM, OpenDirect, and VAST together under agent interfaces. The Ad Context Protocol, now at 3.1, runs an agent-native pipeline from inventory discovery through creative production, and a video creative on that path ends as a VAST document handed to the sell side. Neither stack changes the endpoint. Every video transaction still resolves to InLine or Wrapper, MediaFiles, Impression pixels, and TrackingEvents.",
            "The new signaling changes what the agents negotiate over. A seller agent will offer a pause ad, a buyer agent will bid on it by format, and the deal will clear machine to machine without a human reading the tag. The format is no longer an implied pre-roll. It is a declared contract with its own rendering behavior, and the VAST that fulfills it has to match the declaration."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "A signal is a promise, not a proof",
          "paragraphs": [
            "Standardized signaling solves the discovery and transaction problem. It does nothing about correctness. The AdCOM or VAST field that says pause ad is an assertion by the seller. It is not a check that the delivered payload is a well-formed pause ad, or valid VAST at all. The trade can clear on a signal while the tag underneath is malformed, mis-shaped for the format, or wrapped in a chain that drops the very signal that sold it.",
            "This is the same gap the agentic protocols already carry, now widened by new surface. The protocol layer moves deal state and format signals between agents. The correctness of what actually ships is out of scope for the signaling, and out of scope for AAMP and AdCP alike. A new format vocabulary means new ways for the payload to disagree with the promise."
          ]
        },
        {
          "type": "list",
          "heading": "Where the new formats break at the payload",
          "items": [
            "A tag signaled as a non-linear pause or overlay ad but structured as a standard linear InLine, so the player renders it in the wrong slot or not at all.",
            "Interactive overlay and squeeze back formats that rely on SIMID for remote or QR interaction, a component with a documented history of failing validation.",
            "MediaFiles whose dimensions, delivery, or apiFramework do not match the format the impression was sold as.",
            "TrackingEvents mapped to a linear lifecycle that never fires for a non-interruptive format, silently losing measurement.",
            "Wrapper chains that resolve to an InLine stripped of the format signal or the universal ad ID, so the payload no longer proves what the deal promised."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Validate the artifact, not just the deal",
          "paragraphs": [
            "The fix is not exotic. It is a validation step at the payload, before the tag enters a deal and before an agent commits to it. vastlint validates the VAST document these formats ship as: structure across VAST 2.0 through 4.3, MediaFiles, tracking, wrapper resolution, universal ad IDs, OMID, and SIMID. It checks what the tag is, independent of what a signal claims it is.",
            "In an agentic loop that matters more, not less, because there is no human in the path to catch a payload that does not match its declaration. Run the vastlint MCP server inside a buyer or seller agent and the tag gets validated before the deal clears, in the same protocol the agents already speak. The signal tells the agents what was bought. Validation confirms that what ships is what was signaled."
          ]
        },
        {
          "type": "cta",
          "heading": "Wire validation into your agent loop",
          "paragraph": "The agentic integration guide covers connecting the vastlint MCP server to AAMP buyer agents, AdCP pipelines, A2A orchestrators, and plain MCP clients like Claude and Cursor, so the VAST payload gets checked before an agent commits to a deal.",
          "href": "/docs/agentic/",
          "label": "Read the agentic integration guide"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "CTV Ad Portfolio",
              "href": "https://iabtechlab.com/standards/ctv-ad-portfolio/",
              "description": "The IAB Tech Lab portfolio that defines Pause, Overlay, Squeeze Back, Menu, Screensaver, and In-Scene formats.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab Introduces Standardized Signals For CTV Ad Portfolio For Public Comment",
              "href": "https://www.prnewswire.com/news-releases/iab-tech-lab-introduces-standardized-signals-for-ctv-ad-portfolio-for-public-comment-302763676.html",
              "description": "The May 2026 announcement of AdCOM, VAST, and Native signaling updates, with public comment open through June 5, 2026.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Navigating the Agentic Frontier: The IAB Tech Lab 2026 Roadmap",
              "href": "https://iabtechlab.com/navigating-the-agentic-frontier-the-iab-tech-lab-2026-roadmap/",
              "description": "The roadmap that committed to completing programmatic trading signals for OpenRTB, VAST, and SIMID in Q2 2026.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Why SIMID creatives keep failing validation in 2026",
              "href": "/blog/simid-creatives-failing-validation-2026",
              "description": "The interactive layer these overlay and squeeze back formats lean on, and why it fails validation.",
              "source": "vastlint"
            },
            {
              "label": "What Is the Latest VAST Version? VAST 4.3, VAST 4.4 Status, and the IAB CTV Addendum",
              "href": "/blog/latest-vast-version",
              "description": "Version context for the VAST changes underneath the CTV Ad Portfolio signaling work.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "content-taxonomy-authority-and-shareable-reports-in-vastlint",
      "title": "Content Taxonomy authority validation and shareable reports land in vastlint 0.8.0",
      "description": "vastlint 0.8.0 validates the authority attribute on <Category> and <BlockedAdCategories> against the IAB Content Taxonomy registry, and vastlint check --share now returns a public report link. Four new rules, 191 total, plus a crates.io housekeeping note for cargo users.",
      "publishedAt": "2026-07-05",
      "updatedAt": "2026-07-05",
      "author": "Alex Sekowski",
      "readingTime": "6 min read",
      "heroKicker": "Product update",
      "tags": [
        "Content Taxonomy",
        "Brand safety",
        "VAST validator",
        "Ad ops",
        "Release"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "What shipped",
          "paragraphs": [
            "vastlint 0.8.0 adds IAB Content Taxonomy authority validation: four new rules that check the value of the authority attribute on <Category> and <BlockedAdCategories> elements, bringing the catalog to 191 rules. Presence checks existed already; these validate what the attribute actually says.",
            "Shareable report links are also live. vastlint check tag.xml --share validates as usual, uploads the report, and prints a public vastlint.org/r/ URL you can paste into Slack, a ticket, or a partner escalation. The tag itself never leaves your machine.",
            "Both run everywhere the core runs: the CLI, the Rust, JS, Python, Ruby, Go, and Elixir libraries, the web validator, and the hosted MCP server at vastlint.org/mcp."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the authority attribute matters",
          "paragraphs": [
            "A category code like IAB6-7 means nothing on its own. It is a key into a taxonomy, and the authority attribute names which one: the URL of the organization that maintains the category list. VAST 4.0 made authority required on <Category>, and VAST 4.1 added it to <BlockedAdCategories>.",
            "In production tags, authority carries everything from bare domains to typos to free prose. A malformed value breaks category mapping for every downstream system that tries to resolve it. On <BlockedAdCategories> the failure is quieter and worse: a block list nobody can resolve blocks nothing, and the wrapper's brand safety intent silently evaporates."
          ]
        },
        {
          "type": "code",
          "heading": "Three authorities, three different verdicts",
          "language": "xml",
          "code": "<Category authority=\"my taxonomy\">IAB6-7</Category>\n<Category authority=\"taxonomy.example.com\">IAB6-7</Category>\n<Category authority=\"https://www.iabtechlab.com/IABTC/2.2\">IAB6-7</Category>"
        },
        {
          "type": "list",
          "heading": "What vastlint reports on that snippet",
          "items": [
            "VAST-4.0-category-authority-not-uri (warning) on the first: \"my taxonomy\" cannot be read as an authority URL, so no downstream system can resolve the codes.",
            "VAST-4.0-category-authority-unknown (info) on the second: well-formed, but not an IAB Content Taxonomy registry host. Custom taxonomies are legal per spec, which is why this is Info rather than a warning; it only works if every party in the chain resolves the same authority.",
            "The third passes clean. Bare domains (iabtechlab.com), scheme and www prefixes, iabtechlab.com subdomains such as ads.iabtechlab.com, and version-qualified paths like iabtechlab.com/IABTC/2.2 are all recognised forms.",
            "The same pair of checks runs on <BlockedAdCategories> in wrappers from VAST 4.1 up, as VAST-4.1-blockedadcategories-authority-not-uri and VAST-4.1-blockedadcategories-authority-unknown."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Shareable report links",
          "paragraphs": [
            "Validation results usually die in a terminal scrollback. When the problem is in a partner's tag, you end up screenshotting output or pasting JSON into a ticket. --share replaces that with a link: the report page shows every issue with its rule ID, severity, location, and spec reference, links each rule to its docs page, and works for whoever you send it to, no account needed.",
            "What gets uploaded is the report, never the tag: rule IDs, severities, XPath locations, messages, and summary counts. The input XML stays local. --share is off by default and independent of telemetry, and the default no-storage behaviour of every other vastlint surface is unchanged."
          ]
        },
        {
          "type": "code",
          "heading": "One flag, one link",
          "language": "sh",
          "code": "$ vastlint check preroll.xml --share\n...\nShareable report: https://vastlint.org/r/f63a5b935c"
        },
        {
          "type": "paragraphs",
          "heading": "If you install with cargo",
          "paragraphs": [
            "A housekeeping note for crates.io users: a release pipeline bug meant versions 0.6.3 through 0.7.2 published to npm, PyPI, RubyGems, and hex.pm but never reached crates.io. The pipeline is fixed and both crates are current again. If cargo install vastlint-cli has been serving you 0.6.2, reinstalling picks up macro validation, --share, and the taxonomy rules in one jump."
          ]
        },
        {
          "type": "list",
          "heading": "Also in 0.8.0",
          "items": [
            "Project governance docs: GOVERNANCE.md (roles, key custody, continuity plan), a Contributor Covenant 2.1 code of conduct, a rewritten CONTRIBUTING.md with a DCO requirement and an explicit test policy, and a security assurance case in SECURITY.md. Part of ongoing OpenSSF Best Practices Silver work.",
            "The web validator at vastlint.org/validate now runs the current core, so browser results match the CLI rule for rule.",
            "Full details in the changelog, linked below."
          ]
        },
        {
          "type": "cta",
          "heading": "Check your authorities now",
          "paragraph": "Paste a VAST tag into the validator. If a Category or BlockedAdCategories authority is malformed or unresolvable, you get the rule ID, the exact location, and the fix.",
          "href": "/validate/",
          "label": "Open the validator"
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "IAB Tech Lab Content Taxonomy",
              "href": "https://iabtechlab.com/standards/content-taxonomy/",
              "description": "The registry the new authority checks resolve against, including current taxonomy versions.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VAST specification",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST 4.x defines the authority attribute on Category (4.0) and BlockedAdCategories (4.1).",
              "source": "IAB Tech Lab"
            },
            {
              "label": "vastlint changelog",
              "href": "https://github.com/aleksUIX/vastlint/blob/main/CHANGELOG.md",
              "description": "Everything in 0.8.0, including the release pipeline fix for crates.io.",
              "source": "GitHub"
            },
            {
              "label": "Rule reference",
              "href": "https://vastlint.org/docs/rules/",
              "description": "All 191 rules with examples and fix guidance, including the four new authority rules.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "aamp-vs-adcp-agentic-advertising-standards",
      "title": "AAMP vs AdCP: What IAB Tech Lab and AAO Are Each Building for Agentic Advertising",
      "description": "IAB Tech Lab shipped AAMP 2.0 in June 2026 with transaction-ready buyer and seller agent SDKs. AAO shipped AdCP 3.0 in April. A comparison of the two standards stacks, and the VAST delivery layer both of them depend on but neither verifies.",
      "publishedAt": "2026-07-05",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Agentic advertising",
      "tags": [
        "Standards",
        "Agentic",
        "IAB",
        "Programmatic"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Agentic advertising now has two standards bodies",
          "paragraphs": [
            "Eighteen months ago, agent-driven ad buying was a keynote topic. Today it is two competing standards stacks with shipped software. IAB Tech Lab released AAMP 2.0 in June 2026, adding transaction-ready buyer and seller agent SDKs to the framework it launched in January. AgenticAdvertising.Org, the trade association formed around the Ad Context Protocol, shipped AdCP 3.0 in April and already has 3.1 release candidates in review.",
            "The two efforts are not coordinated. Tech Lab publicly positioned AAMP as the standards-grounded alternative to AdCP, and AAO kept building anyway. Programmatic teams do not get to wait out the fight: buyer agents, seller agents, and the platforms between them are adopting pieces of both, and every video transaction in either stack still resolves to the same artifact at the delivery layer, a VAST tag."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The IAB Tech Lab stack: AAMP",
          "paragraphs": [
            "AAMP (Agentic Advertising Management Protocols) is Tech Lab's umbrella for everything agentic. It rests on three pillars. Agent Foundations contains ARTF, the Agentic Real Time Framework, which defines how agent services run as containers inside host platforms, including real-time bidders. Agentic Protocols covers the Buyer and Seller Agent SDKs plus Agentic Direct, Agentic Deals, and Agentic RTB. Trust and Transparency is anchored by an Agent Registry.",
            "The design philosophy is explicit: build on the rails that already move money. AAMP wires OpenRTB, AdCOM, OpenDirect, and VAST together, with the Model Context Protocol and Google's Agent2Agent protocol as the agent interfaces.",
            "Version 1.0 could only transact direct deals. The 2.0 release added programmatic. The Buyer Agent SDK now creates and optimizes programmatic deals through a three-layer hierarchy of orchestration agents, channel specialists, and functional agents. The Seller Agent SDK turns a static media kit into a storefront that adapts pricing and packaging to the buyer and the deal stage. A Deals Library acts as the system of record, with native OpenDirect 2.1 and Deals API support. Approval gates and audit logs keep humans at the sign-off points."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The AAO stack: AdCP",
          "paragraphs": [
            "The Ad Context Protocol launched in October 2025 from a consortium that included Yahoo, PubMatic, Optable, Scope3, Swivel, and Triton Digital. Governance has since been formalized under AgenticAdvertising.Org (AAO), a trade association with four equally weighted voting classes: brands, agencies, publishers, and technology providers. The reference sell-side implementation lives with the Prebid community, deliberately separate from spec governance.",
            "Where AAMP extends existing rails, AdCP was designed agent-native from the start. It is built directly on MCP and runs asynchronously, so humans can approve while agents negotiate. AdCP 3.0, released in April 2026, stretched the protocol across the full campaign lifecycle: inventory discovery, media buys, creative production with brand.json and the Creative Protocol, governance, and reporting across 20 media channels. The working group is already iterating on 3.1, which tightens the creative lifecycle with retention contracts and status webhooks.",
            "Adoption is real on the sell side. AdCP is in production at Snap, Pinterest, Reddit, Netflix, and Vox Media."
          ]
        },
        {
          "type": "list",
          "heading": "Where the stacks actually differ",
          "items": [
            "Governance: IAB Tech Lab is the incumbent body that already maintains VAST, OpenRTB, and OpenDirect. AAO is a new trade association built specifically for agentic advertising, with brands and agencies holding equal votes to publishers and vendors.",
            "Design center: AAMP layers agents on top of the existing programmatic rails. AdCP defines new MCP-native tasks first and treats legacy systems as integration targets.",
            "Coverage: AAMP is deepest at the transaction layer, with ARTF containers running inside bidder infrastructure. AdCP is broadest across the lifecycle, from planning through creative production to reporting.",
            "Interfaces: both name MCP as a core agent protocol, which means a tool exposed as an MCP server can serve agents on either stack without modification.",
            "Verification: neither stack validates the creative payload. Both move deal state and context between agents; the correctness of what actually ships is out of scope for both specs."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Both stacks still hand off to VAST",
          "paragraphs": [
            "Follow a video buy through either stack and the endpoint is identical. An AAMP agentic deal or an AdCP media buy ultimately serves through an ad server that returns VAST XML: an InLine or Wrapper, MediaFiles, Impression pixels, TrackingEvents. AAMP names VAST among the standards it builds on. An AdCP creative agent that produces video hands a VAST tag to the seller side. Twenty channels of protocol surface on one side, one XML document on the other.",
            "That document is where delivery fails. A missing Duration, an HTTP media URL on a CTV device that requires HTTPS, a wrapper chain that exceeds the player's depth limit, a VPAID creative on an inventory path that dropped VPAID years ago: none of it is visible at the protocol layer. The deal confirms cleanly, the agents log success, and the impression dies at runtime with a VAST error code nobody is watching.",
            "Human traffickers used to be the backstop. In an agent-to-agent transaction there is no trafficker. If the tag gets checked at all, something in the loop has to check it, which means validation has to be a tool the agent calls before the deal confirms, not a QA pass scheduled after launch."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do while the standards fight plays out",
          "paragraphs": [
            "Betting on a single winner is unnecessary. MCP is the shared interface: AAMP's Buyer Agent SDK accepts additional MCP tool servers, and AdCP is MCP-native end to end. A validator exposed over MCP plugs into both stacks today.",
            "vastlint runs 236 rules grounded in the IAB VAST, OMID, and SIMID specs and returns deterministic, machine-readable results. It is available as a hosted MCP endpoint at vastlint.org/mcp, as a CLI for pipelines, and as native libraries. Point either stack's agent at it and gate deal confirmation on a clean tag. The protocols will keep changing; the payload they deliver has been VAST for two decades and will still be VAST when the governance questions settle."
          ]
        },
        {
          "type": "cta",
          "heading": "Wire validation into your agent loop",
          "paragraph": "The agentic integration guide covers connecting the vastlint MCP server to AAMP buyer agents, AdCP pipelines, A2A orchestrators, and plain MCP clients like Claude and Cursor, with working configuration for each.",
          "href": "/docs/agentic/",
          "label": "Read the agentic integration guide"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "AAMP: Agentic Advertising Management Protocols",
              "href": "https://iabtechlab.com/standards/aamp-agentic-advertising-management-protocols/",
              "description": "IAB Tech Lab's umbrella page for the AAMP framework and its three pillars.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "AAMP 2.0 release announcement",
              "href": "https://iabtechlab.com/aamp-2-0-release-brings-transaction-ready-buyer-and-seller-agent-sdks/",
              "description": "The June 2026 release that added transaction-ready buyer and seller agent SDKs and programmatic deals.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Ad Context Protocol documentation",
              "href": "https://docs.adcontextprotocol.org",
              "description": "Official AdCP docs: tasks, the Creative Protocol, brand.json, and the 3.x changelog.",
              "source": "AdCP"
            },
            {
              "label": "AgenticAdvertising.Org",
              "href": "https://agenticadvertising.org",
              "description": "The trade association that governs AdCP, with its four-class voting structure.",
              "source": "AAO"
            },
            {
              "label": "IAB Tech Lab, not a fan of AdCP, releases an agentic advertising framework",
              "href": "https://www.thecurrent.com/marketing-strategy-iab-tech-lab-adcp-agentic-advertising-framework-ai",
              "description": "Coverage of the split between the Tech Lab and AAO tracks.",
              "source": "The Current"
            },
            {
              "label": "AdCP and VAST: the full breakdown",
              "href": "/docs/adcp/",
              "description": "How AdCP's creative and delivery layers map onto VAST validation.",
              "source": "Docs"
            }
          ]
        }
      ]
    },
    {
      "slug": "ctv-revenue-loss-protocol-infrastructure-standards",
      "title": "Where CTV Ad Revenue Leaks: Protocol, Infrastructure, and Standards Failures",
      "description": "US connected TV is heading past a record year, but a large share of the money never becomes working media. Here is where it leaks, with the numbers: broken ad-tag protocol, latency and wrapper-chain infrastructure, and non-compliance with the IAB standards that make an impression measurable.",
      "publishedAt": "2026-06-27",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "CTV economics",
      "tags": [
        "CTV",
        "Revenue recovery",
        "Standards",
        "Ad ops"
      ],
      "featured": false,
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The market got big. The plumbing did not keep up.",
          "paragraphs": [
            "US connected TV is no longer the upstart line item. The IAB projects that US digital video ad spend will pass $80 billion in 2026, growing faster than the ad market overall and crossing 60% of all TV and video budgets for the first time. Inside that total, the IAB's 2026 forecast puts CTV growth at 13.8% while linear TV slips 1.7%. The budget is moving to streaming, and it is moving fast.",
            "The delivery stack underneath it did not scale as cleanly. A CTV impression is the end of a long chain: a request, one or more wrapper redirects, a VAST response, a media file, verification and measurement code, all of it resolving on a living-room device with a thin runtime and an impatient viewer. Every link in that chain is a place where money stops being working media.",
            "The losses sort into three buckets. Protocol failures, where the ad tag itself is malformed or non-conforming. Infrastructure failures, where latency and redirect depth eat the impression before it renders. And non-compliance with standards, where the impression serves but cannot be measured, verified, or trusted. The first two are mostly preventable before launch. The third is what makes the whole market discount the inventory."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The macro number nobody wants to own",
          "paragraphs": [
            "Start with the size of the leak, because it sets the stakes. The ANA's Programmatic Media Supply Chain Transparency Study found that of every dollar entering a demand-side platform, only about 36 cents reaches a consumer in working media. The study put roughly a quarter of open-web programmatic spend, around $22 billion a year, into the wasteful or unproductive column.",
            "Fraud is its own slice of that. Juniper Research estimated $84 billion lost to ad fraud in 2023, about 22% of global digital ad spend, and projected it would rise toward $172 billion by 2028. CTV is now a prime target: Pixalate measured a 19% invalid-traffic rate for US connected TV in Q4 2025, and DoubleVerify reported that bots accounted for 65% of all CTV fraud, a higher share than any other channel.",
            "Those are macro numbers, and not all of them are something a single ad-ops team can fix. But they describe the discount the market applies to inventory it cannot trust. The practical question for anyone shipping tags is narrower and more actionable: which of these losses are sitting in your own delivery path before the campaign even launches?"
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Protocol: the tag is broken before it serves",
          "paragraphs": [
            "A VAST tag is a contract. The IAB specification says an InLine ad carries at least one Impression, that a MediaFile declares a delivery type and bitrate, that a Duration is present and well-formed, that wrapper chains terminate in real creative. A tag can violate any of those and still be valid XML that parses cleanly. It loads, and it is wrong.",
            "When that happens on a player, it does not fail silently in the abstract. It fails with a code. VAST error 301 fires when a redirect does not return a valid response inside the timeout. Error 302 fires when the wrapper limit is reached. Those codes exist precisely because malformed and non-conforming tags are a leading cause of an ad slot going dark, and the slot going dark is revenue that was sold and not delivered.",
            "The protocol surface is also a moving target across versions. VPAID, the old interactive and verification layer, ran arbitrary JavaScript inside the publisher's player. The IAB Tech Lab deprecated it in 2019 because it slowed page loads, opened a security and malware surface, and did not work on mobile or OTT. The replacement split the job into three conforming pieces: SIMID for interactivity, VAST for delivery, and OMID for verification. Tags that still lean on VPAID as a fallback, or that mix the layers incorrectly, are shipping a known-deprecated dependency into the exact environment, CTV, where it was never designed to run."
          ]
        },
        {
          "type": "list",
          "heading": "Protocol-level failures that quietly cost impressions",
          "items": [
            "Missing required fields: an InLine without an Impression, a Linear without a Duration, a Creative without a UniversalAdId in VAST 4.x.",
            "Malformed values: durations that do not match HH:MM:SS, MediaFile delivery types outside the allowed enum, URLs that are not valid URIs.",
            "Insecure resources: HTTP MediaFile or tracking URLs that get blocked by mixed-content policy on secure inventory, so the asset never loads and the beacon never fires.",
            "Deprecated dependencies: VPAID treated as a fallback instead of a migration to SIMID and OMID.",
            "Version drift: a tag that declares one VAST version but uses structures from another, so strict players reject it."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Infrastructure: latency and wrapper chains",
          "paragraphs": [
            "Even a perfectly conforming tag loses money if it arrives too late. CTV viewers abandon quickly. A widely cited peer-reviewed study of 23 million video views (Krishnan and Sitaraman) found that viewers begin abandoning after about two seconds of startup delay, and that each additional second of delay raises the abandonment rate by roughly 5.8%. Time-to-first-frame is not a quality-of-experience nicety. It is a fill-and-completion lever.",
            "Wrapper chains are where that latency accumulates. Each redirect is one more network dependency, one more timeout surface, one more place tracking can diverge from the final inline response. The VAST 4.2 specification recommends limiting a chain to five wrappers before an InLine response, after which a player may reject the rest of the chain. Players enforce their own timeouts well before that: the Google IMA SDK defaults to a five-second load timeout per wrapper. A chain that is technically legal can still blow the budget one hop at a time.",
            "The reason this matters so much in CTV specifically is that the completion bar is high. FreeWheel's marketplace report puts long-form and CTV video completion around 95%. When nearly every successfully rendered ad runs to completion, the impressions you lose are almost entirely the ones that never rendered: the timeout, the dead redirect, the asset that loaded too slowly to count. The loss hides in the gap between ads requested and ads served, not in the completion rate you actually report."
          ]
        },
        {
          "type": "quote",
          "quote": "In CTV the completion rate is not where the money leaks. The leak is upstream, in the impressions that never rendered because a tag was malformed, a redirect timed out, or the chain ran one hop too deep.",
          "attribution": "vastlint operations note"
        },
        {
          "type": "paragraphs",
          "heading": "Non-compliance: served, but unmeasurable",
          "paragraphs": [
            "The third bucket is the one that depresses the price of the whole pool. An impression can render perfectly and still be worth less because no one can prove it happened the way the buyer needs.",
            "Standardized measurement coverage is still partial on CTV. When the IAB Tech Lab extended the Open Measurement SDK to Samsung and LG in 2024, it described that as bringing OM SDK to about 40% of the CTV market, which means the majority of CTV was still outside the standard measurement path. DoubleVerify found that only half of CTV impressions offered full app-level transparency in 2024. Server-side ad insertion compounds this: because beacons fire from the server rather than the player, the MRC's SSAI and OTT guidance is explicit that viewability and interaction cannot be confirmed the way a client-side beacon confirms them, which is why client beacons are still recommended even under SSAI.",
            "Put those together and a large share of CTV inventory is technically delivered but hard to verify, and unverifiable inventory trades at a discount. DoubleVerify's own framing is blunt: absent verification, more than one in four CTV impressions would fail to meet the minimum bar for fraud-free, viewable, brand-safe, brand-suitable delivery, and it estimates roughly $700,000 in wasted spend for every billion impressions when viewability protections are missing. Compliance with the measurement standards is not paperwork. It is what lets the impression be sold at full value."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What you actually control before launch",
          "paragraphs": [
            "Two of the three buckets are addressable before a single impression serves, and they are the two that do not require a measurement contract or a fraud vendor to fix. The protocol bucket is deterministic: a tag either conforms to its declared VAST version or it does not, and that is checkable. The infrastructure bucket is mostly observable: wrapper depth, redirect timing, final media attributes, and insecure resources can all be inspected on the real chain before you traffic it.",
            "The non-compliance bucket is partly yours too. You cannot single-handedly fix CTV measurement coverage, but you can make sure your tags carry conforming verification and interactivity layers, secure resources, and the required identifiers, so your inventory is on the right side of the line when measurement is available.",
            "The point is to stop treating these as post-mortem categories. Underdelivery, low fill, and reporting disputes are usually the late symptoms of failures that were visible in the tag and the chain at launch time."
          ]
        },
        {
          "type": "code",
          "heading": "A pre-launch checklist mapped to where money leaks",
          "language": "text",
          "code": "Protocol (deterministic, validate the XML):\n  [ ] Required fields present: Impression, Duration, MediaFile, UniversalAdId (4.x)\n  [ ] Values well-formed: duration format, delivery enum, valid URIs\n  [ ] No HTTP resources on secure inventory (MediaFile + trackers HTTPS)\n  [ ] No VPAID fallback; SIMID + OMID where interactivity/verification is needed\n  [ ] Declared VAST version matches the structures actually used\n\nInfrastructure (observe the real chain):\n  [ ] Wrapper depth at or under the 5-hop spec ceiling, ideally fewer\n  [ ] Each redirect resolves well inside the player timeout (IMA default 5s)\n  [ ] Final MediaFile MIME, bitrate, and dimensions match the target device\n  [ ] No 3xx/4xx/5xx behavior in intermediate redirects\n\nCompliance (so the impression is worth full price):\n  [ ] Verification resources conform to OMID\n  [ ] Tracking remains consistent across the chain, not just at the first hop\n  [ ] AdVerifications and required identifiers present and well-formed"
        },
        {
          "type": "paragraphs",
          "heading": "Where validation actually helps, and where it does not",
          "paragraphs": [
            "Be honest about scope. A linter cannot recover money lost to bot fraud, cannot extend measurement coverage to a platform that lacks it, and cannot make a slow CDN fast. Those need verification vendors, measurement partners, and infrastructure work.",
            "What a linter does is remove an entire class of loss deterministically: the malformed, non-conforming, insecure, or deprecated tag that was going to fail or go unmeasured before it ever left your hands. That is the protocol bucket in full and a meaningful part of the compliance bucket, checked in milliseconds against the published IAB specification, with a stable rule ID and a spec reference for every finding.",
            "vastlint is built for exactly that floor: 236 rules across VAST 2.0 through 4.3 plus VMAP, DAAST, SIMID, and OMID, available as a CLI, as libraries, as a GitHub Action, as a hosted MCP server, and as a URL inspector that walks every wrapper hop on the live chain. It will not fix the parts of CTV economics that are genuinely someone else's problem. It will make sure none of your lost revenue is the kind you could have caught for free."
          ]
        },
        {
          "type": "resources",
          "heading": "Related guides on vastlint",
          "items": [
            {
              "label": "Common CTV VAST errors",
              "href": "/docs/ctv-vast-errors/",
              "description": "The errors that show up specifically on connected TV devices and why they fail there.",
              "source": "Docs"
            },
            {
              "label": "VAST error codes reference",
              "href": "/docs/vast-error-codes/",
              "description": "What 301 (redirect timeout), 302 (wrapper limit), and the rest actually mean in delivery.",
              "source": "Docs"
            },
            {
              "label": "VAST wrapper chains: limits and debugging",
              "href": "/guides/vast-wrapper-chains/",
              "description": "Wrapper depth, timeout behavior, and how to keep latency from eating the impression.",
              "source": "Guide"
            },
            {
              "label": "VPAID is deprecated, stop treating it as a fallback",
              "href": "/docs/vpaid-deprecated/",
              "description": "Why VPAID was retired and how to migrate to SIMID and OMID for CTV.",
              "source": "Docs"
            },
            {
              "label": "Validating OMID in VAST tags",
              "href": "/docs/omid/",
              "description": "Getting the verification layer right so the impression stays measurable.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "US digital video ad spend to surpass $80B in 2026",
              "href": "https://www.iab.com/news/u-s-digital-video-ad-spend-to-surpass-80b-in-2026/",
              "description": "IAB 2026 Digital Video Ad Spend and Strategy Report: market size and growth versus the total ad market.",
              "source": "IAB"
            },
            {
              "label": "Digital Video Ad Serving Template (VAST)",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The spec family that defines conformance, wrapper limits, and inline responses.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Understand VAST error codes",
              "href": "https://support.google.com/admanager/answer/4442429",
              "description": "Google Ad Manager reference for 301 redirect timeout, 302 wrapper limit, and related delivery errors.",
              "source": "Google Ad Manager"
            },
            {
              "label": "IAB Tech Lab introduces SIMID to replace VPAID",
              "href": "https://iabtechlab.com/press-releases/iab-tech-lab-releases-for-public-comment-a-new-specification-to-improve-transparency-and-user-experience-in-video-advertising/",
              "description": "The rationale for deprecating VPAID and splitting interactivity (SIMID), delivery (VAST), and verification (OMID).",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Open Measurement SDK expands to new CTV platforms",
              "href": "https://www.prnewswire.com/news-releases/iab-tech-lab-expands-open-measurement-sdk-to-new-ctv-platforms-302158395.html",
              "description": "IAB Tech Lab on OM SDK reaching roughly 40% of the CTV market, the measurement-coverage gap.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "DV Global Insights 2025: bot fraud in CTV",
              "href": "https://doubleverify.com/blog/ctv/verify/dv-global-insights-2025-bot-fraud-in-ctv-the-hidden-drain-on-ad-budgets",
              "description": "DoubleVerify on the 65% bot share of CTV fraud and the cost of unprotected, unverified inventory.",
              "source": "DoubleVerify"
            },
            {
              "label": "Pixalate Q4 2025 North America IVT benchmarks",
              "href": "https://www.globenewswire.com/news-release/2026/03/09/3251883/0/en/Pixalate-Releases-Q4-2025-North-America-Invalid-Traffic-IVT-Ad-Fraud-Benchmarks-Connected-TV-CTV-IVT-Rate-in-United-States-at-19.html",
              "description": "Pixalate's 19% US CTV invalid-traffic rate across 100B+ programmatic impressions.",
              "source": "Pixalate"
            },
            {
              "label": "ANA Programmatic Media Supply Chain Transparency Study",
              "href": "https://www.ana.net/miccontent/show/id/rr-2023-12-ana-programmatic-media-supply-chain-transparency-study",
              "description": "Where the open-web programmatic dollar goes: roughly 36 cents reaching the consumer.",
              "source": "ANA"
            },
            {
              "label": "Video Stream Quality Impacts Viewer Behavior (IMC 2012)",
              "href": "https://people.cs.umass.edu/~ramesh/Site/HOME_files/imc208-krishnan.pdf",
              "description": "Krishnan and Sitaraman: each added second of startup delay raises abandonment by about 5.8%.",
              "source": "ACM IMC"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Catch the loss you control before launch",
          "paragraph": "Paste a live VAST URL into the inspector to walk every wrapper hop, or validate the XML against 236 IAB-grounded rules. The cheapest revenue to recover is the kind a malformed tag was about to throw away.",
          "href": "/inspect/",
          "label": "Inspect a live VAST URL"
        }
      ]
    },
    {
      "slug": "vast-validity-is-a-verifiable-reward",
      "title": "Most of Advertising Can't Be a Training Reward. VAST Validity Can.",
      "description": "Reinforcement learning with verifiable rewards works where a rule-based checker can score an output without a human or a learned judge. Math and code qualify. So does VAST. Here is why ad-tag validity is one of the few verifiable rewards in advertising, and how to wire vastlint into a training or fine-tuning loop.",
      "publishedAt": "2026-06-19",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Model training",
      "tags": [
        "Model training",
        "RLVR",
        "Agentic",
        "Standards"
      ],
      "featured": false,
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The reason RLVR works is the reward, not the model",
          "paragraphs": [
            "The most reliable post-training results of the last two years came from a narrow setup: reinforcement learning with verifiable rewards. Instead of a human rating outputs or a second model guessing at quality, a rule-based checker scores each generation against objective, task-grounded criteria. The model generates, the checker returns a verdict, the policy updates against that verdict.",
            "It works best in two places: mathematical reasoning, where an answer is right or wrong, and code generation, where a compiler and a test suite decide. The common thread is not the domain. It is that a cheap, deterministic verifier exists. Where you can compute correctness without a human and without a learned reward model, RL has a clean signal to optimise against. Where you cannot, you are back to expensive labels and reward models that drift.",
            "That framing is worth bringing to advertising, because it changes which problems are tractable. Most of advertising is not verifiable. A few corners of it are. VAST is one of them."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Most adtech signals make terrible rewards",
          "paragraphs": [
            "Think about what you would actually want a media or creative model to optimise. Creative quality is subjective and needs a human or a learned judge. Fill rate, click-through, completion, and revenue are real signals, but they are noisy, they arrive hours or days late, and they are confounded by auction dynamics, audience, and seasonality. Worse, they are gameable: a model can learn to produce tags that score well on a proxy metric without being correct, which is exactly the failure mode verifiable rewards were meant to avoid.",
            "None of those signals give you what a verifier gives you: an immediate, deterministic, ungameable verdict on a single output, with no human in the loop and no second model to train and maintain. For most of advertising, that verdict does not exist.",
            "For VAST, it does. A VAST tag either conforms to the IAB specification at its declared version or it does not. The check is structural, it is grounded in a published standard, and it returns the same answer every time. That is the precise property that made code and math good RLVR domains, and it is rare enough in advertising to be worth building on."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why VAST is verifiable when the rest of the stack is not",
          "paragraphs": [
            "A VAST tag is a contract, not an opinion. The spec says an InLine ad must carry at least one Impression, that a MediaFile has a bitrate and a delivery type, that wrapper chains terminate, that a Duration is present and well-formed. These are not matters of taste. They are checkable against the IAB VAST 2.0 through 4.3 specifications, and a violation is a violation regardless of who is looking.",
            "The catch that makes this useful rather than trivial: a broken VAST tag is still well-formed XML. It parses. A model generating tags will happily produce output that loads cleanly and is wrong, missing a required Impression, pointing at an insecure MediaFile, burying the creative four wrappers deep. None of that throws. So 'it parsed' is not a reward. 'It conforms to the spec' is, and computing that is exactly what a linter does.",
            "vastlint is that linter, built as one Rust core with a Python binding that runs in-process. For a training loop, the binding is the relevant part: validation is a function call, not a subprocess and not a network hop, and it returns a structured result you can turn into a reward in a couple of lines."
          ]
        },
        {
          "type": "list",
          "heading": "What the verifier has to give a training loop",
          "items": [
            "Determinism: the same tag scores the same every step, so the reward is stable and the policy is not chasing a moving target.",
            "Speed in-process: training and rejection sampling touch millions of generations, so a subprocess or network call per sample would dominate the loop. A function call against the Rust core clears a production-size tag in well under a millisecond.",
            "Structured output, not a verdict string: per-rule severities and counts, so you can shape a dense reward instead of a single pass or fail bit.",
            "Spec grounding: every rule traces to a section of the IAB VAST spec, so the thing you optimise toward is standards conformance, not a vendor heuristic the model can overfit.",
            "Version awareness: the tag declares a version, and the checker validates against that version's rules, so the model is rewarded for being correct at the spec it claims."
          ]
        },
        {
          "type": "code",
          "heading": "The reward, concretely",
          "language": "python",
          "code": "import vastlint\n\n# Verifiable reward: deterministic, sub-millisecond, no human, no learned judge.\ndef vast_reward(xml: str) -> float:\n    result = vastlint.validate(xml)\n    if result.valid:\n        return 1.0\n    s = result.summary\n    return -1.0 * s.errors - 0.25 * s.warnings   # shaped, not just pass/fail\n\n\n# Rejection sampling: turn a base model into a clean SFT set without labels.\ndef build_sft_examples(prompt: str, samples: list[str]) -> list[dict]:\n    return [\n        {\"prompt\": prompt, \"completion\": xml}\n        for xml in samples\n        if vastlint.validate(xml).valid\n    ]"
        },
        {
          "type": "paragraphs",
          "heading": "Binary is potent. Dense is better.",
          "paragraphs": [
            "The simplest version of this is a binary reward: valid is one, invalid is zero. That is enough to move a model, and it is how most verifiable-reward setups start. But a binary signal is sparse. Early in training the model is wrong almost every time, so almost every sample returns zero and there is little gradient to learn from.",
            "Because vastlint returns per-rule counts rather than a single bit, you do not have to stay binary. A tag with one error is closer to correct than a tag with ten, and you can say so: weight by severity, penalise an insecure MediaFile more heavily than a missing recommended mezzanine, reward getting from ten errors to one even when the tag is not yet clean. Recent RL work keeps finding the same thing, that when the verifiable reward is sparse it pays to make it dense, and the structured result is what lets you do that here without inventing a separate scorer.",
            "Per-rule output is also what makes the model debuggable during training. Track the valid rate across checkpoints and you get one number. Track which rule IDs fail most and you get a map of what the model has not learned yet, so a regression shows up as a specific spec violation instead of a number that quietly slid."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where a VAST reward actually fits",
          "paragraphs": [
            "The obvious target is any model that writes or repairs ad tags: a creative agent that emits a VAST document, a fine-tuned model that takes a broken tag and returns a fixed one, an SSAI or templating system that assembles tags from parts. In agentic pipelines this lines up with the Ad Context Protocol, where a build_creative step can produce a vast asset and a sync_creatives step hands it to a seller. Training that generator against a verifier means fewer rejections downstream, because the tag was scored against the same standard the seller will check it with.",
            "One honest boundary. Spec validity is necessary, not sufficient. A tag that passes vastlint can still fail to play in a specific player, exchange, or CTV environment, because those impose constraints beyond the standard. So validity is a reward component, the verifiable floor, not the whole objective. That is a feature, not a limitation: it is precisely the part of the problem that can be scored without a human, which is what makes it the right place to apply RL with verifiable rewards. Use it for the floor, and keep human or metric-based signals for the parts that genuinely are not verifiable.",
            "The point is narrow and, hopefully, useful. Advertising has very few places where you can score a model output deterministically and cheaply. Ad-tag conformance is one of the clearest, the verifier already exists, and it is a pip install away."
          ]
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "VAST validation in Python",
              "href": "/docs/best-vast-validator-python/",
              "description": "The Python package: install, the structured result shape, and the training, agentic, and AdCP use cases.",
              "source": "Docs"
            },
            {
              "label": "Agentic ad delivery",
              "href": "/docs/agentic/",
              "description": "Where validation sits in MCP, AAMP, and AdCP agent workflows.",
              "source": "Docs"
            },
            {
              "label": "MCP docs",
              "href": "/docs/mcp/",
              "description": "The same Rust core exposed as an MCP tool for agents that call validation over the protocol.",
              "source": "Docs"
            },
            {
              "label": "Rules reference",
              "href": "/docs/rules/",
              "description": "The rule catalog and severities the verifier scores against.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "Reinforcement Learning with Verifiable Rewards (RLVR)",
              "href": "https://www.emergentmind.com/topics/reinforcement-learning-with-verified-rewards-rlvr",
              "description": "Overview of the post-training paradigm: rule-based verifiers as direct supervision, with success concentrated in math and code.",
              "source": "EmergentMind"
            },
            {
              "label": "Crossing the Reward Bridge: Expanding RLVR Across Diverse Domains",
              "href": "https://arxiv.org/pdf/2503.23829",
              "description": "On extending verifiable-reward RL beyond the math and code domains where it first worked.",
              "source": "arXiv"
            },
            {
              "label": "Hybrid Reinforcement: When Reward Is Sparse, It's Better to Be Dense",
              "href": "https://arxiv.org/pdf/2510.07242",
              "description": "Evidence that dense, shaped reward beats sparse binary reward when verifiable signals are sparse.",
              "source": "arXiv"
            },
            {
              "label": "Digital Video Ad Serving Template (VAST)",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The published IAB standard that defines what conformance, and therefore the reward, means.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Ad Context Protocol: Introduction",
              "href": "https://docs.adcontextprotocol.org/docs/intro",
              "description": "The MCP-based protocol whose vast creative asset a trained generator would produce and a seller would validate.",
              "source": "AdCP"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Put a verifier in your training loop",
          "paragraph": "vastlint is a deterministic, sub-millisecond VAST verifier with a zero-dependency Python binding. Install it and turn spec conformance into a reward signal.",
          "href": "/docs/best-vast-validator-python/",
          "label": "Read the Python guide"
        }
      ]
    },
    {
      "slug": "simid-creatives-failing-validation-2026",
      "title": "Why SIMID creatives keep failing validation in 2026",
      "description": "With VPAID gone from Google IMA and Ad Manager, interactive ads now ship as SIMID. The catch: most SIMID creatives fail VAST validation on the same handful of issues. Here are the InteractiveCreativeFile, apiFramework, nonlinear iframe, and HTTPS errors that block them, and how to catch every one before launch.",
      "publishedAt": "2026-06-18",
      "updatedAt": "2026-06-18",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Interactive ads",
      "tags": [
        "SIMID",
        "VPAID",
        "Interactive ads",
        "CTV",
        "VAST validator"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The interactive ad you shipped no longer renders",
          "paragraphs": [
            "VPAID is gone from the places that mattered. Google IMA dropped VPAID rendering, Google Ad Manager finished sunsetting it, and CTV never accepted it in the first place. The replacement is SIMID, the IAB Secure Interactive Media Interface Definition, and in 2026 it is no longer optional: buyers and SSPs increasingly require interactive creatives to be delivered as SIMID inside VAST 4.x or not at all.",
            "Here is the pattern we keep seeing. A creative that worked fine as VPAID gets re-wrapped as SIMID, passes a quick visual smoke test in one player, then fails silently across half the inventory. The creative is fine. The VAST envelope around it is not. SIMID moved the interactivity into a sandboxed, postMessage-driven iframe, and that change shifts where things break: from runtime JavaScript errors to structural problems in the tag that a validator catches in milliseconds."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where SIMID actually lives in the tag",
          "paragraphs": [
            "SIMID is not a media file. For a linear ad, the interactive layer is declared with an InteractiveCreativeFile element inside MediaFiles, carrying apiFramework=\"SIMID\" and a type attribute for the document MIME type, alongside the regular video MediaFile that plays underneath it. For a nonlinear ad, SIMID is referenced through the NonLinear creative as an iframe resource. The player loads that resource in a sandbox and talks to it over a defined postMessage protocol. There is no direct DOM access the way VPAID had, which is the whole point.",
            "That structure is also exactly where validation fails. The video underneath is valid VAST, so superficial checks pass, but the SIMID declaration is malformed, mistyped, or served over the wrong scheme. The ad either falls back to the linear video with no interactivity or gets rejected outright."
          ]
        },
        {
          "type": "list",
          "heading": "The five issues that block most SIMID creatives",
          "items": [
            "Missing or wrong apiFramework. The InteractiveCreativeFile must declare apiFramework=\"SIMID\". A blank value, a casing mismatch, or a leftover apiFramework=\"VPAID\" makes the player treat the file as an unknown resource and skip the interactive layer.",
            "Missing type on the SIMID resource. The type attribute tells the player what document it is loading. Omit it and many players will not initialise the creative. This is the nonlinear-iframe SIMID type requirement.",
            "Nonlinear SIMID delivered without an iframe resource. A nonlinear SIMID creative has to be an iframe resource. Pointing it at a static or HTML resource instead is a structural error that fails validation before the creative ever loads.",
            "Non-HTTPS resource URLs. SIMID resources served over http break on every modern player and CTV device. Mixed-content blocking is silent: no error dialog, just a creative that never appears.",
            "No video fallback. SIMID layers interactivity on top of a real MediaFile. Ship the InteractiveCreativeFile without a valid video MediaFile underneath and there is nothing to play when interactivity is unavailable, which is most of CTV."
          ]
        },
        {
          "type": "code",
          "heading": "A linear SIMID declaration that validates",
          "language": "xml",
          "code": "<MediaFiles>\n  <!-- The video that actually plays -->\n  <MediaFile delivery=\"progressive\" type=\"video/mp4\"\n             width=\"1280\" height=\"720\">\n    https://cdn.example.com/ad-720p.mp4\n  </MediaFile>\n\n  <!-- The SIMID interactive layer on top of it -->\n  <InteractiveCreativeFile apiFramework=\"SIMID\"\n                           type=\"text/html\">\n    https://cdn.example.com/simid/creative.html\n  </InteractiveCreativeFile>\n</MediaFiles>"
        },
        {
          "type": "paragraphs",
          "heading": "Why this slips through QA",
          "paragraphs": [
            "Manual QA tests one creative in one player on one device. SIMID failures are conditional: a missing type attribute breaks the creative on a CTV player but renders fine in a forgiving desktop SDK, and an http resource is blocked only where the page is served over https. By the time the gap shows up in delivery, the campaign is live and the interactive impressions are quietly falling back to plain video.",
            "Structural validation does not have that blind spot. Every InteractiveCreativeFile, every apiFramework value, every resource scheme, and every nonlinear iframe requirement is a deterministic check. Run it once on the tag and you see all of them at once, with the rule ID and the exact fix, before the creative reaches a player at all."
          ]
        },
        {
          "type": "cta",
          "heading": "Check your SIMID tag now",
          "paragraph": "Paste your VAST tag into the validator. It flags every SIMID issue, the InteractiveCreativeFile attributes, the apiFramework value, the nonlinear iframe requirement, and any non-HTTPS resource, with a rule ID, severity, and the exact fix.",
          "href": "/validate/",
          "label": "Validate a VAST tag"
        },
        {
          "type": "paragraphs",
          "heading": "Fix it once, keep it fixed",
          "paragraphs": [
            "The durable fix is to put the same structural check in front of every interactive creative, not just the ones someone remembers to spot-test. Validate the tag the moment it is trafficked, fail the build when a SIMID rule trips, and the fallback-to-video failure mode disappears. The rules below are the specific SIMID checks vastlint runs, each with examples and fix guidance, plus the broader VAST and IMA context that decides whether your interactive creative renders at all."
          ]
        },
        {
          "type": "resources",
          "heading": "Go deeper on vastlint",
          "items": [
            {
              "label": "What is SIMID? IAB's secure replacement for VPAID",
              "href": "/docs/simid/",
              "description": "How SIMID works with VAST 4.x: the InteractiveCreativeFile element, apiFramework=\"SIMID\", the iframe postMessage API, and SIMID versus VPAID.",
              "source": "Docs"
            },
            {
              "label": "Nonlinear SIMID must be an iframe resource",
              "href": "/docs/simid-rules/SIMID-1.1-nonlinear-simid-no-iframe/",
              "description": "The rule that catches nonlinear SIMID creatives delivered without the required iframe resource.",
              "source": "Rule"
            },
            {
              "label": "SIMID iframe resource requires a type",
              "href": "/docs/simid-rules/SIMID-1.1-iframe-simid-type-required/",
              "description": "Why a missing type attribute on the SIMID iframe resource stops players from initialising the creative.",
              "source": "Rule"
            },
            {
              "label": "SIMID needs a video MediaFile underneath",
              "href": "/docs/simid-rules/SIMID-1.0-simid-mediafile-required/",
              "description": "The fallback rule: a SIMID layer without a valid video MediaFile has nothing to play on CTV.",
              "source": "Rule"
            },
            {
              "label": "Google IMA SDK and VAST: AdsLoader, contentComplete, and errors",
              "href": "/guides/vast-google-ima-sdk/",
              "description": "How IMA handles VAST after VPAID, and the delivery errors to fix before launch.",
              "source": "Guide"
            },
            {
              "label": "VAST versions compared: 2.0 to 4.3, and which to use",
              "href": "/docs/vast-versions/",
              "description": "Which VAST version supports SIMID, what changed for CTV, and what to target for new interactive tags.",
              "source": "Docs"
            },
            {
              "label": "VAST error codes and rules: 236 fixes",
              "href": "/docs/rules/",
              "description": "The full searchable rule catalog, including every SIMID, VAST, and VMAP check with XML examples.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "SIMID 1.2 specification",
              "href": "https://iabtechlab.com/standards/secure-interactive-media-interface-definition-simid/",
              "description": "The IAB Tech Lab SIMID standard: the interface, the postMessage protocol, and how SIMID is referenced from VAST.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VAST 4.x specification",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The VAST standard that defines InteractiveCreativeFile, apiFramework, and how SIMID is carried inside the tag.",
              "source": "IAB Tech Lab"
            }
          ]
        }
      ]
    },
    {
      "slug": "vmap-and-daast-validation-in-vastlint-core",
      "title": "VMAP and DAAST validation land in vastlint core",
      "description": "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.",
      "publishedAt": "2026-06-13",
      "updatedAt": "2026-06-13",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "Product update",
      "tags": [
        "VMAP",
        "DAAST",
        "Digital audio",
        "Ad ops",
        "VAST validator"
      ],
      "featured": false,
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "What shipped",
          "paragraphs": [
            "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 187 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."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "VMAP, briefly: the where and when of ad breaks",
          "paragraphs": [
            "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."
          ]
        },
        {
          "type": "list",
          "heading": "What actually goes wrong with VMAP",
          "items": [
            "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."
          ]
        },
        {
          "type": "code",
          "heading": "VMAP that looks fine and is not",
          "language": "xml",
          "code": "<vmap:VMAP xmlns:vmap=\"http://www.iab.net/videosuite/vmap\" version=\"1.0\">\n  <vmap:AdBreak timeOffset=\"15:00\" breakType=\"linear\">\n    <vmap:AdSource id=\"mid-1\">\n      <vmap:AdTagURI templateType=\"vast3\">\n        https://ads.example.com/vast?cb=[CACHEBUSTER]&pos=mid\n      </vmap:AdTagURI>\n    </vmap:AdSource>\n  </vmap:AdBreak>\n</vmap:VMAP>"
        },
        {
          "type": "list",
          "heading": "What vastlint reports on that snippet",
          "items": [
            "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."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "DAAST, and why audio still matters in 2026",
          "paragraphs": [
            "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."
          ]
        },
        {
          "type": "list",
          "heading": "The DAAST checks that catch real mistakes",
          "items": [
            "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."
          ]
        },
        {
          "type": "code",
          "heading": "A VAST tag pretending to be DAAST",
          "language": "xml",
          "code": "<DAAST version=\"1.0\">\n  <Ad id=\"audio-1\">\n    <InLine>\n      <AdTitle>Morning drive spot</AdTitle>\n      <Impression><![CDATA[https://t.example.com/imp]]></Impression>\n      <Creatives>\n        <Creative>\n          <Linear>\n            <Duration>00:00:30</Duration>\n            <MediaFiles>\n              <MediaFile delivery=\"progressive\" type=\"video/mp4\">\n                <![CDATA[https://cdn.example.com/spot.mp4]]>\n              </MediaFile>\n            </MediaFiles>\n            <VideoClicks>\n              <ClickThrough><![CDATA[https://example.com]]></ClickThrough>\n            </VideoClicks>\n          </Linear>\n        </Creative>\n      </Creatives>\n    </InLine>\n  </Ad>\n</DAAST>"
        },
        {
          "type": "list",
          "heading": "vastlint's verdict",
          "items": [
            "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."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why this belongs in core, not a separate tool",
          "paragraphs": [
            "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."
          ]
        },
        {
          "type": "list",
          "heading": "Where the same checks run",
          "items": [
            "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."
          ]
        },
        {
          "type": "cta",
          "heading": "Validate a VMAP or DAAST tag now",
          "paragraph": "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.",
          "href": "/validate/",
          "label": "Open the validator"
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "Video Multiple Ad Playlist (VMAP) 1.0 specification",
              "href": "https://www.iab.com/wp-content/uploads/2015/06/VMAPv1_0.pdf",
              "description": "The original IAB VMAP 1.0 PDF, published July 19, 2012. The grammar vastlint's VMAP rules are derived from.",
              "source": "IAB"
            },
            {
              "label": "Digital Audio Ad Serving Template (DAAST)",
              "href": "https://www.iab.com/guidelines/daast/",
              "description": "IAB's DAAST landing page, including the deprecation note pointing audio buyers to VAST 4.1 and above.",
              "source": "IAB"
            },
            {
              "label": "VAST 4.1 release: DAAST merged into VAST",
              "href": "https://www.iab.com/news/vast-4-1/",
              "description": "The November 2018 release that folded audio support into VAST via the adType attribute.",
              "source": "IAB"
            },
            {
              "label": "IAB: digital audio ad spend hits $8.4B in 2025",
              "href": "https://radioink.com/2026/04/16/iab-digital-audio-grew-10-in-2025-as-podcasts-near-3b/",
              "description": "IAB/PwC data on 2025 digital audio growth and podcast revenue, the reason legacy audio tags still circulate.",
              "source": "Radio Ink"
            }
          ]
        }
      ]
    },
    {
      "slug": "vastlint-vs-springserve-vast-tag-tester",
      "title": "vastlint vs SpringServe VAST Tag Tester",
      "description": "Paste the live URL at vastlint.org/tester/. SpringServe's tagtest is a player-style check for VAST and VMAP. vastlint owns the standards layer: public rules, hop-by-hop inspection, CLI and CI.",
      "publishedAt": "2026-06-11",
      "updatedAt": "2026-06-11",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Tool comparison",
      "tags": [
        "SpringServe",
        "VAST tester",
        "VAST validator",
        "Ad ops"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "Paste the live VAST URL at https://vastlint.org/tester/. Free, no signup: fetch, preview, tracking. SpringServe's tag tester at tools.springserve.com/tagtest is a fast player-style check for VAST and VMAP: events, diagram, metadata. If the question is whether the tag does something in a player right now, it is a reasonable spot check. Wrapper hops are https://vastlint.org/inspect/.",
            "vastlint answers a different and earlier question: is this tag structurally compliant with the published IAB VAST specifications? It validates VAST 2.0 through 4.3 against public, spec-derived rules, splits the job into a validator for resolved XML, a tester for live URLs, and a wrapper-chain inspector, and ships the same rule engine as a CLI, library, and MCP server you can put in CI.",
            "For most debugging sessions the order matters more than the tool choice. Validate the XML against the standards first, then watch player behavior. Playback symptoms on top of structurally invalid XML are mostly noise."
          ]
        },
        {
          "type": "list",
          "heading": "The fastest way to choose between them",
          "items": [
            "Use SpringServe tagtest when you want a quick player-style event check with a visual diagram of the request flow.",
            "Use SpringServe tagtest when the input is a VMAP document and you want to watch the break structure play out. vastlint's VMAP validation is on the public roadmap but has not shipped yet.",
            "Use vastlint when you need to know whether the tag is compliant with a specific VAST version, with a rule ID, severity, and spec reference for every issue.",
            "Use vastlint when the failure is somewhere inside a wrapper chain and you need hop-by-hop inspection instead of a single end-to-end result.",
            "Use vastlint when validation has to run outside a browser session: CLI, CI, server-side pipelines, or an AI agent calling the MCP server.",
            "Use both when the campaign is valuable: standards validation first, player-style behavior check second."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What SpringServe's tag tester shows on its public surface",
          "paragraphs": [
            "The public tool accepts VAST and VMAP input and reports a player view, the tags tested, the events that fired, a request-flow diagram, and tag metadata. That is genuinely useful for operational spot checks, especially when you want to see event firing without wiring up a test page yourself, and it is a natural fit for teams already working inside the SpringServe ecosystem.",
            "What the public page does not surface is the standards layer. No VAST version support matrix is published, there are no public rule-by-rule diagnostics, no documented methodology for what is checked and why, and no public path to embed the checks in your own pipeline. None of that means the tool is bad. It means the public surface is a tester, not a validation product."
          ]
        },
        {
          "type": "list",
          "heading": "Where vastlint closes the gap",
          "items": [
            "Public rule docs: every rule has its own page with the rule ID, why it fires, and a copyable XML fix.",
            "Published methodology: rules are derived from IAB XSD schemas where they exist and RFC 2119 normative prose where they do not, including VAST 4.3, which has no published XSD.",
            "Current version coverage: VAST 2.0, 3.0, 4.0, 4.1, 4.2, and 4.3 are all validated, with automatic version detection.",
            "Three separated surfaces: a validator for resolved XML, a tester for live URL fetches with creative preview and tracking visibility, and an inspector that unwraps wrapper chains hop by hop.",
            "Reusable engine: the same Rust core ships as a CLI, Go and npm packages, a VS Code extension, and an MCP server, so the check that ran in the browser also runs in CI and server-side systems."
          ]
        },
        {
          "type": "quote",
          "quote": "A player-style tester tells you what happened. A standards validator tells you what is wrong and which line to fix.",
          "attribution": "vastlint field note"
        },
        {
          "type": "code",
          "heading": "Recommended workflow when SpringServe is part of QA",
          "language": "text",
          "code": "# 1. Validate the resolved VAST XML in the vastlint validator\n# 2. If the tag is a live URL, unwrap each hop in the vastlint inspector\n# 3. Run the vastlint tester for creative preview and tracking visibility\n# 4. Fix structural issues first; every rule links to the exact XML fix\n# 5. Finish with a SpringServe player-style pass if the team wants event-level confirmation"
        },
        {
          "type": "list",
          "heading": "When vastlint is the better first choice",
          "items": [
            "The tag fails somewhere and you need the exact element, attribute, and spec reference rather than a playback symptom.",
            "You are trafficking VAST 4.3 or need consistent checks across all six VAST versions.",
            "Validation has to be repeatable: pre-commit, CI, or inline in an SSP, DSP, or ad-server pipeline.",
            "The chain involves multiple wrappers and you need to see which hop breaks.",
            "An AI agent or automated workflow needs a structured pass/fail with rule IDs, via the MCP server."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "When SpringServe tagtest still earns a spot",
          "paragraphs": [
            "If your demand or supply partner runs SpringServe, testing in the same environment they use is a legitimate final check. The event view and request-flow diagram are quick to read, and the VMAP support covers a format vastlint does not validate yet.",
            "The mistake to avoid is treating a player-style pass as proof of standards compliance. A tag can play in one tester and still carry structural issues that fail in stricter players, CTV SDKs, or SSAI environments. Run the standards layer first and the player layer second."
          ]
        },
        {
          "type": "resources",
          "heading": "Sources and related docs",
          "items": [
            {
              "label": "SpringServe Tag Tester",
              "href": "http://tools.springserve.com/tagtest",
              "description": "SpringServe's public tag testing tool: player view, tags tested, events, diagram, and metadata for VAST and VMAP input.",
              "source": "SpringServe"
            },
            {
              "label": "Best VAST validator tools in 2026",
              "href": "/blog/best-vast-validator-tools-2026/",
              "description": "The full comparison roundup: IAB Tech Lab, Google IMA, AdMeIn, SpringServe, AdServe, and vastlint.",
              "source": "Blog"
            },
            {
              "label": "Rule derivation methodology",
              "href": "/docs/methodology/",
              "description": "How vastlint derives rules from IAB XSD schemas, normative prose, and related standards.",
              "source": "Docs"
            },
            {
              "label": "Validate VAST XML online",
              "href": "/docs/validate-vast-xml/",
              "description": "How to choose between validating resolved XML and testing a live tag URL.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Run the standards layer first",
          "paragraph": "Validate the resolved XML against public, spec-derived rules before any player-style pass. Every issue comes back with a rule ID, severity, and the exact fix.",
          "href": "/validate/",
          "label": "Open the VAST tag validator"
        }
      ]
    },
    {
      "slug": "vastlint-vs-adserve-vast-inspector",
      "title": "vastlint vs AdServe VAST Inspector",
      "description": "AdServe's VAST Inspector is a capable player-style tester that plays the ad and pings tracking URLs, with advertised support through VAST 4.2. vastlint covers VAST 2.0–4.3 with public rule docs, a published methodology, hop-by-hop wrapper inspection, and an engine you can embed in CI. Here is how the two fit together.",
      "publishedAt": "2026-06-11",
      "updatedAt": "2026-06-11",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Tool comparison",
      "tags": [
        "AdServe",
        "VAST inspector",
        "VAST validator",
        "Ad ops"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "AdServe's VAST Inspector at adserve.tv accepts a VAST tag URL or raw XML, including VPAID creatives, and runs it through a player that attempts to interpret the response, play the ad, and ping the tracking URLs. Its public page advertises support for linear, wrapper, ad pod, redirects, event tracking, click tracking, and measurement reports across VAST 2.0 through 4.2. As a playback-style check, that is a solid surface.",
            "vastlint approaches the same tag from the standards side. It validates VAST 2.0 through 4.3 against public, spec-derived rules, documents every rule with a copyable fix, separates validation, live-URL testing, and wrapper inspection into three tools, and ships the engine as a CLI, library, and MCP server for CI and server-side use.",
            "The name overlap is worth untangling: AdServe's “inspector” is a playback inspector: it watches the ad run. vastlint's inspector is a wrapper-chain inspector: it unwraps each redirect hop and validates every response on the way to the InLine. Those are different jobs, and most broken tags need the second one first."
          ]
        },
        {
          "type": "list",
          "heading": "The fastest way to choose between them",
          "items": [
            "Use AdServe when you want to watch the ad actually play and see tracking pings fire in a browser session.",
            "Use AdServe when you are still maintaining legacy VPAID creatives and want a public player that will attempt to run them.",
            "Use vastlint when you need spec compliance with a rule ID, severity, and spec reference for every issue, including VAST 4.3, which AdServe's public page does not advertise.",
            "Use vastlint when the failure is inside a wrapper chain and you need to see exactly which hop breaks.",
            "Use vastlint when the check has to run outside a browser: CLI, CI, server-side pipelines, or AI agents via MCP.",
            "Use both on high-value campaigns: standards validation first, playback confirmation second."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What AdServe's inspector shows on its public surface",
          "paragraphs": [
            "The public page advertises a genuinely broad playback surface: linear and wrapper handling, ad pods, redirects, event tracking, click tracking, and measurement reports, with VAST support listed for 2.0, 3.0, and 4.0 through 4.2. The player-based approach means you see real interpretation behavior: the tool tries to play the ad and fire the trackers rather than just parsing the XML.",
            "What the public page does not surface is the layer underneath. Advertised version support stops at 4.2 rather than 4.3, there is no public rule-by-rule catalog or derivation methodology, no distinct wrapper-inspection workflow separate from playback, and no public path to embed the checks in CI or a server-side pipeline. As with most player-style testers, the public surface is the playback experience itself."
          ]
        },
        {
          "type": "list",
          "heading": "Where vastlint closes the gap",
          "items": [
            "VAST 4.3 coverage: 4.3 has no published IAB XSD, so vastlint derives its 4.3 rules from the normative spec prose and documents how.",
            "Public rule docs: every error links to a rule page with the reason it fires and a copyable XML fix.",
            "A dedicated wrapper-chain inspector: each redirect hop is fetched, parsed, and validated individually, so you see where the chain breaks instead of a single end-to-end outcome.",
            "VPAID handling that matches where the industry is: vastlint detects VPAID, flags it as deprecated, and routes you to the SIMID/OMID migration path rather than just playing the legacy creative.",
            "An embeddable engine: the same Rust core runs in the web tools, the CLI, Go and npm packages, and the MCP server, so validation is repeatable in CI and ad-serving pipelines."
          ]
        },
        {
          "type": "quote",
          "quote": "Playing the ad proves it played in that player today. Validating the tag proves what every spec-compliant player can expect from it.",
          "attribution": "vastlint field note"
        },
        {
          "type": "code",
          "heading": "Recommended workflow when AdServe is part of QA",
          "language": "text",
          "code": "# 1. Validate the resolved VAST XML in the vastlint validator\n# 2. If the tag is a live URL, unwrap each redirect hop in the vastlint inspector\n# 3. Run the vastlint tester for creative preview and tracking visibility\n# 4. Fix structural issues first; each one links to the exact XML fix\n# 5. Finish with an AdServe playback pass if you want to watch the ad run and ping trackers"
        },
        {
          "type": "list",
          "heading": "When vastlint is the better first choice",
          "items": [
            "You traffic VAST 4.3 or need one consistent rule set across all six VAST versions.",
            "A player rejected the tag and you need the exact element and spec reference, not a playback symptom.",
            "The tag redirects through multiple wrappers and you need hop-by-hop visibility.",
            "You are migrating VPAID creatives and need deprecation detection plus a documented migration path.",
            "Validation must be automated: pre-traffic checks in CI, inline checks in an SSP or ad server, or agent-driven checks over MCP."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "When AdServe still earns a spot in the workflow",
          "paragraphs": [
            "A playback pass that pings real tracking URLs is a useful final confirmation, and AdServe's public surface covers a wide range of playback scenarios including ad pods and legacy VPAID. If your team wants to watch the creative run before sign-off, it is a reasonable place to do it.",
            "Just keep the layers in order. A tag that plays in one public tester can still fail in stricter players, CTV SDKs, or SSAI environments because of structural issues a playback session never exposes. Validate against the published standards first, then confirm playback."
          ]
        },
        {
          "type": "resources",
          "heading": "Sources and related docs",
          "items": [
            {
              "label": "AdServe VAST Inspector",
              "href": "https://adserve.tv/vast-inspector/",
              "description": "AdServe's public inspector page, including its advertised VAST 2.0–4.2 support and playback, tracking, and reporting claims.",
              "source": "AdServe"
            },
            {
              "label": "Best VAST validator tools in 2026",
              "href": "/blog/best-vast-validator-tools-2026/",
              "description": "The full comparison roundup: IAB Tech Lab, Google IMA, AdMeIn, SpringServe, AdServe, and vastlint.",
              "source": "Blog"
            },
            {
              "label": "Inspect a VAST wrapper chain",
              "href": "/inspect/",
              "description": "vastlint's hop-by-hop wrapper-chain inspector: every redirect fetched, parsed, and validated.",
              "source": "Tool"
            },
            {
              "label": "VPAID is deprecated: migration guide",
              "href": "/docs/vpaid/",
              "description": "What replaced VPAID, how to detect it in a tag, and how to migrate to SIMID and OMID.",
              "source": "Docs"
            },
            {
              "label": "Rule derivation methodology",
              "href": "/docs/methodology/",
              "description": "How vastlint derives rules from IAB XSD schemas, normative prose, and related standards.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Validate before you press play",
          "paragraph": "Run the tag through spec-derived validation first. Every issue comes back with a rule ID, severity, and the exact fix. Then confirm playback wherever your team prefers.",
          "href": "/validate/",
          "label": "Open the VAST tag validator"
        }
      ]
    },
    {
      "slug": "agentic-buying-needs-a-harness",
      "title": "Agentic Buying Doesn't Fail at Intelligence. It Fails Without a Harness",
      "description": "Two-thirds of ad buyers are ramping up agentic AI while verification stays manual. The lesson from coding agents and from the IAB's own agentic roadmap is the same: autonomy only works inside a deterministic harness, and validators like vastlint are that layer for video delivery.",
      "publishedAt": "2026-06-11",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Agentic advertising",
      "tags": [
        "Agentic",
        "Standards",
        "Automation",
        "MCP"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Buying is going agentic faster than verification is",
          "paragraphs": [
            "The IAB's 2026 Outlook Study puts numbers on what every trading desk already feels: 96% of buyers are aware of agentic AI for ad buying, and 66% are increasing their focus on it for buying and campaign execution this year. At the same time, 40% of those buyers name understanding agentic AI as an investment challenge.",
            "Video is moving even faster. In the IAB's 2026 Digital Video Ad Spend & Strategy Report, two in three digital video buyers are already live (21%), testing (20%), or planning to use (25%) agentic AI for video campaigns, with another 28% actively investigating.",
            "So execution is being automated at speed. What is not being automated at the same speed is verification: the step that decides whether what the agent produced will actually deliver, play, and track. That gap is where agentic buying breaks."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What coding agents already proved about autonomy",
          "paragraphs": [
            "Software engineering went through this exact transition first, and the result was unambiguous: coding agents did not become useful because models got smarter in isolation. They became useful because they run inside a harness: a compiler, a type checker, a linter, a test suite, CI. Every action the agent takes gets deterministic, machine-readable feedback, and the agent iterates against that feedback until the work passes.",
            "Take the harness away and an LLM writing code is just producing plausible-looking text. Nobody ships that.",
            "A media-buying agent assembling a deal and trafficking a video tag is in the same position, except worse: there is no compiler for a VAST tag. XML that is well-formed can still reference a deprecated VPAID creative, omit a required Duration, carry an insecure tracker, or bury the media file four wrappers deep. The agent needs the same loop a coding agent gets (act, validate, repair, re-validate), and that loop requires a deterministic validator it can call as a tool."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The standards bodies are building the protocols. Protocols are not verification",
          "paragraphs": [
            "The industry's standards work confirms the direction. In January 2026, IAB Tech Lab released AAMP (Agentic Advertising Management Protocols) v1.0, an umbrella framework for agent-driven advertising that deliberately builds on existing standards: OpenRTB, AdCOM, OpenDirect, and VAST, wired together with modern agent protocols like the Model Context Protocol and Agent2Agent. Tech Lab's own framing is blunt: without speed, structure, security, and trust, there's no agentic advertising future worth having.",
            "A few months earlier, in October 2025, a consortium including Yahoo, PubMatic, Optable, Scope3, Swivel, and Triton Digital launched the Ad Context Protocol (AdCP), an open standard built on MCP that lets buyer and seller agents exchange context and orchestrate buys across platforms.",
            "Both efforts solve the communication problem: how agents discover inventory, negotiate, and transact. Neither one verifies that the payload changing hands is correct. When a human trafficker is removed from the loop and both sides of a transaction are machines, nobody is left to eyeball the tag. Protocol adoption makes payload validation more urgent, not less. It is the missing rung between agents that can transact and agents that can be trusted to."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Programmatic already showed what automation without verification costs",
          "paragraphs": [
            "We do not have to speculate about what happens when execution is automated and verification is not, because programmatic already ran the experiment. The ANA's Programmatic Transparency Benchmark found $26.8 billion in wasted global programmatic spend in its Q2 2025 report, up 34% from the roughly $20 billion its landmark 2023 study identified. The same research found the average campaign running across 44,000 websites when a few hundred would reach most of the audience.",
            "Programmatic automated the buying loop and left quality checking to quarterly reports and post-campaign audits. Agentic buying shortens the decision loop from hours to seconds. Run that loop without inline verification and the waste does not shrink. It compounds at machine speed."
          ]
        },
        {
          "type": "list",
          "heading": "What the harness layer has to provide",
          "items": [
            "Deterministic results: the same input produces the same findings every run, with stable rule IDs an agent can branch on.",
            "Machine-readable output: structured JSON and exit codes that can gate a pipeline, not prose a human has to interpret.",
            "Spec grounding: every rule traceable to a section of the IAB VAST, OMID, or SIMID specs, so a failure is a standards violation, not a vendor opinion.",
            "Availability everywhere agents run: as a CLI for pipelines, as native libraries inside ad servers, as a CI action, and as an MCP tool agents can call directly.",
            "Wrapper-chain resolution, so what gets validated is what the player will actually receive, not just the first hop.",
            "Bounded auto-repair: deterministic, low-risk fixes only, always followed by re-validation.",
            "One shared gate for humans and agents, so QA standards do not drift between the two."
          ]
        },
        {
          "type": "code",
          "heading": "The loop, concretely",
          "language": "bash",
          "code": "# deterministic gate inside an agentic workflow\nvastlint check tag.xml --format json --fail-on-warning\n\n# the agent gets structured findings, not prose:\n# {\"id\":\"VAST-2.0-inline-adsystem\",\"severity\":\"error\",\n#  \"path\":\"/VAST/Ad[0]/InLine\",\"spec_ref\":\"IAB VAST 2.0 §2.2.1\"}\n\n# bounded deterministic repair, then re-validate\nvastlint fix tag.xml --dry-run\nvastlint check tag.xml --format json"
        },
        {
          "type": "paragraphs",
          "heading": "Where vastlint sits in that stack",
          "paragraphs": [
            "Video is where the payload is most fragile and most expensive. The IAB projects U.S. digital video ad spend to surpass $80 billion in 2026, with CTV alone at $29.3 billion, and VAST is the delivery contract underneath nearly all of it.",
            "vastlint is the lint layer for that contract: 236 deterministic rules mapped to the IAB VAST, OMID, and SIMID specs, with stable rule IDs, NDJSON output, wrapper unwrapping, and a deliberately conservative fix mode. It runs as a CLI, as Go and Rust libraries, as a GitHub Action, and as a hosted MCP server: the same gate whether the caller is an ops analyst, a CI job, or a buying agent.",
            "To be clear about scope: payload validation is one slice of the harness, not the whole thing. Agentic buying will also need gates for brand safety, supply path, and pacing. But the creative delivery payload is the most compiler-like piece of the problem: fully specified by IAB standards, deterministically checkable. It is the slice you can put in front of an agent today."
          ]
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "Agentic docs",
              "href": "/docs/agentic/",
              "description": "Where agentic workflows fit into the vastlint operating model.",
              "source": "Docs"
            },
            {
              "label": "MCP docs",
              "href": "/docs/mcp/",
              "description": "The hosted MCP surface: validation, rule catalog, wrapper inspection, and safe auto-fix as agent tool calls.",
              "source": "Docs"
            },
            {
              "label": "AdCP docs",
              "href": "/docs/adcp/",
              "description": "How validation integrates with Ad Context Protocol workflows.",
              "source": "Docs"
            },
            {
              "label": "Validate VAST XML",
              "href": "/docs/validate-vast-xml/",
              "description": "Core validator behavior and the rule catalog the gate enforces.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "Agentic Advertising and AI Initiatives (AAMP)",
              "href": "https://iabtechlab.com/standards/agentic-advertising-and-ai/",
              "description": "IAB Tech Lab's AAMP v1.0 framework: agentic protocols built on OpenRTB, AdCOM, OpenDirect, VAST, MCP, and A2A.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "2026 Outlook Study",
              "href": "https://www.iab.com/insights/2026-outlook/",
              "description": "Buyer adoption data: 96% awareness of agentic AI for buying, 66% increasing focus, 40% citing it as an investment challenge.",
              "source": "IAB"
            },
            {
              "label": "2026 Digital Video Ad Spend & Strategy Report",
              "href": "https://www.iab.com/insights/video-ad-spend-report-2026/",
              "description": "U.S. digital video spend surpassing $80B, CTV at $29.3B, and agentic AI adoption among video buyers.",
              "source": "IAB"
            },
            {
              "label": "Q2 2025 Programmatic Transparency Benchmark",
              "href": "https://www.ana.net/content/show/id/pr-2025-08-programmatictrans",
              "description": "$26.8B in annual wasted programmatic spend, up 34% from the 2023 study.",
              "source": "ANA"
            },
            {
              "label": "Ad Context Protocol: Introduction",
              "href": "https://docs.adcontextprotocol.org/docs/intro",
              "description": "The open, MCP-based standard for agent-to-agent media transactions launched in October 2025.",
              "source": "AdCP"
            },
            {
              "label": "Digital Video Ad Serving Template (VAST)",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The canonical delivery contract every payload gate ultimately checks against.",
              "source": "IAB Tech Lab"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Put a gate in front of your agents",
          "paragraph": "The hosted MCP endpoint exposes validation, wrapper inspection, rule listing, and safe auto-fix: the same deterministic harness in agent workflows, CI, and human QA.",
          "href": "/docs/mcp/",
          "label": "View MCP docs"
        }
      ]
    },
    {
      "slug": "how-to-validate-omid-in-vast-tags",
      "title": "How to Validate OMID in VAST 4.1-4.3 Tags with VASTlint",
      "description": "OMID validation starts in the VAST XML long before the player runs OM SDK. Learn which VAST versions matter, what vastlint checks today, how the release channels differ, and how to validate OMID blocks from the web UI, CLI, npm package, or MCP.",
      "publishedAt": "2026-06-09",
      "updatedAt": "2026-06-09",
      "author": "Alex Sekowski",
      "readingTime": "10 min read",
      "heroKicker": "OMID validation",
      "tags": [
        "OMID",
        "Google IMA",
        "VAST 4.1",
        "Ad verification"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "OMID validation in VAST starts with the XML. If the Verification vendor is malformed, the JavaScriptResource is insecure, the same vendor is duplicated, or verification tracking is wired incorrectly, the measurement stack starts broken before the player has a chance to execute OM SDK.",
            "vastlint can catch the VAST-side OMID mistakes early in the web validator, CLI, npm package, Rust core, and MCP workflow. What it cannot do is prove runtime viewability or compliance by itself. IAB Tech Lab's OM SDK and Google's IMA docs are clear that actual measurement still depends on the player integration, supported access modes, and the measurement provider scripts that run at playback time."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What OMID is doing in the tag",
          "paragraphs": [
            "IAB Tech Lab positions OM SDK as the standard measurement layer for digital video, CTV, mobile, and web. The VAST side of that integration is the AdVerifications block: the tag tells the player which verification vendor resources exist, and the runtime exposes measurement signals through the OMID API once playback actually begins.",
            "Google IMA's OM SDK guide is a useful operational reference here. It says the HTML5 SDK automatically parses AdVerifications in VAST tags and sends viewability data to the specified measurement vendors. It also calls out the version split directly: VAST 4.1 and higher should use AdVerifications, while earlier versions can carry the same data inside Extension type=\"AdVerifications\" for compatibility."
          ]
        },
        {
          "type": "list",
          "heading": "Which VAST versions matter for OMID",
          "items": [
            "VAST 4.1 is where IAB Tech Lab explicitly introduces improved ad verification and ad creative measurement. In normal modern tags, that means AdVerifications and Verification blocks.",
            "VAST 4.2 keeps the same OMID model while adding SIMID on the interactivity side, which is why teams often think about SIMID and OMID together when replacing VPAID-era payloads.",
            "VAST 4.3 adds browserOptional on JavaScriptResource, so a validator that understands 4.3 should also know when that attribute is missing.",
            "If you still receive older VAST documents, some players and SDKs support OM verification via Extension type=\"AdVerifications\" instead of top-level AdVerifications. That compatibility path matters in real traffic, even if your trafficking policy prefers 4.1+."
          ]
        },
        {
          "type": "list",
          "heading": "What OMID XML validation can catch before playback",
          "items": [
            "Missing Verification vendor attributes or missing verification resources altogether.",
            "JavaScriptResource or ExecutableResource blocks that omit apiFramework or use a non-OMID value when the resource is clearly meant for OM measurement.",
            "HTTP verification resources that should be HTTPS in secure runtimes.",
            "Duplicate vendor identifiers inside the same AdVerifications block.",
            "Vendor identifiers that are too loose to be useful operationally, such as bare names instead of domain-qualified identifiers.",
            "Missing or empty VerificationParameters for OMID payloads that need runtime configuration.",
            "Verification tracking wired to the wrong event model instead of the verificationNotExecuted path used by VAST verification blocks.",
            "verificationNotExecuted tracking URLs that omit the [REASON] macro, which makes later debugging much weaker than it needs to be."
          ]
        },
        {
          "type": "code",
          "heading": "A minimal OMID block that should pass in VAST 4.3",
          "language": "xml",
          "code": "<AdVerifications>\n  <Verification vendor=\"measurement.example.com-omid\">\n    <JavaScriptResource apiFramework=\"omid\" browserOptional=\"true\"><![CDATA[https://cdn.measurement.example.com/omsdk/omid.js]]></JavaScriptResource>\n    <VerificationParameters><![CDATA[{\"campaign\":\"spring-launch\"}]]></VerificationParameters>\n    <TrackingEvents>\n      <Tracking event=\"verificationNotExecuted\"><![CDATA[https://tracker.example.com/omid?reason=[REASON]]]></Tracking>\n    </TrackingEvents>\n  </Verification>\n</AdVerifications>"
        },
        {
          "type": "paragraphs",
          "heading": "Why that example is version-specific",
          "paragraphs": [
            "The core shape there is VAST 4.1+: Verification vendor, verification resource, optional VerificationParameters, and verification tracking. The browserOptional attribute is the part that matters specifically to VAST 4.3 JavaScriptResource handling.",
            "If your player stack is older, the compatibility question is not just whether the XML is technically well-formed. It is whether the runtime expects AdVerifications directly or an Extension wrapper, and whether the player actually has OM SDK support on that platform."
          ]
        },
        {
          "type": "code",
          "heading": "A block that looks plausible but should be flagged",
          "language": "xml",
          "code": "<AdVerifications>\n  <Verification vendor=\"moat\">\n    <JavaScriptResource apiFramework=\"OMSDK\"><![CDATA[http://measurement.example.com/omid.js]]></JavaScriptResource>\n    <TrackingEvents>\n      <Tracking event=\"start\"><![CDATA[https://tracker.example.com/omid?reason=[REASON]]]></Tracking>\n      <Tracking event=\"verificationNotExecuted\"><![CDATA[https://tracker.example.com/omid]]></Tracking>\n    </TrackingEvents>\n  </Verification>\n  <Verification vendor=\"moat\">\n    <JavaScriptResource apiFramework=\"omid\"><![CDATA[https://measurement.example.com/secondary.js]]></JavaScriptResource>\n  </Verification>\n</AdVerifications>"
        },
        {
          "type": "list",
          "heading": "What the latest OMID rule set should complain about",
          "items": [
            "VAST-4.1-verification-vendor-format because a bare vendor name like moat is weak compared with a domain-qualified identifier such as company.com-omid.",
            "VAST-4.1-verification-duplicate-vendor because the same vendor appears twice in one AdVerifications block.",
            "VAST-4.1-js-resource-apiframework-value because an OM verification resource should declare apiFramework=\"omid\".",
            "VAST-4.1-js-resource-https because the first JavaScriptResource points at HTTP instead of HTTPS.",
            "VAST-4.1-verification-parameters because neither Verification includes non-empty VerificationParameters.",
            "A verification tracking event error because Tracking under Verification is not the same event set as Linear tracking; verificationNotExecuted is the allowed path here.",
            "VAST-4.1-verification-tracking-reason because the verificationNotExecuted tracker omits the [REASON] macro."
          ]
        },
        {
          "type": "list",
          "heading": "Which vastlint channel to use",
          "items": [
            "The web validator at vastlint.org/validate is the fastest manual check when ad ops or QA needs to paste a live tag and spot obvious OMID mistakes without installing anything.",
            "The current published npm package line is 0.4.23. It already catches the core AdVerifications shape: required vendor and resource attributes, apiFramework requirements, and the VAST 4.3 browserOptional warning.",
            "The deepest OMID coverage in the June 9 release line is in vastlint-core and the CLI at 0.4.24. That adds vendor format, duplicate-vendor detection, VerificationParameters guidance, HTTPS resource semantics, pre-4.1 Extension compatibility checks, and verificationNotExecuted tracking validation.",
            "If you are gating launches in CI, use the CLI or core first. If you are spot-checking tags with humans, the website and npm package are the easiest entry points. If you are wiring validation into agentic QA, the MCP surface is the right shape."
          ]
        },
        {
          "type": "code",
          "heading": "Use the CLI when OMID should block launch",
          "language": "sh",
          "code": "vastlint check omid-example.xml --format json\n\n# Gate on warnings too when OMID hygiene matters\nvastlint check omid-example.xml --fail-on-warning"
        },
        {
          "type": "code",
          "heading": "Use the npm package inside a web or Node pipeline",
          "language": "ts",
          "code": "import { validate } from 'vastlint';\n\nconst result = validate(xmlString);\n\nconst omidIssues = result.issues.filter((issue) =>\n  issue.id.includes('verification') ||\n  issue.id.includes('js-resource') ||\n  issue.id.includes('exec-resource') ||\n  issue.id.includes('browser-optional')\n);\n\nfor (const issue of omidIssues) {\n  console.log(issue.id, issue.severity, issue.message);\n}"
        },
        {
          "type": "code",
          "heading": "Use the hosted MCP tool in agent workflows",
          "language": "json",
          "code": "{\n  \"tool\": \"validate_vast\",\n  \"input\": {\n    \"xml\": \"<VAST version='4.3'><Ad id='omid-demo'><InLine><AdSystem>example-ad-server</AdSystem><AdTitle>OMID demo</AdTitle><AdServingId>omid-demo-serving-id</AdServingId><Impression><![CDATA[https://tracker.example.com/impression]]></Impression><Creatives><Creative><UniversalAdId idRegistry='unknown'>omid-demo</UniversalAdId><Linear><Duration>00:00:15</Duration><TrackingEvents><Tracking event='start'><![CDATA[https://tracker.example.com/start]]></Tracking><Tracking event='firstQuartile'><![CDATA[https://tracker.example.com/firstQuartile]]></Tracking><Tracking event='midpoint'><![CDATA[https://tracker.example.com/midpoint]]></Tracking><Tracking event='thirdQuartile'><![CDATA[https://tracker.example.com/thirdQuartile]]></Tracking><Tracking event='complete'><![CDATA[https://tracker.example.com/complete]]></Tracking></TrackingEvents><MediaFiles><MediaFile delivery='progressive' type='video/mp4' width='1280' height='720'><![CDATA[https://cdn.example.com/video.mp4]]></MediaFile></MediaFiles></Linear></Creative></Creatives><AdVerifications><Verification vendor='measurement.example.com-omid'><JavaScriptResource apiFramework='omid' browserOptional='true'><![CDATA[https://cdn.measurement.example.com/omid.js]]></JavaScriptResource><VerificationParameters><![CDATA[campaign=spring-launch]]></VerificationParameters></Verification></AdVerifications></InLine></Ad></VAST>\"\n  }\n}"
        },
        {
          "type": "paragraphs",
          "heading": "What OMID XML validation cannot prove",
          "paragraphs": [
            "This boundary matters. A valid AdVerifications block is necessary, but it is not the same thing as successful OM SDK measurement in the player. Google's IMA guide says the SDK parses AdVerifications and can apply access mode rules per vendor, which means runtime behavior still depends on the player and SDK configuration rather than XML alone.",
            "That is why the right operational split is: validate the XML before launch, then verify runtime measurement separately in the player or SDK environment you actually ship. vastlint handles the first job. OM SDK compliance and viewability outcomes still require the second."
          ]
        },
        {
          "type": "quote",
          "quote": "Validate the XML before you ask OM SDK to explain a runtime problem.",
          "attribution": "vastlint field note"
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "VAST validator",
              "href": "/validate/",
              "description": "Paste a full VAST tag into the live validator and inspect the verification issues before launch.",
              "source": "Tool"
            },
            {
              "label": "VAST 4.0 to 4.1 migration guide",
              "href": "/docs/vast-4-to-4-1/",
              "description": "Where AdVerifications, OMID resources, and the VAST 4.1 verification model actually enter the standard.",
              "source": "Docs"
            },
            {
              "label": "VAST 4.2 to 4.3 guide",
              "href": "/docs/vast-4-2-to-4-3/",
              "description": "Useful when you need the browserOptional context for OMID JavaScriptResource handling in VAST 4.3.",
              "source": "Docs"
            },
            {
              "label": "VPAID is deprecated",
              "href": "/docs/vpaid/",
              "description": "Why the forward path is standard playback for media, SIMID for interactivity, and OMID for measurement.",
              "source": "Docs"
            },
            {
              "label": "MCP docs",
              "href": "/docs/mcp/",
              "description": "How to expose VAST validation as a tool call in agentic ad-ops workflows.",
              "source": "Docs"
            },
            {
              "label": "Rule reference",
              "href": "/docs/rules/",
              "description": "Browse the current rule catalog and search for OMID-related verification rules by ID.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "IAB Tech Lab OM SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "The official OM SDK overview, platform coverage, developer guides, and compliance resources.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST standards",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The official VAST standards hub and version history, including the 4.1 and 4.3 context for verification and measurement changes.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA: Enable Open Measurement",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/omsdk",
              "description": "Useful runtime guidance on how AdVerifications are parsed, which VAST versions use AdVerifications directly, and how OMID access modes work in the HTML5 SDK.",
              "source": "Google IMA"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Validate an OMID tag now",
          "paragraph": "Paste a VAST 4.1-4.3 tag into the web validator, or move the same XML into the CLI if OMID issues should gate launch approval in CI.",
          "href": "/validate/",
          "label": "Open the validator"
        }
      ]
    },
    {
      "slug": "using-vastlint-go-in-ad-serving-components",
      "title": "Using vastlint-go in Ad Serving Components to Validate and Unwrap Programmatic VAST",
      "description": "If your Go ad server accepts VAST from programmatic demand, do not forward it blind. Validate every hop, unwrap wrappers safely, quarantine broken trackers and unsupported creatives, and reduce the compliance blind spots that leak revenue.",
      "publishedAt": "2026-06-07",
      "updatedAt": "2026-06-07",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "Ad serving with Go",
      "tags": [
        "vastlint-go",
        "Ad server",
        "Programmatic demand",
        "Tracking pixels"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "If your serving component receives VAST from DSPs, SSPs, exchanges, or reseller wrapper chains, the safest posture is to treat every response as untrusted input. Fetch the first hop, validate it in process with vastlint-go, unwrap only when the wrapper is structurally sound, and keep validating until you reach the final inline creative or a policy limit.",
            "That pattern does two jobs at once. It catches spec and hygiene failures before the player eats the loss, and it gives your ad server one deterministic place to enforce business policy: wrapper depth, HTTPS-only delivery, tracker sanity, supported interactivity, and minimum measurement requirements for the inventory class."
          ]
        },
        {
          "type": "list",
          "heading": "What breaks first when you relay demand-side VAST blindly",
          "items": [
            "A wrapper arrives without a usable VASTAdTagURI because the upstream macro resolved to empty text, so the chain stops before the creative ever resolves.",
            "Extra wrapper hops add latency and fragility long before anyone hits a formal maximum, which turns live delivery into soft no-fill and silent underdelivery.",
            "Impression, quartile, click, error, or verification URLs still point at HTTP or stale staging hosts, so secure runtimes block them or your reporting trail becomes noise.",
            "Each wrapper adds more trackers, and nobody can tell the difference between legitimate accumulation and accidental duplication, so billing and discrepancy reviews start from a bad inventory of beacons.",
            "The tag carries VPAID or browser-only verification assumptions into CTV, SSAI, or restricted runtimes that expect SIMID, OMID, or a safer fallback path.",
            "MediaFiles technically exist, but the MIME type, codec, bitrate, or asset profile does not line up with what the receiving runtime will actually select and render.",
            "Click and viewability expectations are copied from desktop web into runtimes where event coverage is partial, full-screen behavior differs, or measurement requires extra configuration."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Trackers are necessary, but they do not prove the ad was good",
          "paragraphs": [
            "A clean tracker layer matters because it is your audit trail. Broken Error URLs, duplicated quartile beacons, unresolved macros, or staging endpoints in production make later discrepancy work much harder than it needs to be.",
            "But a fired pixel is still only proof that some system made a request. Google IMA and OM documentation are explicit that viewability and verification depend on runtime conditions: a viewable and unobstructed container, supported feature coverage, valid verification resources, and the measurement stack that the player actually executes. Your serving component can keep the XML and measurement hooks clean before playback. It cannot prove viewability from XML alone."
          ]
        },
        {
          "type": "list",
          "heading": "What a Go serving component should enforce before the player sees the tag",
          "items": [
            "Validate every fetched VAST document in process with vastlint-go instead of waiting for the player to discover that the response was malformed.",
            "Own wrapper fetching in your application: set a depth cap, detect loops, normalize redirects, and stop the chain when the next hop is empty or unsafe.",
            "Apply URL policy across media, impressions, trackers, click destinations, and verification resources so HTTPS-only inventory does not depend on best-effort cleanup in the player.",
            "Keep an allowlist or denylist for MIME types, interactive frameworks, and verification models by inventory class, because web, mobile, SSAI, and CTV do not tolerate the same payloads.",
            "Record which partner or wrapper hop introduced each tracker so you can explain the final beacon stack instead of arguing about it after campaign launch.",
            "Quarantine or downgrade bad demand inside the same request path, then return a structured reason to the upstream partner or choose a fallback creative before revenue is lost."
          ]
        },
        {
          "type": "code",
          "heading": "A simple unwrap-and-validate loop in Go",
          "language": "go",
          "code": "package demand\n\nimport (\n  \"context\"\n  \"encoding/xml\"\n  \"errors\"\n  \"fmt\"\n  \"net/http\"\n  \"strings\"\n\n  vastlint \"github.com/aleksUIX/vastlint-go\"\n)\n\ntype vastDoc struct {\n  Ads []struct {\n    Wrapper *struct {\n      VASTAdTagURI string `xml:\"VASTAdTagURI\"`\n    } `xml:\"Wrapper\"`\n  } `xml:\"Ad\"`\n}\n\nfunc validateChain(ctx context.Context, client *http.Client, startURL string) error {\n  seen := map[string]struct{}{}\n  nextURL := startURL\n\n  for depth := 0; depth < 5; depth++ {\n    if _, ok := seen[nextURL]; ok {\n      return fmt.Errorf(\"wrapper loop: %s\", nextURL)\n    }\n    seen[nextURL] = struct{}{}\n\n    xmlBytes, err := fetchVAST(ctx, client, nextURL)\n    if err != nil {\n      return err\n    }\n\n    result, err := vastlint.ValidateWithOptions(xmlBytes, vastlint.Options{\n      MaxWrapperDepth: 5,\n      RuleOverrides: map[string]string{\n        \"VAST-2.0-mediafile-https\": \"error\",\n      },\n    })\n    if err != nil {\n      return err\n    }\n    if !result.Valid {\n      return fmt.Errorf(\"quarantine demand tag: %v\", result.Issues)\n    }\n\n    var doc vastDoc\n    if err := xml.Unmarshal(xmlBytes, &doc); err != nil {\n      return err\n    }\n\n    nextURL = \"\"\n    for _, ad := range doc.Ads {\n      if ad.Wrapper != nil && strings.TrimSpace(ad.Wrapper.VASTAdTagURI) != \"\" {\n        nextURL = strings.TrimSpace(ad.Wrapper.VASTAdTagURI)\n        break\n      }\n    }\n\n    if nextURL == \"\" {\n      return nil // final inline VAST is clean enough to hand to the player\n    }\n  }\n\n  return errors.New(\"wrapper depth exceeded\")\n}"
        },
        {
          "type": "paragraphs",
          "heading": "Why this protects revenue instead of just improving hygiene",
          "paragraphs": [
            "The operational win is timing. If you reject a bad demand response after the player times out, the revenue opportunity is already gone. If you reject it in your Go serving path, you still have a chance to serve a fallback, log the exact failing hop, and preserve evidence for the partner that sent the broken tag.",
            "That same path is where you can keep score. Stable rule IDs from vastlint-go let you trend partner quality, distinguish hard blockers from advisory issues, and stop treating every delivery dispute like a one-off mystery."
          ]
        },
        {
          "type": "list",
          "heading": "Quarantine signals worth treating as hard fail",
          "items": [
            "Missing or empty VASTAdTagURI on a wrapper hop.",
            "Wrapper loop, redirect cycle, or depth cap reached before the inline creative appears.",
            "Malformed XML, no usable InLine or Wrapper payload, or a version mismatch that breaks your target runtime.",
            "HTTP-only media or other secure-delivery violations on inventory where the player, browser, or CTV environment expects HTTPS.",
            "Unsupported interactive payloads for the receiving platform, especially when legacy VPAID assumptions are being pushed into environments that need SIMID or a non-interactive fallback.",
            "Broken, contradictory, or obviously duplicated measurement URLs when billing or reconciliation depends on those events.",
            "Verification or measurement payloads that look present in XML but cannot run in the actual destination environment you are serving."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Invisible ads are a policy problem, not just an XML problem",
          "paragraphs": [
            "If by invisible ads you mean stacked, hidden, or otherwise non-viewable playback, no validator can prove or disprove that from XML alone. That requires runtime measurement such as OM SDK, Active View, or other environment-specific verification signals, and those only work when the player and container are configured to expose real visibility data.",
            "What your serving component can do is stop forwarding tags that arrive with weak evidence: dead verification resources, no workable impression or error trail, mismatched media for the destination runtime, or wrapper chains so opaque that nobody can explain who injected which beacon. That does not replace viewability or anti-fraud controls, but it does remove a large class of sloppy demand that makes invisible-delivery disputes harder to unwind."
          ]
        },
        {
          "type": "quote",
          "quote": "Do not ask the player to be your first validator.",
          "attribution": "vastlint field note"
        },
        {
          "type": "resources",
          "heading": "Related guides on vastlint",
          "items": [
            {
              "label": "Best VAST XML Validator for Go",
              "href": "/docs/best-vast-validator-go/",
              "description": "Where to start if you want the Go binding itself, install instructions, and the minimal API surface.",
              "source": "Docs"
            },
            {
              "label": "Embedding vastlint in an SSP, DSP, or ad server",
              "href": "/docs/ad-server-integration/",
              "description": "Broader integration guidance for in-process validation, rule policy, latency, and ad-serving architecture.",
              "source": "Docs"
            },
            {
              "label": "How to Validate VAST Trackers Before Launch",
              "href": "/blog/how-to-validate-vast-trackers-before-launch/",
              "description": "A focused pass on impression, quartile, click, and error tracker hygiene across wrappers and live tag URLs.",
              "source": "Blog"
            },
            {
              "label": "Missing VASTAdTagURI: Why Wrapper Tags Fail",
              "href": "/docs/missing-vastadtaguri/",
              "description": "The fastest route to diagnosing wrapper hops that have no usable next target.",
              "source": "Docs"
            },
            {
              "label": "Common VAST errors",
              "href": "/docs/common-vast-errors/",
              "description": "A practical reference for malformed URLs, deprecated payloads, missing required elements, and other common delivery failures.",
              "source": "Docs"
            },
            {
              "label": "VAST Wrapper Chains: How They Work, Limits & Debugging",
              "href": "/guides/vast-wrapper-chains/",
              "description": "Why wrapper chains lose money before they hit hard limits, and how to inspect each hop cleanly.",
              "source": "Guide"
            },
            {
              "label": "Tracking Pixels Won't Save You From CTV Fraud",
              "href": "/blog/tracking-pixels-wont-save-you-from-ctv-fraud/",
              "description": "Where tracker validation stops and runtime trust, viewability, and anti-fraud controls have to take over.",
              "source": "Blog"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "IAB Tech Lab VAST standards hub",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "Current VAST version history, supporting resources, and the official standards landing page.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/simid/",
              "description": "Background on SIMID as the interactive standard that replaces VPAID for safer cross-platform use cases.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "The VAST CTV Addendum 2024 is Ready for Implementation",
              "href": "https://iabtechlab.com/vast-ctv-addendum-2024-ready-for-implementation/",
              "description": "Why ACIF, OM support, icons, and higher-resolution creative matter across modern TV-viewing environments.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA SDK support and compatibility",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/compatibility",
              "description": "Supported formats, partial event coverage, platform support, and feature differences that make player-specific QA necessary.",
              "source": "Google IMA"
            },
            {
              "label": "Google IMA SIMID support",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/simid-support",
              "description": "Practical details on which SIMID messages are supported and where interactivity still has runtime boundaries.",
              "source": "Google IMA"
            },
            {
              "label": "Google IMA Open Measurement",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/omsdk",
              "description": "How OM SDK parses AdVerifications, what access modes exist, and why measurement is a runtime concern rather than an XML-only check.",
              "source": "Google IMA"
            },
            {
              "label": "Google IMA Active View guide",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/viewability",
              "description": "Explains how viewability depends on a viewable and unobstructed ad container and how to verify measurement signals in the network layer.",
              "source": "Google IMA"
            },
            {
              "label": "Google IMA bitrate and media format guide",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/bitrates-formats",
              "description": "Why multiple media files, bitrate ceilings, and MIME preferences matter when the XML is valid but the chosen asset still fails in runtime.",
              "source": "Google IMA"
            },
            {
              "label": "Google IMA CORS for VAST servers",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/cors",
              "description": "A reminder that cross-origin delivery policy can break web VAST fetches even when the XML itself is fine.",
              "source": "Google IMA"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Need the production integration pattern?",
          "paragraph": "Use vastlint-go inside your serving path to validate each fetched VAST hop, then use the tester or inspector when you need to debug the live demand URL outside your application.",
          "href": "/docs/ad-server-integration/",
          "label": "Read the ad server integration guide"
        }
      ]
    },
    {
      "slug": "updated-vast-validator-for-the-iab-standard",
      "title": "Why We Built an Updated VAST Validator for the IAB Standard",
      "description": "VASTlint is an independent, next-generation validator and tester for teams that need broader VAST coverage, wrapper inspection, and automation while still respecting the role of the official IAB Tech Lab tools.",
      "publishedAt": "2026-06-02",
      "updatedAt": "2026-06-02",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Validator strategy",
      "tags": [
        "IAB Tech Lab",
        "VAST validator",
        "VAST tester",
        "Ad ops"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "We built vastlint because the market needs an updated VAST validator and tester for the IAB standard: one that covers more of the modern workflow than the current public baseline, explains what failed, and can run inside browsers, CI, servers, and agent pipelines.",
            "This is not an official IAB Tech Lab product, not a rebrand of the IAB VAST Tag Validator, and not a claim of affiliation. It is an independent validator built against the published IAB Tech Lab VAST specifications, schemas, and related public materials."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What we mean by next-generation",
          "paragraphs": [
            "For us, next-generation does not mean replacing the standards owner. It means extending the public validation workflow so a team can move from live tag URL, to wrapper-chain inspection, to resolved XML validation, to fix guidance, to automation without switching mental models every step of the way.",
            "The official IAB Tech Lab validator and tester still matter. They are the standards-owner baseline and an important point of reference. But many production teams now need a wider operational surface: newer-version handling, explicit wrapper workflows, reusable APIs, and tooling that works outside a single browser session."
          ]
        },
        {
          "type": "list",
          "heading": "Where the official IAB tools still matter most",
          "items": [
            "Official status: they come from the standards owner, which matters for trust, internal sign-off, and standards-baseline checks.",
            "Reference value: they are the cleanest answer when a team asks for the standards body's own public validator or tester.",
            "Quick baseline use: they remain useful when you want an official first pass before you get into platform-specific or automation-heavy workflows.",
            "Ecosystem signaling: if you need the IAB Tech Lab standards hub, validator, tester, or adoption program, those should be linked directly rather than paraphrased through a third party."
          ]
        },
        {
          "type": "list",
          "heading": "Where vastlint goes wider on the public surface",
          "items": [
            "Version coverage: VASTlint validates VAST 2.0 through 4.3 and documents how the newer end of the standard is handled.",
            "Workflow coverage: it separates live URL testing, wrapper inspection, and resolved XML validation instead of forcing those jobs into one page.",
            "Rule transparency: it publishes rule references, methodology, and fix guidance so teams can understand why a tag failed instead of only seeing pass or fail.",
            "Automation: it runs as a web tool, CLI, npm package, Rust library, Go binding, and MCP endpoint for agent-based ad workflows.",
            "Operational debugging: it is designed for ad ops, CTV, SSAI, and platform troubleshooting, not only one-off browser checks."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The honest comparison",
          "paragraphs": [
            "The right framing is not official versus unofficial, winner takes all. The right framing is what problem are you solving right now. If you need the standards owner's public baseline, use the IAB Tech Lab tools. If you need a broader day-to-day validation and testing workflow for modern VAST operations, start with vastlint and cross-check with the official tools when that baseline matters.",
            "That is also why we avoid claiming that VASTlint is the IAB validator. It is not. A better description is that VASTlint is an updated validator and tester for the IAB VAST standard: independent, broader in workflow, and built for current implementation reality."
          ]
        },
        {
          "type": "list",
          "heading": "What we are explicitly not claiming",
          "items": [
            "We are not claiming IAB Tech Lab affiliation, endorsement, sponsorship, or trademark ownership.",
            "We are not claiming that passing VASTlint is the same thing as certification by the standards owner.",
            "We are not claiming that spec compliance alone guarantees playback in every SDK, player, DSP, SSP, or CTV environment.",
            "We are not claiming to replace platform-specific checks such as Google IMA, Roku RAF, or ad-server-specific QA."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why build it anyway",
          "paragraphs": [
            "Because modern teams need more than a point-in-time validator page. They need to inspect live tags, trace wrappers, validate the resolved XML, understand the exact failing rule, and then move the same logic into release gates, supply-path QA, and AI-assisted trafficking workflows.",
            "That is the gap vastlint tries to close. It builds on top of the published IAB Tech Lab VAST standard and related public materials, while adding the wider workflow that production ad-tech teams now need."
          ]
        },
        {
          "type": "quote",
          "quote": "This is not a rebrand of the official IAB tool. It is an independent update for teams that need broader coverage and a modern validation workflow.",
          "attribution": "vastlint field note"
        },
        {
          "type": "resources",
          "heading": "References and useful starting points",
          "items": [
            {
              "label": "IAB Tech Lab VAST standards hub",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "Official VAST overview, version history, and standards references.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST GitHub repository",
              "href": "https://github.com/InteractiveAdvertisingBureau/vast",
              "description": "Public VAST specification materials and supporting repository maintained by IAB Tech Lab.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST Tag Validator",
              "href": "https://tools.iabtechlab.com/resourcecenter/vastTagValidator",
              "description": "The official public validator page from the standards owner.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST Tag Tester",
              "href": "https://vasttester.iabtechlab.com/",
              "description": "The official public tester endpoint linked from the IAB Tech Lab VAST resources.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab Specification Adoption Program",
              "href": "https://tools.iabtechlab.com/adoption",
              "description": "Official adoption-program context from IAB Tech Lab if you need the standards body's own program surface.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB VAST validator guide",
              "href": "/guides/iab-vast-validator/",
              "description": "Our independent guide to validating tags against the IAB VAST standard without implying official affiliation.",
              "source": "Guide"
            },
            {
              "label": "vastlint methodology",
              "href": "/docs/methodology/",
              "description": "How VASTlint derives rules from VAST schemas, normative prose, and related standards.",
              "source": "Docs"
            },
            {
              "label": "Validate VAST XML online",
              "href": "/validate/",
              "description": "Paste resolved XML and check it against the current vastlint rule set.",
              "source": "Tool"
            },
            {
              "label": "Test a live VAST tag URL",
              "href": "/tester/",
              "description": "Start from a live URL when the real problem is wrapper resolution and fetch-time behavior.",
              "source": "Tool"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Need the broader workflow, not just the baseline?",
          "paragraph": "Start with live URL testing or resolved XML validation in vastlint, then cross-check with the official IAB Tech Lab surfaces when you need the standards-owner baseline too.",
          "href": "/tester/",
          "label": "Test a live VAST tag URL"
        }
      ]
    },
    {
      "slug": "latest-vast-version",
      "title": "What Is the Latest VAST Version? VAST 4.3, the VAST 4.4 Draft, and the IAB CTV Addendum",
      "description": "The latest officially released IAB VAST version is still 4.3. A vast_4.4.xsd appeared in July 2026 but is marked DRAFT. Here is how 4.3, the 4.4 draft, the 2024 CTV Addendum, and real-world version support fit together without republishing the spec.",
      "publishedAt": "2026-05-27",
      "updatedAt": "2026-05-27",
      "author": "Alex Sekowski",
      "readingTime": "6 min read",
      "heroKicker": "VAST versions",
      "tags": [
        "VAST versions",
        "IAB Tech Lab",
        "CTV",
        "Ad ops"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "The latest officially released IAB VAST version is 4.3. As of July 2026 there is still no published VAST 4.4 specification.",
            "That answer needs a footnote it did not need when this post went up. On 17 July 2026 a file called vast_4.4.xsd was merged into the IAB VAST repository, from a branch named 4.4Development. It is not a release yet: the schema's own annotation reads \"DRAFT for working group discussion\", so it is still being worked through. It landed alongside the CTV Ad Portfolio work, whose signaling guidance was finalised on 22 July and is ready to build against today.",
            "What changed after 4.3 is the VAST CTV Addendum 2024, published by IAB Tech Lab as a backwards-compatible addendum rather than a new core VAST version. Between that, the addendum, and now a draft 4.4 XSD, it is easy to see why teams searching for the latest VAST version get mixed signals."
          ]
        },
        {
          "type": "list",
          "heading": "The VAST version timeline you can cite",
          "items": [
            "VAST 2.0: 2008. The baseline for inline ads, wrappers, tracking, and companions.",
            "VAST 3.0: 2012. Added skippable ads, icons, and ad pods.",
            "VAST 4.0: 2016. Added mezzanine files, UniversalAdId, and stronger SSAI and CTV alignment.",
            "VAST 4.1: 2018. Added OMID verification, interactive creative files, and accessibility improvements.",
            "VAST 4.2: 2019. Clarified macros and conditional-ad behavior.",
            "VAST 4.3: December 2022. Formalized SIMID and fully removed VPAID from the version. Still the latest release.",
            "VAST CTV Addendum 2024: July 2024. Important, but not a new VAST core version.",
            "vast_4.4.xsd: July 2026. A working-group draft supporting the CTV Ad Portfolio. Adds video, duration and SIMID to NonLinear ads. Keep 4.2 or 4.3 in your production version attribute for now."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the IAB has officially published",
          "paragraphs": [
            "If you need the authoritative source, use the IAB Tech Lab VAST standards hub and the public VAST GitHub repository. Those are the right places to confirm whether a version is released, what the latest named version is, and whether a change shipped as a full specification update or as an addendum.",
            "The practical distinction matters. A new addendum can be operationally important without becoming the new answer to the question what is the latest VAST version. That is exactly where the CTV Addendum 2024 sits today."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the IAB VAST spec is still the harness for the ecosystem",
          "paragraphs": [
            "The reason VAST versions matter is not just XML syntax. The IAB Tech Lab VAST specification is the harness that keeps the video ad ecosystem interoperable. It gives ad servers, SSPs, DSPs, CTV apps, web players, SSAI vendors, and measurement providers a shared contract for what a video ad response contains, how wrappers resolve, where tracking belongs, and which interactive or verification mechanisms are valid in a given version.",
            "Without that harness, every buyer, seller, player, and measurement stack would need bespoke pairwise integrations. With it, a VAST tag generated in one system can be trafficked through another, inspected by a third, and played by a fourth. That is why the released IAB version still matters even when vendors add their own tooling and extensions around it."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why VASTlint is the harness for AI agents trafficking VAST",
          "paragraphs": [
            "AI agents do not consume standards prose the way humans do. They need an executable surface. That is where vastlint fits. The VAST spec defines the contract; vastlint turns that contract into machine-usable validation, structured rule IDs, fix guidance, and MCP-callable tools that an agent can use before trafficking a tag.",
            "In an agentic workflow, a planner agent, creative agent, trafficking agent, or QA agent can hand the final VAST tag to vastlint and get back a deterministic answer: version detected, errors, warnings, XPath locations, and spec references. In that sense, VASTlint is a harness for AI agents in the same way the IAB VAST spec is a harness for the broader market. It constrains behavior enough that autonomous systems can traffic tags without guessing what the protocol expects."
          ]
        },
        {
          "type": "list",
          "heading": "What that means in practice for agentic trafficking",
          "items": [
            "A trafficking agent can validate a tag before launch instead of learning from no-fill or playback failure after delivery starts.",
            "A QA agent can explain failures with rule IDs and spec references instead of vague natural-language guesses.",
            "An orchestrator can call validate_vast or validate_vast_url over MCP as a pre-trafficking or pre-approval step.",
            "Human traffickers and AI agents can share the same validation harness, which keeps the workflow consistent across UI, CI, and automated delivery pipelines."
          ]
        },
        {
          "type": "list",
          "heading": "What teams get wrong about VAST versions",
          "items": [
            "Treating the CTV Addendum 2024 as if it were VAST 4.4. It is not.",
            "Assuming the newest IAB VAST-related document is automatically the newest VAST core version.",
            "Planning migrations around rumors, issue trackers, or vendor marketing instead of the released IAB standard.",
            "Copying spec tables into internal docs when a short release-status summary plus links to IAB sources is enough.",
            "Picking a version based only on recency instead of player, SSAI, CTV, and partner support."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What version should you support in production",
          "paragraphs": [
            "For new supply-side or validation work, VAST 4.2 and 4.3 are the right default targets. They align better with modern CTV, measurement, and interactive requirements, and they avoid building new dependencies around VPAID-era behavior.",
            "That does not mean you can ignore older tags. In the long tail, VAST 3.0 is still common, and VAST 2.0 still appears in legacy systems. The right production posture is usually generate modern tags, accept older inbound tags, and validate by declared version instead of forcing every partner onto the newest release on day one."
          ]
        },
        {
          "type": "list",
          "heading": "Recommended support policy",
          "items": [
            "Generate VAST 4.2 or 4.3 for new campaigns and integrations.",
            "Accept VAST 3.0 and, where business requires it, VAST 2.0 from older partners.",
            "Handle the CTV Addendum 2024 when CTV disclosure, creative identity, or high-resolution workflows matter.",
            "Do not treat VAST 4.4 as available until IAB Tech Lab actually publishes it.",
            "Validate tags against the declared version so newer elements do not silently leak into older documents."
          ]
        },
        {
          "type": "quote",
          "quote": "The latest VAST-related document is not always the latest VAST version.",
          "attribution": "vastlint field note"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "A pause ad used to be a JPEG. VAST 4.4 changes that.",
              "href": "/blog/vast-4-4-draft-schema-ctv-ad-portfolio",
              "description": "What the July 2026 draft schema and the finalised CTV Ad Portfolio guidance change, and why the version attribute should stay where it is.",
              "source": "vastlint"
            },
            {
              "label": "IAB Tech Lab VAST standards hub",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "Official VAST standards landing page from IAB Tech Lab.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST GitHub repository",
              "href": "https://github.com/InteractiveAdvertisingBureau/vast",
              "description": "Public repository for VAST specification materials and issue tracking.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Which VAST version should you use?",
              "href": "/docs/vast-versions/",
              "description": "Version-by-version guide covering VAST 2.0 through 4.3 and the CTV Addendum.",
              "source": "Docs"
            },
            {
              "label": "VAST 4.4 preview",
              "href": "/docs/vast-4-4/",
              "description": "What the next named VAST version is likely to add once it is released.",
              "source": "Docs"
            },
            {
              "label": "VAST validation in agentic ad delivery",
              "href": "/docs/agentic/",
              "description": "How vastlint exposes VAST validation to buyer, trafficking, and QA agents through MCP.",
              "source": "Docs"
            },
            {
              "label": "Validate a VAST tag",
              "href": "/validate/",
              "description": "Check which version a live tag declares and whether its XML matches that version.",
              "source": "Tool"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Need the full version-by-version breakdown?",
          "paragraph": "Use the main VAST versions guide for the release timeline, migration paths, and the operational differences between 2.0, 3.0, and 4.x.",
          "href": "/docs/vast-versions/",
          "label": "Open the VAST versions guide"
        }
      ]
    },
    {
      "slug": "best-vast-validator-tools-2026",
      "title": "Best VAST Validator Tools in 2026",
      "description": "VASTlint is the strongest starting point when you need current-version standards validation, live URL testing, wrapper inspection, and reusable automation. Here is how IAB Tech Lab, Google IMA, AdMeIn, SpringServe, AdServe, and schema-only validators compare on the public surface.",
      "publishedAt": "2026-05-24",
      "updatedAt": "2026-06-11",
      "author": "Alex Sekowski",
      "readingTime": "11 min read",
      "heroKicker": "Roundup",
      "tags": [
        "VAST validator",
        "VAST tester",
        "Ad ops",
        "CTV"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "For most ad-tech teams, VASTlint is the best place to start because it covers the operational layer first: current-version standards validation, live URL testing, wrapper inspection, public methodology, and embeddable automation.",
            "The rest of the public tools still matter, but usually for narrower reasons. The IAB Tech Lab validator matters as the official baseline from the standards owner. Google IMA Video Suite Inspector matters as an IMA HTML5 runtime debugger. AdMeIn, SpringServe, and AdServe matter as tester-style browser QA surfaces. Schema-only validators matter when all you need is a narrow structural baseline.",
            "That is why the right answer for serious teams is usually not one tool. It is the right order of tools. Start with standards validation and wrapper inspection. Then use runtime-specific or preview-specific testers when the destination environment requires them."
          ]
        },
        {
          "type": "list",
          "heading": "The fastest way to choose",
          "items": [
            "Pick vastlint if you need VAST 2.0 through 4.3 coverage, public methodology, live URL testing, wrapper inspection, fix guidance, and reusable validation beyond a browser page.",
            "Pick the IAB Tech Lab validator if official status from the standards owner matters most.",
            "Pick Google IMA Video Suite Inspector if the real question is whether the tag behaves correctly in IMA HTML5.",
            "Pick AdMeIn, SpringServe, or AdServe if the team wants a tester-style browser QA surface and public preview-first workflows.",
            "Pick a schema-only validator if all you want is a narrow schema baseline and nothing more.",
            "Use more than one tool when the campaign matters enough that standards validation and runtime behavior should be checked separately."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The three jobs most teams mix together",
          "paragraphs": [
            "The biggest source of confusion in this category is that many teams ask one vague question: what is the best VAST validator? But the tools on the public market are usually optimized for one of three jobs, not all three.",
            "The first job is official or standards-owner baseline validation. The second is runtime or player preview, where the tool actually tries to render the ad, fire tracking, or show event behavior in a specific environment. The third is embeddable standards validation, where teams need a current rule set, wrapper-chain visibility, live URL testing, and a path into CI or server-side systems.",
            "Once you separate those jobs, the tool choices become much easier and much fairer."
          ]
        },
        {
          "type": "list",
          "heading": "What each tool is best understood as",
          "items": [
            "vastlint: an independent standards-first toolkit with validate, test, and inspect workflows plus public methodology and embeddable automation.",
            "IAB Tech Lab VAST Tag Validator: the official public baseline from the standards owner, with public support on its page for VAST 2.0, 3.0, and 4.1.",
            "Google IMA Video Suite Inspector: an IMA HTML5 runtime debugger, not a neutral validator for every downstream environment.",
            "AdMeIn VAST Tester: a compact tester-style public surface with browser QA, Google IMA-powered preview, and deeper analysis gated behind sign-in.",
            "SpringServe Tagtest: a player-style public tester for quick operational checks, not a public methodology-driven validation surface.",
            "AdServe VAST Inspector: a player-style tester that publicly advertises VAST support through 4.2 and focuses on playback, redirects, tracking, and measurement-style checks.",
            "schema-only validators: useful when all you want is schema validation, but narrow if you also need wrapper inspection, live URL testing, or prose-derived 4.3 rules."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where VASTlint is materially different",
          "paragraphs": [
            "The strongest mistake to avoid is giving competitors credit for generic QA capabilities that vastlint already exposes on its own public surfaces. vastlint already covers creative preview, click behavior, tracking visibility, metadata inspection, wrapper unwrapping, and creative parsing. So when another tool leads with preview, events, or wrapper visibility, that does not automatically make it broader.",
            "The real differences usually live elsewhere: official status, runtime specificity, public version coverage, whether deeper analysis is gated, whether methodology is public, and whether the validation path can be embedded in automation. That is where VASTlint is materially different from most public alternatives.",
            "It covers VAST 2.0 through 4.3, publishes how rules are derived from IAB XSD schemas and normative prose, separates validate, test, and inspect into distinct workflows, and ships as web, CLI, Rust, Go, npm, and MCP tooling."
          ]
        },
        {
          "type": "list",
          "heading": "Decision matrix in plain English",
          "items": [
            "Latest publicly advertised version support: VASTlint is strongest because its public positioning runs through VAST 4.3; IAB's public page stops at 4.1, while AdMeIn and AdServe publicly stop at 4.2.",
            "Public rule diagnostics and methodology: VASTlint is strongest because it exposes both publicly; most tester-style tools do not foreground a public rule catalog or derivation story.",
            "Live URL testing and wrapper inspection: VASTlint is strongest as a public workflow because it explicitly separates live tag testing and wrapper inspection instead of burying those tasks inside one tester surface.",
            "CI, server-side use, and self-hosting path: VASTlint is strongest because it is open source and embeddable instead of only being a hosted browser tool.",
            "Playback or runtime preview: Google IMA wins when IMA HTML5 is the actual runtime; tester-style browser tools like AdMeIn, SpringServe, and AdServe also fit here.",
            "Official affiliation: IAB Tech Lab is the clear winner because it is the standards owner. VASTlint is independent by design."
          ]
        },
        {
          "type": "quote",
          "quote": "Most VAST tools win one job. The useful stack is knowing which job you are actually hiring the tool to do.",
          "attribution": "vastlint field note"
        },
        {
          "type": "paragraphs",
          "heading": "Recommended order of operations",
          "paragraphs": [
            "If the input is a live ad tag from an exchange, SSP, or ad server, the first step should usually be standards validation and wrapper inspection, not a player preview. Resolve the live tag, inspect every wrapper hop, and validate the final XML before you ask whether a specific runtime likes what it sees.",
            "After that, move into the environment-specific or packaging-specific tool that matches your question. If stakeholders need the standards-owner baseline, cross-check with IAB Tech Lab. If the target runtime is IMA HTML5, use Google's inspector. If the team wants another public browser QA pass, use AdMeIn or another tester-style surface.",
            "That order prevents runtime noise from masking structural problems and keeps official baselines from being misused as a substitute for operational debugging."
          ]
        },
        {
          "type": "code",
          "heading": "Practical workflow for most teams",
          "language": "bash",
          "code": "# 1. Start with the live tag URL in vastlint tester\n# 2. Inspect the wrapper chain hop by hop in vastlint inspector\n# 3. Validate the resolved XML against current published VAST rules in vastlint validator\n# 4. If needed, cross-check with the IAB validator for the official baseline\n# 5. If needed, run a runtime-specific or tester-style tool such as Google IMA or AdMeIn\n# 6. Fix standards issues first, then fix runtime or preview-specific behavior"
        },
        {
          "type": "list",
          "heading": "Which tool should you start with",
          "items": [
            "Start with vastlint if you want the best all-around operational workflow for current VAST validation.",
            "Start with IAB Tech Lab if internal trust depends on official standards-owner affiliation.",
            "Start with Google IMA if the only question is IMA HTML5 playback behavior.",
            "Start with AdMeIn, SpringServe, or AdServe if the team wants a fast tester-style browser QA pass after structural validation.",
            "Start with a schema-only validator only if you explicitly want a narrow schema check and know that wrapper, live URL, and 4.3 methodology questions are out of scope."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Bottom line",
          "paragraphs": [
            "If you want the broadest practical workflow for standards-derived validation, current-version coverage, wrapper inspection, live URL testing, public methodology, and reusable automation, VASTlint is the strongest starting point.",
            "The rest of the field still has a place. The IAB validator is the official reference. Google's inspector is the right IMA-specific runtime check. AdMeIn and similar tools are useful when the team wants a compact tester surface. The useful comparison is not which tool wins every category. It is which tool wins the category you actually need next."
          ]
        },
        {
          "type": "resources",
          "heading": "Related comparisons and docs",
          "items": [
            {
              "label": "vastlint vs IAB Tech Lab VAST Tag Validator",
              "href": "/blog/vastlint-vs-iab-tech-lab-vast-tag-validator/",
              "description": "Head-to-head comparison between vastlint and the official IAB Tech Lab validator.",
              "source": "Blog"
            },
            {
              "label": "vastlint vs Google IMA Video Suite Inspector",
              "href": "/blog/vastlint-vs-google-ima-video-suite-inspector/",
              "description": "Head-to-head comparison focused on IMA runtime testing versus standards-first validation.",
              "source": "Blog"
            },
            {
              "label": "vastlint vs AdMeIn VAST Tester",
              "href": "/blog/vastlint-vs-admein-vast-tester/",
              "description": "Head-to-head comparison focused on tester packaging versus standards depth and workflow breadth.",
              "source": "Blog"
            },
            {
              "label": "vastlint vs SpringServe VAST Tag Tester",
              "href": "/blog/vastlint-vs-springserve-vast-tag-tester/",
              "description": "Player-style event checks and VMAP playout versus public standards validation and CI-ready tooling.",
              "source": "Blog"
            },
            {
              "label": "vastlint vs AdServe VAST Inspector",
              "href": "/blog/vastlint-vs-adserve-vast-inspector/",
              "description": "Playback inspection through VAST 4.2 versus spec-derived validation through 4.3 with hop-by-hop wrapper inspection.",
              "source": "Blog"
            },
            {
              "label": "Rule derivation methodology",
              "href": "/docs/methodology/",
              "description": "How VASTlint derives rules from IAB XSD schemas, normative prose, and related standards.",
              "source": "Docs"
            },
            {
              "label": "Validate VAST XML online",
              "href": "/validate/",
              "description": "Run a standards-derived XML compliance check against VAST 2.0 through 4.3.",
              "source": "Tool"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Start with the standards layer",
          "paragraph": "Validate the XML, test the live tag, and inspect the wrapper chain before you move into runtime-specific or preview-first tools.",
          "href": "/tester/",
          "label": "Test a live VAST tag URL"
        }
      ]
    },
    {
      "slug": "vastlint-vs-iab-tech-lab-vast-tag-validator",
      "title": "vastlint vs IAB Tech Lab VAST Tag Validator",
      "description": "Live VAST URL goes to the vastlint tester. SIMID handshake goes to the IAB-style workbench. Resolved XML goes to the validator. The IAB Tech Lab validator is the official baseline. Here is when to use each.",
      "publishedAt": "2026-05-24",
      "updatedAt": "2026-09-05",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Tool comparison",
      "tags": [
        "IAB Tech Lab",
        "VAST validator",
        "VAST tester",
        "Ad ops"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "If your team needs the best day-to-day validation workflow, start with vastlint. Split the click: a live VAST URL goes to the tester, wrapper hops go to the inspector, a SIMID handshake or IAB sample creative goes to the IAB-style workbench, and resolved XML goes to the validator.",
            "If the question is what the standards owner itself exposes publicly, the IAB Tech Lab VAST Tag Validator is the right official reference point. That is its real differentiator. It is the validator publicly presented by the group that publishes the VAST specification.",
            "Most serious teams should treat these as complementary. Use vastlint for the operational workflow and current-version coverage. Use the IAB validator when the official baseline itself matters to the discussion. The IAB-style workbench on iab-tech-lab-vast-tester.vastlint.org is an independent fork, not an IAB Tech Lab product."
          ]
        },
        {
          "type": "list",
          "heading": "The fastest way to choose between them",
          "items": [
            "Use vastlint tester when your input is a live VAST URL: fetch, preview, tracking, clicks.",
            "Use the inspector when the chain is the question: 302, 303, wrapper depth, hop that went empty.",
            "Use the IAB-style VAST tester for SIMID studio and IAB sample creatives. It is an independent fork, not an official IAB Tech Lab product.",
            "Use vastlint validator when you already hold resolved XML and need current-version coverage beyond the IAB page's publicly advertised 2.0, 3.0, and 4.1 support.",
            "Use vastlint when you need public rule explanations, public methodology, or a workflow that extends into CI, automation, or server-side systems.",
            "Use the IAB Tech Lab validator when the most important question is what the standards owner publicly validates.",
            "Use both when you want the operational workflow first and an official baseline cross-check second."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why VASTlint is the stronger starting point",
          "paragraphs": [
            "VASTlint is the stronger starting point when the team needs an operational validator that still begins from the published VAST standards baseline, then carries that coverage forward through VAST 4.3. That matters because the public IAB page advertises support through 4.1, while modern teams still have to handle 4.2 details and 4.3 tags.",
            "It also surfaces the three jobs teams actually need in practice: validate resolved XML, test a live VAST URL, and inspect a wrapper chain hop by hop. That is a clearer day-to-day workflow than a single validator-first page, and it makes repeated QA and debugging easier.",
            "That is the practical split. VASTlint is the stronger operational workflow for current-version handling, public methodology, wrapper debugging, and reusable automation. The IAB validator remains the official baseline reference when standards-owner affiliation matters."
          ]
        },
        {
          "type": "list",
          "heading": "The public-surface gaps vastlint closes",
          "items": [
            "Public positioning around VAST 2.0 through 4.3, not only the versions publicly advertised on the IAB validator page.",
            "A public methodology explaining how rules are derived from IAB VAST XSD schemas where available and from RFC 2119 normative prose where schemas stop.",
            "An explicit public story for VAST 4.3, including why 4.3 checks must be prose-derived because no published IAB XSD exists.",
            "Three separate workflows instead of one validator-first surface: validator for resolved XML, tester for live URLs and creative preview, and inspector for wrapper-chain debugging, metadata, and tracking counts.",
            "Public rule references and fix-oriented diagnostics that can be cited internally during debugging and approvals.",
            "An open-source, embeddable validation path for web, CLI, Rust, Go, npm, and MCP workflows."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the IAB tool is publicly optimized for",
          "paragraphs": [
            "The public IAB Tech Lab page is explicit about what makes the validator important: it was developed by the IAB Tech Lab team. That official status is meaningful. If an internal stakeholder asks which public validator comes directly from the standards owner, this is the strongest answer.",
            "The same public page advertises support for VAST 2.0, 3.0, and 4.1, and it lists a broad set of checks around inline linear, inline non-linear, companions, wrappers, click tracking, event tracking, mezzanine files, VPAID separation, ready-to-serve media files, conditional ads, Universal AdID, ad verification, and viewable impressions.",
            "That makes the IAB validator a credible public baseline. But the public surface is validator-oriented. It is not clearly presented as a broader toolkit with separate live URL testing, wrapper inspection, and embeddable validation paths."
          ]
        },
        {
          "type": "list",
          "heading": "What official status changes on the public surface",
          "items": [
            "It is the public validator presented by the standards owner, which is a trust signal no independent tool can duplicate.",
            "It gives teams a direct standards-owner baseline when stakeholders want to see what the IAB itself exposes publicly.",
            "It is a useful reference point for teams that want to stay close to the public framing and terminology used by the specification owner.",
            "It can be a strong cross-check when procurement, compliance, or partner conversations care about official affiliation.",
            "It keeps the comparison anchored to the standard body rather than to a player vendor or commercial tester."
          ]
        },
        {
          "type": "quote",
          "quote": "The IAB validator is the official baseline. VASTlint is the current-version workflow teams actually operate with.",
          "attribution": "vastlint field note"
        },
        {
          "type": "paragraphs",
          "heading": "Use them in this order",
          "paragraphs": [
            "If the starting point is a live ad tag from an exchange, ad server, or SSP, the first job is to fetch that URL in the vastlint tester. If the player printed 302 or 303, inspect the wrapper chain hop by hop. If the creative is SIMID, open the IAB-style workbench for the handshake. Then validate the resolved XML against a current public rule set.",
            "Once the resolved XML is structurally sound, the IAB validator can become useful as an additional official reference point, especially when the tag falls inside the version range the IAB page publicly advertises. At that point, the question is no longer does this tag work at all. The question is does this already-debugged tag line up with the official public baseline as well.",
            "That sequence keeps the operational debugging first and the standards-owner cross-check second. It avoids using an official validator as a substitute for current-version troubleshooting, wrapper inspection, SIMID studio, or automation-friendly validation."
          ]
        },
        {
          "type": "code",
          "heading": "Recommended workflow when official baseline matters",
          "language": "bash",
          "code": "# 1. Live tag URL: vastlint.org/tester/\n# 2. Wrapper hops: vastlint.org/inspect/\n# 3. SIMID handshake or IAB samples: iab-tech-lab-vast-tester.vastlint.org (independent fork)\n# 4. Resolved XML: vastlint.org/validate/\n# 5. If stakeholders want the standards-owner baseline, cross-check with the IAB validator where its public version coverage applies"
        },
        {
          "type": "list",
          "heading": "When VASTlint is the better first choice",
          "items": [
            "You need coverage that includes VAST 4.2 and 4.3, not only versions publicly advertised through 4.1.",
            "You need a public explanation of how 4.3 rules are derived without a published IAB XSD.",
            "You are starting from a live VAST URL or a redirecting wrapper chain, not just a final XML payload.",
            "You need rule-level diagnostics, public fix guidance, and methodology you can cite internally.",
            "You want one validation workflow that can move into CI, server-side systems, or automated QA.",
            "You need an open-source toolchain rather than a single public validator surface."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "When the IAB validator should still be in the workflow",
          "paragraphs": [
            "The IAB validator should still be in the workflow when official status itself carries weight. If a buyer, publisher, legal reviewer, or internal approver wants to know what the standards owner exposes publicly, the IAB tool is the right reference point.",
            "That is the fair comparison. The IAB validator is not interesting because it outclasses vastlint on operational coverage. It is interesting because it is the official public baseline from the specification owner. VASTlint is stronger when the first question is current-version validation, 4.3 methodology, wrapper debugging, and reusable tooling.",
            "If you want a more inspectable community implementation in the same orbit, the author also maintains a public IAB-style VAST tester at iab-tech-lab-vast-tester.vastlint.org with source on GitHub. Treat it as a community fork, not as an official IAB Tech Lab property. Use it for SIMID studio and IAB sample creatives. Live URLs still start on vastlint.org/tester/."
          ]
        },
        {
          "type": "resources",
          "heading": "Sources and related docs",
          "items": [
            {
              "label": "IAB Tech Lab VAST Tag Validator",
              "href": "https://iabtechlab.com/software/vast-tag-validator/",
              "description": "The IAB Tech Lab's public VAST validator page, including its official positioning and advertised support for VAST 2.0, 3.0, and 4.1.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST standards",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The standards hub for VAST specifications published by IAB Tech Lab.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB VAST validator guide",
              "href": "/guides/iab-vast-validator/",
              "description": "vastlint's guide to what the official IAB validator is useful for and where operational workflows still need more than an official baseline.",
              "source": "Guide"
            },
            {
              "label": "IAB-style VAST tester (SIMID studio)",
              "href": "https://iab-tech-lab-vast-tester.vastlint.org/",
              "description": "Independent fork for SIMID handshake QA and IAB sample creatives. Not an official IAB Tech Lab property.",
              "source": "Community"
            },
            {
              "label": "VAST tag tester",
              "href": "/tester/",
              "description": "Fetch a live VAST URL, preview creative, inspect tracking and click URLs.",
              "source": "Tool"
            },
            {
              "label": "VAST inspector",
              "href": "/inspect/",
              "description": "Walk wrapper hops when the chain is the question.",
              "source": "Tool"
            },
            {
              "label": "VAST-Tester fork source",
              "href": "https://github.com/aleksUIX/VAST-Tester",
              "description": "GitHub repository for the author's public VAST-Tester fork.",
              "source": "GitHub"
            },
            {
              "label": "Rule derivation methodology",
              "href": "/docs/methodology/",
              "description": "How VASTlint derives rules from IAB XSD schemas, normative prose, and related standards.",
              "source": "Docs"
            },
            {
              "label": "Validate VAST XML online",
              "href": "/docs/validate-vast-xml/",
              "description": "How to choose between validating resolved XML and testing a live tag URL.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Start with the live tag URL",
          "paragraph": "Fetch the live VAST URL on the tester. Walk hops on the inspector. Open the IAB-style workbench for a SIMID handshake. Paste resolved XML into the validator. Use the official IAB validator as a reference point when official baseline matters.",
          "href": "/tester/",
          "label": "Test a live VAST tag URL"
        }
      ]
    },
    {
      "slug": "vastlint-vs-admein-vast-tester",
      "title": "vastlint vs AdMeIn VAST Tester",
      "description": "vastlint matches AdMeIn on preview, tracking, metadata, unwrapping, and creative inspection, and is stronger for public standards depth, VAST 4.3 coverage, methodology, and CI-friendly validation. AdMeIn mainly changes the packaging with a compact single-page tester. Here is where each fits.",
      "publishedAt": "2026-05-24",
      "updatedAt": "2026-05-24",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Tool comparison",
      "tags": [
        "AdMeIn",
        "VAST validator",
        "VAST tester",
        "Ad ops"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "If your immediate job is to validate the tag against a public, standards-derived rule set, inspect wrappers, preview creatives, parse metadata, and keep the workflow reusable outside a browser session, VASTlint is the stronger first tool. It already covers preview, tracking, wrapper unwrapping, creative parsing, and rule-level diagnostics without depending on a gated tester surface.",
            "AdMeIn is still a credible public option when the team specifically wants a compact single-page tester-style experience. It packages browser preview, metadata, tracking, and wrapper visibility into one page, but that packaging is not a capability moat over vastlint.",
            "The cleanest workflow for teams that test aggressively is to use vastlint first for the standards layer, then use AdMeIn if one more browser-preview pass helps. That keeps structural debugging separate from player-style preview debugging."
          ]
        },
        {
          "type": "list",
          "heading": "The fastest way to choose between them",
          "items": [
            "Use vastlint if you want the same core QA signals plus stronger standards coverage and a clearer split between tester, inspector, and validator.",
            "Use vastlint when you need public standards-derived validation before you trust any preview environment.",
            "Use vastlint when your input is a live VAST URL with redirects and you need to separate validation, testing, and wrapper inspection into clearer steps.",
            "Use AdMeIn if the team prefers a single tester-style page.",
            "Use AdMeIn after that if the team wants a second visual QA pass with playback-style feedback.",
            "Use vastlint if you need public rule docs, a public methodology, or a workflow that extends into CI, CLI, server-side systems, or automated QA.",
            "Use both if the campaign is valuable enough that standards compliance and browser preview should be checked separately."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why VASTlint is the stronger starting point",
          "paragraphs": [
            "VASTlint is the stronger starting point when the team wants a public, standards-derived answer before it leans on any tester UX. It already covers preview, tracking, wrapper unwrapping, creative parsing, metadata inspection, and rule-level diagnostics without depending on a gated single-page surface.",
            "It also keeps the workflow reusable outside the browser session: test a live tag URL, inspect every wrapper hop, and validate the resolved XML against a public methodology that explains where the rules come from. That is a cleaner first step than starting inside a preview environment influenced by a specific playback stack.",
            "That is the practical split. VASTlint is stronger on standards depth, 4.3 coverage, methodology, and reusable automation. AdMeIn still has value when the team wants a compact tester-style page after that."
          ]
        },
        {
          "type": "list",
          "heading": "The public-surface gaps vastlint closes",
          "items": [
            "Public positioning around VAST 2.0 through 4.3, including the specific 4.3 methodology story where no published IAB XSD exists.",
            "A public methodology page explaining how rules are derived from IAB VAST XSD schemas, RFC 2119 normative prose, and related standards.",
            "Public rule references and fix-oriented diagnostics rather than a preview-first surface with gated deeper analysis.",
            "The same practical QA surface and more: validator for resolved XML, tester for live URLs and creative preview, and inspector for wrapper hops, metadata, tracking counts, and creative parsing.",
            "An open-source path that extends beyond browser use into CLI, Rust, Go, npm, and MCP workflows.",
            "A neutral standards-first baseline that is not tied to a Google IMA-powered preview environment."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What AdMeIn is publicly optimized for",
          "paragraphs": [
            "On its public page, AdMeIn positions the tool as a VAST Tag Tester and Inspector that accepts both VAST tag URLs and VAST XML. It promises live video ad playback, metadata, tracking events, wrapper-chain visibility, and validation-oriented checks. That framing is useful for operators who want a compact QA console, but it is not unique coverage: vastlint also exposes preview, creative metadata, tracking, wrapper unwrapping, and validation across its dedicated surfaces.",
            "The page also says its ad previews are powered by the Google IMA SDK. That matters because it tells you the experience is not a neutral abstract validator. It is a browser preview environment that is already anchored to a specific playback stack.",
            "AdMeIn also publicly advertises support for VAST 2.0, 3.0, 4.0, 4.1, and 4.2, plus VMAP 1.0 support. That makes it look broad enough for many current workflows, especially teams whose day-to-day work is still dominated by preview and trafficking QA rather than standards analysis."
          ]
        },
        {
          "type": "list",
          "heading": "What AdMeIn changes on the public surface",
          "items": [
            "A more compact single-page public QA workflow that keeps URL input, XML input, preview, metadata, events, and wrapper-oriented views together.",
            "A tester-style entry point that may feel simpler to first-time manual users than moving between dedicated validator, tester, and inspector pages.",
            "Public VMAP positioning in addition to VAST testing, which is useful when teams are debugging break scheduling as well as tag structure.",
            "A Google IMA-powered preview environment for teams that explicitly want that runtime in the loop.",
            "A public page that leads with tester UX rather than standards methodology or rule documentation."
          ]
        },
        {
          "type": "quote",
          "quote": "AdMeIn is packaged like a tester. vastlint already covers the same core QA ground and more.",
          "attribution": "vastlint field note"
        },
        {
          "type": "paragraphs",
          "heading": "Use them in this order",
          "paragraphs": [
            "If you start with a preview-first tool, it is easy to blur together multiple problems: the XML itself, wrapper-chain issues, and the behavior of the preview runtime. That often produces noisy debugging because the team starts attributing every failure to the player environment before they have verified the tag structurally.",
            "A cleaner sequence is to start with the live tag in vastlint tester, inspect the wrapper chain in vastlint inspector, validate the resolved XML in vastlint validator, and only then move into AdMeIn if you want an additional browser preview or tracking-event pass.",
            "That order keeps standards validation separate from visual QA. It also means that if AdMeIn surfaces a playback or tracking issue later, the team already knows whether the underlying tag passed a public standards baseline first."
          ]
        },
        {
          "type": "code",
          "heading": "Recommended workflow when AdMeIn is part of QA",
          "language": "bash",
          "code": "# 1. Start from the live VAST URL in vastlint tester\n# 2. Inspect each wrapper hop in vastlint inspector\n# 3. Validate the resolved XML against public standards-derived rules in vastlint validator\n# 4. If the team wants a browser preview and event-oriented QA pass, run the same tag in AdMeIn\n# 5. Fix structural issues first, then fix preview or playback issues"
        },
        {
          "type": "list",
          "heading": "When VASTlint is the better first choice",
          "items": [
            "You need a public standards-based answer before anyone logs in to a gated QA surface.",
            "You need current public positioning that includes VAST 4.3, not only versions publicly advertised through 4.2.",
            "You need methodology you can cite internally when someone asks why a rule exists or how the validator derives it.",
            "You need one validator that can move from browser QA into CI, ad-server checks, or automated workflows.",
            "You need a clearer separation between live URL fetches, wrapper inspection, and final XML validation.",
            "You want a neutral baseline before debugging any preview environment that is already tied to a player stack."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "When AdMeIn still earns a spot in the workflow",
          "paragraphs": [
            "AdMeIn still makes sense when the team wants a fast single-page tester UX or wants another browser surface alongside vastlint. But the capability gap is smaller than the page framing suggests: vastlint already covers preview, metadata, tracking, wrapper unwrapping, and creative parsing in its own tester and inspector flows.",
            "That is the fair comparison. AdMeIn is mostly a packaging and entry-point difference. VASTlint is stronger when the first question is standards coverage, rule explainability, wrapper unwrapping, creative parsing, and reusable validation outside a browser session."
          ]
        },
        {
          "type": "resources",
          "heading": "Sources and related docs",
          "items": [
            {
              "label": "AdMeIn VAST Tester",
              "href": "https://admein.io/vast-tester",
              "description": "AdMeIn's public VAST tester and inspector page, including its preview, metadata, wrapper, and tracking-oriented claims.",
              "source": "AdMeIn"
            },
            {
              "label": "Google IMA SDK VAST validator guide",
              "href": "/guides/vast-google-ima-sdk/",
              "description": "vastlint's guide to Google IMA runtime constraints and troubleshooting, useful because AdMeIn says its previews are powered by Google IMA SDK.",
              "source": "Guide"
            },
            {
              "label": "Rule derivation methodology",
              "href": "/docs/methodology/",
              "description": "How VASTlint derives rules from IAB XSD schemas, normative prose, and related standards.",
              "source": "Docs"
            },
            {
              "label": "Validate VAST XML online",
              "href": "/docs/validate-vast-xml/",
              "description": "How to choose between validating resolved XML and testing a live tag URL.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Validate first, preview second",
          "paragraph": "Resolve the live tag, inspect the wrappers, and validate the XML before you move into a preview-oriented QA tool. That gives the team a cleaner debugging signal from the start.",
          "href": "/tester/",
          "label": "Test a live VAST tag URL"
        }
      ]
    },
    {
      "slug": "vastlint-vs-google-ima-video-suite-inspector",
      "title": "vastlint vs Google IMA Video Suite Inspector",
      "description": "Live VAST URL goes to the vastlint tester. SIMID handshake goes to the IAB-style workbench. Then, if IMA HTML5 is the runtime, run the same tag in Google's Video Suite Inspector. Here is when to use each.",
      "publishedAt": "2026-05-24",
      "updatedAt": "2026-09-05",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Tool comparison",
      "tags": [
        "Google IMA",
        "VAST validator",
        "VAST tester",
        "Ad ops"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "If your question is whether the tag is structurally compliant with the published VAST standards before you get into player-specific behavior, VASTlint is the better first tool. Split the click: live URL to the tester, wrapper hops to the inspector, SIMID handshake to the IAB-style workbench, resolved XML to the validator.",
            "If the remaining question is how that tag behaves inside Google's IMA HTML5 playback environment, Google's Video Suite Inspector is the right runtime-specific check. Its public workflow is explicit: paste a VAST tag or VAST response, run the ad, watch the player, and inspect what happens inside the IMA HTML5 stack.",
            "Most serious teams should use both. Fetch and unwrap the tag in vastlint first. Then, if Google IMA HTML5 is one of your real target runtimes, run the resolved tag through Google's inspector as the final environment-specific check."
          ]
        },
        {
          "type": "list",
          "heading": "The fastest way to choose between them",
          "items": [
            "Use vastlint tester when the input is a live tag URL: fetch, preview, tracking, clicks.",
            "Use the inspector when the chain is the question.",
            "Use the IAB-style VAST tester for SIMID studio. Independent fork, not an IAB Tech Lab product. Google's inspector is still the IMA HTML5 runtime check.",
            "Use vastlint when you need standards-derived validation against published IAB VAST rules before you troubleshoot a specific player or SDK.",
            "Use vastlint if you need public rule references, public methodology, or an embeddable workflow for CI, ad servers, SSPs, DSPs, or QA automation.",
            "Use Google IMA Video Suite Inspector when you need to know how the tag behaves inside the IMA HTML5 runtime specifically."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why VASTlint is the stronger starting point",
          "paragraphs": [
            "VASTlint is the stronger starting point when the question is standards compliance before runtime behavior. It validates against the published VAST rules, publishes its methodology, and is not tied to a single player or SDK.",
            "It also separates the three jobs teams usually need in practice: validate XML, test a live URL, and inspect wrapper chains. That gives you a neutral baseline before player-specific behavior or event logs start adding noise.",
            "That is the practical split. VASTlint is the standards-first layer for current-version validation, public rule docs, wrapper debugging, and reusable automation. Google's Video Suite Inspector remains the runtime-specific check when IMA HTML5 is the real target environment."
          ]
        },
        {
          "type": "list",
          "heading": "The public-surface gaps vastlint closes",
          "items": [
            "A public methodology explaining how rules are derived from published IAB VAST XSD schemas where available and RFC 2119 normative prose where schemas stop.",
            "Clear current-positioning around VAST 2.0 through 4.3, including the important detail that VAST 4.3 has no published IAB XSD and must be handled as a prose-derived ruleset.",
            "Three separate workflows instead of one player tester: validator for XML compliance, tester for live URL fetches, creative preview, and click behavior, and inspector for wrapper-chain debugging, metadata, and tracking counts.",
            "Public rule references and fix-oriented diagnostics instead of relying on a runtime-oriented event log as the first debugging step.",
            "An open-source, embeddable validation path for CLI, Rust, Go, npm, and MCP workflows, not just a browser-based inspector.",
            "A neutral standards-first layer you can run before Google IMA, Roku, Samsung, LG webOS, tvOS, ad servers, or buyer-specific QA."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What Google's tool is actually built for",
          "paragraphs": [
            "The public IMA HTML5 Video Suite Inspector page is very clear about its purpose. It asks for a VAST ad tag or VAST ad response, then tells you that its video player will attempt to interpret the response, play the ad, and ping the tracking URLs. The page shows the exact artifacts operators care about during runtime testing: player output, events, and companions. vastlint can also surface preview, tracking, click behavior, and wrapper details, so the distinction is not generic QA visibility. The distinction is that Google's tester is anchored to the IMA HTML5 runtime itself.",
            "That makes it a useful operational tool when IMA HTML5 is the destination environment. If a trafficking team wants to know whether an ad will load in the IMA HTML5 stack, whether companions display there, or whether tracking fires during playback there, the inspector is doing the right job. It is a runtime-oriented debugger, not a broader capability lead over a standards-first toolkit.",
            "That strength is also its boundary. It is centered on IMA HTML5 behavior, not on being a neutral, public, standards-first validation layer for every downstream environment."
          ]
        },
        {
          "type": "list",
          "heading": "What Google adds when IMA HTML5 is the target runtime",
          "items": [
            "A public runtime check inside the IMA HTML5 environment itself, rather than a neutral cross-runtime baseline.",
            "Direct confirmation of how IMA HTML5 interprets the tag once the SDK actually tries to play it, render companions, and fire tracking.",
            "Direct alignment with the Google IMA HTML5 SDK docs, sample tags, and related implementation guides.",
            "Useful for debugging player-side problems that only appear once IMA HTML5 actually tries to interpret and render the ad.",
            "A natural final check when your production runtime is Google IMA HTML5."
          ]
        },
        {
          "type": "quote",
          "quote": "Google's inspector tells you how IMA behaves. vastlint already covers the core QA surface before that runtime check starts.",
          "attribution": "vastlint field note"
        },
        {
          "type": "paragraphs",
          "heading": "Use them in this order",
          "paragraphs": [
            "The operational mistake is to treat these as mutually exclusive substitutes. They solve adjacent problems, not identical ones. If the tag comes from a live ad server URL, fetch it in the vastlint tester. If the player printed 302 or 303, inspect hops. If the creative is SIMID, open the IAB-style workbench for the handshake, then still run IMA if IMA is the player.",
            "Once the resolved tag is structurally sound, Google's inspector becomes much more valuable. At that point you are no longer asking a vague question like does this tag work. You are asking the sharper question does this standards-valid tag behave the way I expect in IMA HTML5.",
            "That sequence produces better debugging. It prevents player-specific noise from masking simple XML problems and prevents standards validation from being confused with runtime compatibility."
          ]
        },
        {
          "type": "code",
          "heading": "Recommended workflow when Google IMA is your target runtime",
          "language": "bash",
          "code": "# 1. Live tag URL: vastlint.org/tester/\n# 2. Wrapper hops: vastlint.org/inspect/\n# 3. SIMID handshake: iab-tech-lab-vast-tester.vastlint.org (independent fork)\n# 4. Resolved XML: vastlint.org/validate/\n# 5. If Google IMA HTML5 is the destination runtime, run the same resolved tag in Video Suite Inspector"
        },
        {
          "type": "list",
          "heading": "When VASTlint is the better first choice",
          "items": [
            "You need a neutral standards-first answer before anyone argues about player quirks.",
            "You are starting from a live VAST URL with wrappers and redirects, not a final XML payload.",
            "You need rule-level diagnostics, public fix guidance, and methodology you can cite internally.",
            "You want to validate tags in CI, inside an ad server, or inside an automated QA pipeline.",
            "You need an open-source workflow that can live outside a browser session.",
            "You need one baseline validator before comparing behavior across multiple SDKs or players."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "When Google's inspector should be the final check",
          "paragraphs": [
            "If Google IMA HTML5 is the actual production runtime, Google's inspector should still be in the workflow. Its value is not that it replaces standards validation or outclasses broad QA features. Its value is that it shows you what the IMA environment does with the tag after you already know the underlying XML is sound.",
            "That is the fair comparison. Google's tool is excellent at IMA runtime testing. VASTlint is better as the standards-derived front door into the whole debugging process and already covers the generic preview, tracking, click, and wrapper-debugging layer before you ever open IMA."
          ]
        },
        {
          "type": "resources",
          "heading": "Sources and related docs",
          "items": [
            {
              "label": "IMA HTML5 Video Suite Inspector",
              "href": "https://googleads.github.io/googleads-ima-html5/vsi/",
              "description": "Google's public inspector for testing how a VAST ad response behaves in the IMA HTML5 environment.",
              "source": "Google"
            },
            {
              "label": "IMA HTML5 support and compatibility",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/compatibility",
              "description": "Google's compatibility matrix and caveats for browsers, platforms, events, frameworks, and media features.",
              "source": "Google"
            },
            {
              "label": "Enable VPAID 2 JavaScript creatives",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Google's documentation describing VPAID 2 support boundaries and caveats in IMA HTML5.",
              "source": "Google"
            },
            {
              "label": "Review SIMID support",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/simid-support",
              "description": "Google's documentation describing the SIMID messages and behaviors IMA HTML5 supports or does not support.",
              "source": "Google"
            },
            {
              "label": "IAB-style VAST tester (SIMID studio)",
              "href": "https://iab-tech-lab-vast-tester.vastlint.org/",
              "description": "Independent workbench for SIMID handshake QA. Not an IAB Tech Lab product. Use this before you argue about IMA SIMID message support.",
              "source": "Community"
            },
            {
              "label": "VAST tag tester",
              "href": "/tester/",
              "description": "Fetch a live VAST URL, preview creative, inspect tracking and click URLs.",
              "source": "Tool"
            },
            {
              "label": "Google IMA SDK VAST validator guide",
              "href": "/guides/vast-google-ima-sdk/",
              "description": "vastlint's guide to the Google IMA SDK requirements, caveats, and troubleshooting flow.",
              "source": "Guide"
            },
            {
              "label": "Rule derivation methodology",
              "href": "/docs/methodology/",
              "description": "How VASTlint derives rules from IAB XSD schemas, normative prose, and related standards.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Fetch the live tag before you debug the player",
          "paragraph": "Start with the live tag URL on the tester, unwrap hops on the inspector, and use the IAB-style workbench for a SIMID handshake. Then move into Google IMA runtime testing with a cleaner signal.",
          "href": "/tester/",
          "label": "Test a live VAST tag URL"
        }
      ]
    },
    {
      "slug": "how-the-tracking-pixel-ecosystem-actually-works",
      "title": "How the Tracking Pixel Ecosystem Actually Works",
      "description": "Tracking pixels are not one thing. They sit inside a larger measurement and identity system that spans VAST, VMAP, ad registries, anti-fraud tooling, server-side beaconing, and public tracker catalogs. This is the practical map.",
      "publishedAt": "2026-05-22",
      "updatedAt": "2026-09-26",
      "author": "Alex Sekowski",
      "readingTime": "9 min read",
      "heroKicker": "Tracking pixel ecosystem",
      "tags": [
        "Tracking pixels",
        "VAST",
        "VMAP",
        "Measurement"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "A tracking pixel is the visible tip of a bigger system",
          "paragraphs": [
            "People talk about tracking pixels as if they were a single product category. They are not. A tracking pixel is usually just a URL call or beacon that records an event somewhere in the delivery chain: impression, quartile, click, completion, viewability, or a platform-specific diagnostic event.",
            "What matters in practice is the ecosystem around that URL. The pixel sits inside ad-serving specs such as VAST, break-planning formats such as VMAP, ad-server macros, measurement SDKs, server-side beaconing systems, creative identity registries, and anti-fraud layers that decide whether the event should be trusted.",
            "If you only look at the beacon itself, you miss the market structure that makes pixels valuable or misleading. The useful question is not just did the pixel fire. It is who generated it, under which standard, for which event, and whether the rest of the chain gives that event any credibility."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where pixels show up in the ad stack",
          "paragraphs": [
            "In video and CTV, the canonical home for event tracking is VAST. The standard defines [impression URLs, tracking events, error URLs, and click paths](https://pixellint.org/docs/vast-tracking-events-are-pixels/), along with verification resources and the XML structure that tells a player or intermediary what should be called and when.",
            "For multi-break programming, VMAP sits one level above that. Google Ad Manager describes VMAP as a standard way to define multiple ad breaks, where each break contains VAST ad tag URIs. The player or IMA SDK then requests each ad, follows redirects, chooses media, and fires the related tracking events. That is one reason troubleshooting often feels like debugging a call graph instead of a single tag.",
            "Outside video, similar beacon patterns exist across web analytics, affiliate attribution, email open tracking, fraud detection, and retail media measurement. The mechanics are comparable even when the transport or event names differ. A [tracking pixel](https://pixellint.org/docs/what-is-a-tracking-pixel/) is usually a very small reporting interface into a much larger workflow."
          ]
        },
        {
          "type": "list",
          "heading": "The main actor groups in the pixel ecosystem",
          "items": [
            "Publishers and app owners, who expose inventory and need impression, completion, and revenue reporting.",
            "Ad servers and SSPs, which traffic tags, apply macros, redirect requests, and often originate part of the measurement chain.",
            "DSPs and buyers, which need event callbacks for pacing, attribution, optimization, and fraud review.",
            "Measurement and verification vendors, which layer on viewability, attention, OM SDK, brand-safety, or invalid-traffic signals.",
            "Identity and registry providers, which help map the creative or transaction to a shared identifier instead of a vendor-local label.",
            "Privacy, browser, and platform gatekeepers, which increasingly decide which beacons are allowed to exist, persist, or remain trustworthy."
          ]
        },
        {
          "type": "code",
          "heading": "The pixel layer is usually simple XML hiding a complex chain",
          "language": "xml",
          "code": "<InLine>\n  <Impression><![CDATA[https://tracker.example.com/imp?cb=[CACHEBUSTING]]]> </Impression>\n  <Creatives>\n    <Creative>\n      <Linear>\n        <TrackingEvents>\n          <Tracking event=\"start\"><![CDATA[https://tracker.example.com/start?id=[ADID]]]> </Tracking>\n          <Tracking event=\"firstQuartile\"><![CDATA[https://tracker.example.com/q1?id=[ADID]]]> </Tracking>\n          <Tracking event=\"complete\"><![CDATA[https://tracker.example.com/complete?id=[ADID]]]> </Tracking>\n        </TrackingEvents>\n      </Linear>\n    </Creative>\n  </Creatives>\n</InLine>"
        },
        {
          "type": "paragraphs",
          "heading": "Registries matter because pixels need shared identity",
          "paragraphs": [
            "One reason the ecosystem gets messy is that the same creative, campaign, or placement can be named differently at every hop. That is why registries and shared identifiers matter. In VAST this often appears as UniversalAdId with an idRegistry field, which tells downstream systems which identifier namespace they are looking at.",
            "A concrete example is AD-ID, which describes itself as the advertising industry's ad registry. Whether or not every workflow uses AD-ID directly, the idea is important: pixels become more useful when the event can be reconciled to a recognized creative identity instead of an SSP-specific label or a spreadsheet nickname.",
            "Without a shared registry or stable identifier, tracking becomes a stitching problem. Teams spend time debating whether two beacon trails refer to the same creative rather than analyzing performance or fraud."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the market keeps moving away from browser-era assumptions",
          "paragraphs": [
            "The tracking-pixel ecosystem used to feel like a browser problem: drop a beacon, set a cookie, collect events, optimize. That picture is incomplete now. CTV, mobile apps, SSAI, privacy controls, and anti-fraud expectations have all changed what a pixel can realistically prove.",
            "IAB Tech Lab's VAST CTV Addendum 2024 is a good marker of that shift. It ties modern CTV implementation to ACIF support, Open Measurement, higher-resolution creative, and better compatibility across real TV environments. That is not just a formatting update. It reflects a market where the event log needs stronger operational context.",
            "The result is a more layered ecosystem. Pixels still matter, but they now sit beside ad registration, authenticated supply-path metadata, SDK measurement, device-level signals, and server-side reporting systems."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Client-side versus server-side beaconing changes the trust model",
          "paragraphs": [
            "A lot of teams still imagine the player firing every tracking URL directly. That still happens, but it is no longer the only model. Google Ad Manager's trafficking documentation explicitly distinguishes server-side beaconing, including an impression-pinging entity signal and the value ipe=ssb when the server sends impression beacons.",
            "That changes how you interpret the data. A server-originated beacon can improve reliability in some environments and make certain workflows possible in SSAI or constrained-player contexts. It also means a fired beacon may tell you more about infrastructure behavior than about what happened on a specific device surface.",
            "This is why modern measurement conversations are increasingly about layered evidence. The pixel is still useful, but now you also need to know whether the event came from the device, the player SDK, a server-side intermediary, or a verification partner."
          ]
        },
        {
          "type": "quote",
          "quote": "The pixel is the message. The ecosystem is the proof model.",
          "attribution": "vastlint field note"
        },
        {
          "type": "paragraphs",
          "heading": "Public tracker catalogs help explain the outside edge of the market",
          "paragraphs": [
            "If you want to understand how large and fragmented the beacon universe has become, public tracker catalogs are useful even when they are not ad-tech standards. Disconnect's tracker-protection repository, for example, maintains a categorized services.json dataset spanning categories such as Advertising, Analytics, Social, ConsentManagers, Anti-fraud, and multiple fingerprinting-related groups.",
            "That kind of public catalog is not a canonical registry for ad operations. It is better thought of as a market map compiled from the privacy and tracker-protection side. But it makes one thing very clear: the modern pixel ecosystem extends far beyond classic ad servers. The same page or app experience can involve advertising, analytics, attribution, consent, anti-fraud, and fingerprinting vendors all emitting or interpreting related signals.",
            "For operators, that means governance matters. The question is no longer only which tracking URL to place in the tag. It is which classes of trackers are entering the environment, which of them are essential, and how many of them can still be defended under privacy and performance constraints."
          ]
        },
        {
          "type": "list",
          "heading": "What a healthy pixel strategy looks like in 2026",
          "items": [
            "Keep VAST and VMAP event wiring clean so each event has a clear owner and reason to exist.",
            "Prefer stable creative identifiers and registries where available so event reconciliation is possible across vendors.",
            "Document whether critical beacons are client-side, SDK-mediated, or server-side beaconed.",
            "Treat verification, OM SDK, and anti-fraud signals as complementary evidence rather than assuming a fired pixel settles the question.",
            "Review third-party trackers as part of supply-path governance, not just implementation QA.",
            "Assume that privacy controls, browser limits, and app-platform changes will continue to narrow which historical pixel habits remain viable."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The practical takeaway",
          "paragraphs": [
            "The tracking pixel ecosystem works because simple event URLs are cheap, interoperable, and easy to distribute. It becomes confusing because those same URLs are asked to carry too much meaning on their own.",
            "If you want cleaner reporting, better fraud review, and fewer debates between buyers, sellers, and verification partners, the fix is not more pixels by default. The fix is better structure around them: standards-compliant tags, explicit measurement ownership, stable identifiers, and a realistic understanding of which systems are actually generating the evidence.",
            "That is the real market now. Pixels are still everywhere. They are just no longer the whole story."
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "VAST standards overview",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "IAB Tech Lab overview of VAST and the current family of video ad-serving specifications.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VAST CTV Addendum 2024 ready for implementation",
              "href": "https://iabtechlab.com/vast-ctv-addendum-2024-ready-for-implementation/",
              "description": "IAB Tech Lab summary of the CTV addendum, including ACIF, Open Measurement, high-resolution creative, and DSA icon support.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Create and use VMAP ad rules",
              "href": "https://support.google.com/admanager/answer/4539582",
              "description": "Google Ad Manager documentation explaining VMAP, multi-break structures, and how players request VAST ads and tracking events.",
              "source": "Google Ad Manager"
            },
            {
              "label": "AD-ID",
              "href": "https://www.ad-id.org/",
              "description": "The advertising industry's creative ID registry and naming system for campaign assets.",
              "source": "AD-ID"
            },
            {
              "label": "Disconnect tracking protection services catalog",
              "href": "https://github.com/disconnectme/disconnect-tracking-protection/blob/master/services.json",
              "description": "Public categorized tracker catalog spanning advertising, analytics, social, consent, anti-fraud, and fingerprinting groups.",
              "source": "Disconnect"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Inspect the chain behind the pixel",
          "paragraph": "Load a live tag, unwrap the redirects, and review the impression, quartile, click, error, and verification URLs before they become a reporting argument later.",
          "href": "/inspect/",
          "label": "Inspect a live VAST URL"
        }
      ]
    },
    {
      "slug": "tracking-pixels-wont-save-you-from-ctv-fraud",
      "title": "Tracking Pixels Won't Save You From CTV Fraud",
      "description": "A tracking pixel can confirm that a URL fired. In 2026, that is no longer the same thing as proving a real CTV impression happened. Recent IAB Tech Lab guidance makes the gap harder to ignore.",
      "publishedAt": "2026-05-20",
      "updatedAt": "2026-09-26",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Fraud and measurement",
      "tags": [
        "Ad fraud",
        "CTV",
        "Tracking pixels",
        "OM SDK"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "The old habit is to trust the pixel",
          "paragraphs": [
            "For years, a lot of video troubleshooting ended with the same question: did the impression pixel fire? If it did, teams moved on. If it did not, they dug into the tag. That habit made sense when the main problem was whether a browser or player called the URL it was given.",
            "That is not the whole problem anymore, especially in CTV. A fired pixel can prove that some system made a request. It does not, by itself, prove that a real TV app rendered a real ad on a real device for a real viewer.",
            "That distinction matters more in 2026 because the anti-fraud conversation in CTV has moved away from simple beacon counting and toward attested device signals, signed server-to-server messages, and clearer supply-path identity."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why this is suddenly a live issue again",
          "paragraphs": [
            "IAB Tech Lab's January 2026 standards update made the shift explicit. Its recommendation to implement OM SDK for CTV with Device Attestation is not just a measurement feature release. It is a response to device spoofing and weak trust signals in streaming environments.",
            "The same CTV Programmatic Guide is even more direct. It separates classic transparency tools such as ads.txt, sellers.json, SupplyChain, and ads.cert from the measurement layer, and then calls out Device Attestation as the answer to spoofed device claims. In other words: the ecosystem is treating a pixel fire as one signal among several, not as the final word.",
            "If you are still evaluating premium CTV delivery with a browser-era mindset, you are probably over-trusting logs that were never designed to settle fraud questions on their own."
          ]
        },
        {
          "type": "list",
          "heading": "What a pixel can tell you, and what it cannot",
          "items": [
            "It can tell you that a URL was requested at a point in the delivery chain.",
            "It can help you detect [missing events, malformed macros, HTTPS drift, and duplicate beacons](https://pixellint.org/docs/vast-tracking-events-are-pixels/), and catch broken partner wiring.",
            "It cannot prove that the device identity in the request was genuine.",
            "It cannot prove that the screen was on, the app was authentic, or the ad was actually viewable in a CTV runtime.",
            "It cannot tell you whether a server-side intermediary fabricated or replayed the beacon.",
            "It cannot replace signed transport, supply-path transparency, or attested measurement signals."
          ]
        },
        {
          "type": "code",
          "heading": "A modern tag still needs clean pixels, but not only pixels",
          "language": "xml",
          "code": "<InLine>\n  <Impression><![CDATA[https://tracker.example.com/imp?cb=[CACHEBUSTING]]]></Impression>\n  <Creatives>\n    <Creative>\n      <Linear>\n        <Duration>00:00:15</Duration>\n        <TrackingEvents>\n          <Tracking event=\"start\"><![CDATA[https://tracker.example.com/start]]></Tracking>\n          <Tracking event=\"complete\"><![CDATA[https://tracker.example.com/complete]]></Tracking>\n        </TrackingEvents>\n        <MediaFiles>\n          <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\">\n            <![CDATA[https://cdn.example.com/ads/spot-15s.mp4]]>\n          </MediaFile>\n        </MediaFiles>\n      </Linear>\n    </Creative>\n  </Creatives>\n  <AdVerifications>\n    <Verification vendor=\"measurement.example\">\n      <JavaScriptResource apiFramework=\"omid\"><![CDATA[https://verification.example.com/omid.js]]></JavaScriptResource>\n    </Verification>\n  </AdVerifications>\n</InLine>"
        },
        {
          "type": "paragraphs",
          "heading": "VAST is still where the weak signals leak in",
          "paragraphs": [
            "None of this makes VAST hygiene less important. It makes it more important. Fraud review gets worse when the tag is already sloppy. HTTP trackers, duplicated impressions, inconsistent quartile URLs, dead verification resources, and wrapper chains that hide who is calling what all make the evidence harder to trust.",
            "A bad tag creates two problems at once. First, it can directly break delivery or measurement. Second, it muddies the audit trail when someone later asks whether the discrepancy was fraud, a player issue, or just careless trafficking.",
            "That is why pixel QA and anti-fraud work should not sit in separate buckets anymore. If the tracker layer is noisy, your fraud analysis starts from compromised data."
          ]
        },
        {
          "type": "quote",
          "quote": "A pixel tells you a request happened. It does not tell you the impression was trustworthy.",
          "attribution": "vastlint field note"
        },
        {
          "type": "list",
          "heading": "What to review before you trust the measurement",
          "items": [
            "Validate every impression, quartile, error, click, and verification URL in the trafficked VAST, not just the sample XML from the vendor deck.",
            "Remove duplicate or contradictory trackers so one playback event does not create a noisy measurement trail.",
            "Require HTTPS everywhere, including tracking and verification resources, because mixed-content failures still create false debugging trails.",
            "Ask the seller or platform whether OM SDK for CTV is implemented and whether Device Attestation is part of the measurement path.",
            "Check whether server-to-server hops that matter to your reporting use signed protocols such as ads.cert Authenticated Connections.",
            "Reconcile campaign performance against post-IVT or post-SIVT numbers when the buying agreement supports that distinction, rather than treating raw counts as final truth."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The practical takeaway for ad ops teams",
          "paragraphs": [
            "Do not throw away pixels. You still need them, and you still need them to be clean. They remain one of the fastest ways to catch broken tags, missing macros, vendor misfires, and partner regressions before a campaign burns budget.",
            "But stop treating a fired pixel as a complete answer to fraud or quality questions in CTV. The recent standards work is pushing the market toward a layered trust model: transparent seller identity, authenticated transport, and attested measurement on the device side. That is the right model because the fraud is no longer limited to malformed XML. It lives in the claims around the XML too.",
            "If your workflow only inspects whether the beacon fired, you are checking the easiest signal to fake and ignoring the ones the industry is finally standardizing to trust."
          ]
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "VAST tag testing",
              "href": "/docs/vast-tag-testing/",
              "description": "How to inspect impression, quartile, click, and verification URLs before launch.",
              "source": "Docs"
            },
            {
              "label": "Validate VAST XML",
              "href": "/docs/validate-vast-xml/",
              "description": "The baseline XML, URL, and tracking checks that should happen before trafficking.",
              "source": "Docs"
            },
            {
              "label": "Common VAST errors",
              "href": "/docs/common-vast-errors/",
              "description": "The low-level mistakes that often turn a fraud investigation into a measurement mess.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "Resolve to Update Your Tech Lab Standards in 2026",
              "href": "https://iabtechlab.com/resolve-to-update-your-tech-lab-standards-in-2026/",
              "description": "IAB Tech Lab's 2026 standards note highlighting OM SDK for CTV with Device Attestation as a priority.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "CTV Programmatic Guide",
              "href": "https://iabtechlab.com/standards/advanced-tv/ctv-programmatic-guide/",
              "description": "The current guide mapping CTV fraud, measurement, ads.txt, sellers.json, ads.cert, and Device Attestation to specific use cases.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Ads.cert",
              "href": "https://iabtechlab.com/standards/ads-cert/",
              "description": "Overview of authenticated server-to-server protocols for origin authentication and tamper resistance in advertising flows.",
              "source": "IAB Tech Lab"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Inspect the tracker layer before someone argues about fraud",
          "paragraph": "Use the inspector to unwrap the live chain, review every tracking URL, and clean up obvious evidence problems before the campaign goes into market.",
          "href": "/inspect/",
          "label": "Inspect a live VAST URL"
        }
      ]
    },
    {
      "slug": "ctv-has-graduated-your-vast-tags-need-to-grow-up-too",
      "title": "CTV Has Graduated. Your VAST Tags Need to Grow Up Too",
      "description": "A recent IAB Tech Lab note on CTV maturity is the right cue for ad ops teams: if connected TV is now infrastructure, VAST tags have to carry production-grade metadata, measurement, and latency discipline.",
      "publishedAt": "2026-05-12",
      "updatedAt": "2026-05-12",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "CTV maturity",
      "tags": [
        "CTV",
        "VAST 4.3",
        "SSAI",
        "Live streaming"
      ],
      "featured": false,
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Maturity changes the QA bar",
          "paragraphs": [
            "In a recent IAB Tech Lab article, Brad Pipkin argues that CTV has moved from naming debates into implementation, measurement, and live-event execution. That framing matters for anyone shipping VAST tags because the failures that remain are less about whether XML loads and more about whether the tag behaves predictably across SSAI, verification, and device-specific playback.",
            "When a channel matures, tolerance for ambiguous signaling drops. Buyers want consistent classification, sellers need interoperable delivery, and measurement partners expect richer metadata than a bare-bones inline creative.",
            "That means a VAST tag built for browser-era QA is no longer enough for premium streaming inventory in 2026."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What CTV maturity means inside the tag",
          "paragraphs": [
            "The recent IAB piece points to VAST 4.3, OpenRTB 2.6, AdCOM, OM SDK for CTV, and live-event guidance as part of the stack that turns definitions into systems. In practice, VAST is where several of those expectations become concrete: asset signaling, verification behavior, SSAI support, and the metadata the player and measurement layer depend on.",
            "The VAST standards page tells the same story in version-history form. The current CTV addendum is not cosmetic. It explicitly calls out ACIF support for ad registration, icons that support DSA compliance, and the need for higher-resolution creative on larger screens. That is the difference between a tag that merely parses and a tag that is ready for modern TV inventory.",
            "If your tag still relies on thin metadata, deep wrapper chains, legacy interactivity, or media assets chosen for web convenience instead of device reliability, you are carrying pre-maturity assumptions into a mature environment."
          ]
        },
        {
          "type": "list",
          "heading": "The fields and behaviors worth tightening now",
          "items": [
            "Prefer VAST 4.x or 4.3 responses when the supply path supports them, especially for SSAI and modern measurement expectations.",
            "Include UniversalAdId and other creative metadata that make cross-platform reporting and traceability easier.",
            "Keep wrapper chains short enough for real CTV latency budgets, not just spec-maximum hop counts.",
            "Require HTTPS across media, tracking, error, and verification URLs.",
            "Provide creative assets that are actually sized and encoded for large-screen playback, not just browser-safe defaults.",
            "Ship at least one CTV-safe MP4 rendition and provide mezzanine coverage where premium or SSAI paths expect it.",
            "Audit interactive assumptions so SIMID or native controls are used where appropriate and legacy VPAID dependencies are removed.",
            "Check pod and live-event behavior explicitly because concurrency stress exposes weak redirects and slow third-party beacons first."
          ]
        },
        {
          "type": "code",
          "heading": "A cleaner starting point for a modern CTV creative",
          "language": "xml",
          "code": "<InLine>\n  <Creatives>\n    <Creative sequence=\"1\" adId=\"spring-launch\">\n      <UniversalAdId idRegistry=\"Ad-ID\">ABCD1234000H</UniversalAdId>\n      <Linear>\n        <Duration>00:00:15</Duration>\n        <MediaFiles>\n          <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\" bitrate=\"4500\">\n            <![CDATA[https://cdn.example.com/ads/spring-launch-15s.mp4]]>\n          </MediaFile>\n          <Mezzanine delivery=\"streaming\" type=\"video/mp4\" width=\"1920\" height=\"1080\">\n            <![CDATA[https://cdn.example.com/ads/spring-launch-master.mp4]]>\n          </Mezzanine>\n        </MediaFiles>\n      </Linear>\n    </Creative>\n  </Creatives>\n</InLine>"
        },
        {
          "type": "paragraphs",
          "heading": "The partner questions are now technical questions",
          "paragraphs": [
            "The new buyer guide from IAB Tech Lab and the WFA is useful because it turns CTV diligence into a standards checklist. Buyers are told to ask whether providers actually support the standards they claim to support, from OM SDK to the Forecasting API, and whether they can signal what counts as live inventory accurately.",
            "Translate that into VAST review and the implications are direct. You need to know whether measurement survives the real playback path, whether the provider distinguishes live from VOD correctly, whether pod behavior and forecasting match how the campaign will be sold, and whether the ad formats they promise are backed by a creative package your tag can actually deliver.",
            "That is a better editorial lens for VAST QA in 2026: stop asking only whether the XML is valid and start asking whether the tag matches the transaction, the measurement plan, and the player environment the provider is putting in market."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Live streaming is where shortcuts surface",
          "paragraphs": [
            "The same IAB post highlights live streaming as the place where CTV starts meeting broadcast-level expectations. It calls out fill rates, latency risk, forecasting, bandwidth pressure, and ad pod execution as the new pressure points. That is exactly where VAST shortcuts become expensive.",
            "A long wrapper chain, slow verification call, or missing high-quality asset may be tolerated in low-volume QA and then fail under live concurrency.",
            "If you sell sports, tentpole entertainment, or premium news, treat live-event traffic as a separate launch class. The acceptable tag is the one that resolves quickly, measures cleanly, and renders on the real device mix under pressure."
          ]
        },
        {
          "type": "quote",
          "quote": "CTV maturity does not demand fancier XML. It demands fewer hidden assumptions between request, response, player, and measurement.",
          "attribution": "vastlint operations note"
        },
        {
          "type": "list",
          "heading": "A publish-today review before the next campaign goes live",
          "items": [
            "Resolve the full wrapper chain and record actual hop count and per-hop latency.",
            "Confirm final media choices against the device classes you actually serve, not just desktop playback.",
            "Ask the provider how it signals live inventory, where OM measurement runs, and what standards-based features are active on the real playback path.",
            "Review verification, tracking, and error URLs for HTTPS and partner stability.",
            "Make sure creative IDs and metadata match how the campaign will be measured downstream.",
            "Re-run the check on the trafficked line item, not only the partner sample tag."
          ]
        },
        {
          "type": "resources",
          "heading": "Related guides on vastlint",
          "items": [
            {
              "label": "VAST Wrapper Chains: How They Work, Limits & Debugging",
              "href": "/guides/vast-wrapper-chains/",
              "description": "Why practical redirect budgets matter more on TV devices and during live events.",
              "source": "Guide"
            },
            {
              "label": "VAST XML for Google IMA SDK",
              "href": "/guides/vast-google-ima-sdk/",
              "description": "How one of the most common player stacks interprets wrappers, media files, and runtime events.",
              "source": "Guide"
            },
            {
              "label": "VAST XML for Roku RAF",
              "href": "/guides/vast-roku-raf/",
              "description": "Roku-specific delivery assumptions that often expose weak VAST chains first.",
              "source": "Guide"
            },
            {
              "label": "VAST XML for Amazon Fire TV",
              "href": "/guides/vast-amazon-fire-tv/",
              "description": "Fire TV runtime and format details that matter once CTV traffic becomes operationally strict.",
              "source": "Guide"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Validate the tag before CTV traffic does it for you",
          "paragraph": "Run the validator for a fast XML pass, then inspect the full wrapper chain so live-event and device-specific failures show up before launch day.",
          "href": "/inspect/",
          "label": "Inspect a live VAST URL"
        }
      ]
    },
    {
      "slug": "why-ctv-vast-tags-fail-after-qa",
      "title": "Why CTV VAST Tags Still Fail After QA",
      "description": "The tags that pass a quick validator pass in the browser but still collapse on real TV devices usually break on wrapper depth, codec assumptions, HTTPS drift, or missing mezzanine expectations. This is the checklist that catches the expensive misses.",
      "publishedAt": "2026-05-10",
      "updatedAt": "2026-05-11",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "CTV delivery",
      "tags": [
        "CTV",
        "SSAI",
        "VAST QA",
        "Wrapper chains"
      ],
      "featured": false,
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Passing validation is not the same as passing delivery",
          "paragraphs": [
            "A normal XML validator can tell you whether the tag is structurally valid. It cannot tell you whether the fourth wrapper in a chain times out on a Samsung panel, whether the MP4 is encoded in a way a Roku box will reject, or whether a buyer-side HTTPS check will silently zero-fill the impression.",
            "That is why CTV failures often look random in launch week. The tag technically works, but the player environment is stricter than the test harness you used before trafficking.",
            "The IAB Tech Lab's recent VAST 4.3 and CTV addendum work is a good reminder that connected TV is not just browser video on a bigger screen. Resolution expectations, measurement behavior, asset handling, and device runtimes all matter more."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why browser QA misses TV-specific breakpoints",
          "paragraphs": [
            "Desktop validation usually happens on fast office networks, modern browsers, and player stacks that tolerate redirect latency. Real CTV traffic lands on constrained consumer networks, device SDKs with tighter wrapper budgets, and native playback engines that are much less forgiving about codecs and HTTPS drift.",
            "That gap explains why a tag can pass basic QA on Friday and underdeliver on Monday. The XML did not change. The execution environment did."
          ]
        },
        {
          "type": "list",
          "heading": "The failures that show up first in production",
          "items": [
            "Wrapper chains that resolve eventually on a desktop connection but exceed the practical hop budget on a TV device.",
            "Media files that are legal VAST but not a CTV-safe encoding profile for the device or SDK in play.",
            "HTTP tracking and creative URLs that survive QA but are blocked when the device runtime enforces HTTPS only.",
            "VPAID or other interactive assumptions that still appear in a third-party response long after the receiving platform stopped accepting them.",
            "Missing mezzanine or incomplete metadata in environments that expect a richer asset package for SSAI or premium CTV delivery.",
            "Player-specific requirements such as Roku RAF measurement handling or Google IMA wrapper limits that were never exercised in the original test harness."
          ]
        },
        {
          "type": "quote",
          "quote": "Most CTV outages are not caused by a broken root document. They are caused by a chain of individually small assumptions that only fail when the real device is in the loop.",
          "attribution": "vastlint field note"
        },
        {
          "type": "code",
          "heading": "A safer media section for premium TV inventory",
          "language": "xml",
          "code": "<Linear>\n  <Duration>00:00:15</Duration>\n  <MediaFiles>\n    <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1920\" height=\"1080\" bitrate=\"4500\">\n      <![CDATA[https://cdn.example.com/ads/brand-15s-h264-aac.mp4]]>\n    </MediaFile>\n    <Mezzanine delivery=\"streaming\" type=\"video/mp4\" width=\"1920\" height=\"1080\">\n      <![CDATA[https://cdn.example.com/ads/brand-15s-master.mp4]]>\n    </Mezzanine>\n  </MediaFiles>\n</Linear>"
        },
        {
          "type": "list",
          "heading": "A practical CTV preflight before launch",
          "items": [
            "Resolve the full wrapper chain and count real hops, not just the redirects visible in the first partner handoff.",
            "Confirm that every URL in the chain is HTTPS, including impressions, errors, click trackers, and companion assets.",
            "Verify that at least one MP4 H.264 asset is available for device classes that do not tolerate web-oriented encodes.",
            "Check whether the receiving stack expects mezzanine, higher-resolution creative, or extra metadata for SSAI and premium CTV paths.",
            "Reject any path that still depends on VPAID when the destination is tvOS, Fire TV, Roku, webOS, or another CTV runtime.",
            "Test on the actual player class that will serve the campaign, not just a browser inspector or desktop sample app."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Match QA to the actual receiving stack",
          "paragraphs": [
            "Before launch, validate the raw XML, then inspect the live wrapper chain, then check the receiving player class. Google IMA on web, Google IMA on tvOS, Roku RAF, and server-side stitched playback each fail differently.",
            "For example, Google IMA commonly makes teams think in terms of a four-hop wrapper ceiling, while Roku RAF forces a second conversation about practical timeout budgets, measurement beacons, and how ads are rendered in the actual device runtime.",
            "If the campaign matters, your launch gate should be player-specific, not just schema-specific. That is the difference between catching the expensive misses early and learning about them from underdelivery after launch."
          ]
        },
        {
          "type": "resources",
          "heading": "Related guides on vastlint",
          "items": [
            {
              "label": "VAST Wrapper Chains: How They Work, Limits & Debugging",
              "href": "/guides/vast-wrapper-chains/",
              "description": "Platform wrapper limits, followAdditionalWrappers behavior, and why extra hops quietly kill delivery.",
              "source": "Guide"
            },
            {
              "label": "VAST XML for Google IMA SDK",
              "href": "/guides/vast-google-ima-sdk/",
              "description": "What IMA expects across web, mobile, and CTV, including wrapper limits and VPAID policy.",
              "source": "Guide"
            },
            {
              "label": "VAST XML for Roku RAF",
              "href": "/guides/vast-roku-raf/",
              "description": "Roku-specific constraints around wrapper timing, media formats, and tracking behavior.",
              "source": "Guide"
            },
            {
              "label": "VAST XML for Apple tvOS",
              "href": "/guides/vast-apple-tvos/",
              "description": "How tvOS behaves when playback runs through the Google IMA SDK for tvOS.",
              "source": "Guide"
            },
            {
              "label": "VAST XML for Amazon Fire TV",
              "href": "/guides/vast-amazon-fire-tv/",
              "description": "Fire TV format, HTTPS, and runtime assumptions that often cause launch-week regressions.",
              "source": "Guide"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "Digital Video Ad Serving Template (VAST)",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The official IAB Tech Lab overview and version history for VAST, including VAST 4.3.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VAST CTV Addendum 2024",
              "href": "https://iabtechlab.com/wp-content/uploads/2024/07/VAST-CTV-Addendum-2024-FINAL.pdf",
              "description": "The CTV addendum covering newer creative expectations, device-oriented support, and CTV-specific updates.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Integrating the Roku Advertising Framework",
              "href": "https://developer.roku.com/en-gb/docs/developer-program/advertising/integrating-roku-advertising-framework.md",
              "description": "Roku's guide to client-side and server-side ad insertion, tracking, and RAF-specific implementation details.",
              "source": "Roku Developer"
            },
            {
              "label": "Set up the IMA SDK",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/get-started",
              "description": "Google's IMA setup guide and runtime model for requesting ads, managing ad playback, and handling events.",
              "source": "Google IMA"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Run the tag before it burns a week of delivery",
          "paragraph": "Use the validator for a fast structural check, then use the inspector to follow every wrapper hop and spot the CTV-specific breakpoints before the campaign goes live.",
          "href": "/inspect/",
          "label": "Inspect a wrapper chain"
        }
      ]
    },
    {
      "slug": "vast-4-3-launch-checklist-for-gam-and-ima",
      "title": "A VAST 4.3 Launch Checklist for Google Ad Manager and IMA",
      "description": "If the tag is going through GAM and the final playback path is IMA, most launch mistakes happen in the handoff: wrapper depth, parameter hygiene, HTTPS assets, and assumptions about deprecated interactive formats.",
      "publishedAt": "2026-05-08",
      "updatedAt": "2026-05-11",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "GAM + IMA",
      "tags": [
        "Google Ad Manager",
        "IMA SDK",
        "VAST 4.3",
        "Launch QA"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Treat GAM as one more wrapper in your budget",
          "paragraphs": [
            "Teams still lose time by counting only the third-party wrappers they can see. In many trafficking setups, GAM adds its own wrapper layer before the IMA SDK resolves the rest of the chain. That means your practical budget is smaller than the tag owner thinks it is.",
            "If you hand off a tag that already depends on several redirects, you are choosing latency and risk before the player ever sees an inline creative.",
            "That is the operational reason to inspect the full path as it will run in production, not just the vendor-supplied URL in isolation."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Parameter hygiene is part of delivery, not paperwork",
          "paragraphs": [
            "Google Ad Manager's own help docs separate required parameters from programmatic and recommended parameters for a reason. Missing values like correlator, description_url, env, gdfp_req, iu, output, sz, unviewed_position_start, and url are not documentation trivia. They shape whether the request is understood correctly and whether measurement and policy expectations are met.",
            "For programmatic and OTT traffic, parameters like plcmt, vpa, vpmute, ott_placement, omid_p, and vid_d become part of launch quality too. Teams often call a tag valid while still shipping a request that is incomplete for the actual inventory type.",
            "If the last mile is Google IMA, the runtime contract matters as much as the URL. IMA needs a correctly sized ad container, sane lifecycle handling, and ad requests that match the player context you are actually shipping."
          ]
        },
        {
          "type": "list",
          "heading": "What to verify before launch",
          "items": [
            "The request will stay within a four-hop total wrapper budget once GAM is included.",
            "Every asset and tracking URL is HTTPS and resolves cleanly from the target environment.",
            "The media files are native video assets, not legacy VPAID dependencies hiding in the chain.",
            "UniversalAdId and other VAST 4.x metadata are present where downstream buying and reporting expect them.",
            "The request parameters are correct for the actual platform, especially when the destination is CTV or app inventory.",
            "The destination player handles pause, resume, resize, and non-linear behavior the way IMA expects instead of leaving those cases to chance.",
            "The final inspected chain is the same one your operators think they trafficked."
          ]
        },
        {
          "type": "code",
          "heading": "A cleaner request shape for web or CTV trafficking",
          "language": "text",
          "code": "https://pubads.g.doubleclick.net/gampad/ads?\n  env=instream&\n  gdfp_req=1&\n  iu=/6062/example/video&\n  output=xml_vast4&\n  sz=1920x1080&\n  description_url=https%3A%2F%2Fpublisher.example%2Fshows%2Fdemo&\n  url=https%3A%2F%2Fpublisher.example%2Fepisode%2F123&\n  unviewed_position_start=1&\n  plcmt=1&\n  vpa=auto&\n  vpmute=0&\n  omid_p=example-player&\n  correlator=1234567890"
        },
        {
          "type": "paragraphs",
          "heading": "Remember the IMA runtime contract",
          "paragraphs": [
            "Google's own IMA guidance is clear on the operating model: keep one AdsLoader for the lifecycle of the page or app view, build the AdDisplayContainer correctly, listen for ADS_MANAGER_LOADED and AD_ERROR, and wire CONTENT_PAUSE_REQUESTED and CONTENT_RESUME_REQUESTED so content playback behaves correctly around ad breaks.",
            "That sounds basic, but it is where many launches still regress. A perfect VAST response cannot save an integration that never resizes the AdsManager, mishandles non-linear ads, or starts playback outside the user-action constraints of the platform.",
            "This is also why browser-only validation is not enough. The URL shape, the VAST payload, and the receiving runtime have to agree."
          ]
        },
        {
          "type": "list",
          "heading": "Where teams still regress on VAST 4.x",
          "items": [
            "Serving VPAID through a path that ultimately lands on mobile or CTV IMA where it is blocked anyway.",
            "Assuming GAM parameters can be copied between web, app, and OTT without checking the implementation-specific requirements.",
            "Leaving UniversalAdId, OMID context, or measurement-related metadata inconsistent across trafficking variants.",
            "Treating it loads in the browser sample player as equivalent to a real production validation step.",
            "Skipping a final wrapper inspection after the trafficked line item is actually live."
          ]
        },
        {
          "type": "resources",
          "heading": "Related guides on vastlint",
          "items": [
            {
              "label": "VAST XML for Google Ad Manager",
              "href": "/guides/vast-google-ad-manager/",
              "description": "GAM wrapper behavior, parameter coverage, and trafficking-specific VAST guidance.",
              "source": "Guide"
            },
            {
              "label": "VAST XML for Google IMA SDK",
              "href": "/guides/vast-google-ima-sdk/",
              "description": "The player-side expectations that determine whether a trafficked tag will actually render.",
              "source": "Guide"
            },
            {
              "label": "VAST Wrapper Chains: How They Work, Limits & Debugging",
              "href": "/guides/vast-wrapper-chains/",
              "description": "Why GAM should be counted as part of your real redirect budget.",
              "source": "Guide"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "VAST ad tag parameters for web",
              "href": "https://support.google.com/admanager/answer/10655276",
              "description": "Google Ad Manager's required, programmatic, and recommended parameters for web VAST implementations.",
              "source": "Google Ad Manager"
            },
            {
              "label": "Set up the IMA SDK",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/get-started",
              "description": "Google's reference workflow for building the ad container, AdsLoader, AdsManager, and playback lifecycle.",
              "source": "Google IMA"
            },
            {
              "label": "Digital Video Ad Serving Template (VAST)",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The official spec landing page and version history for VAST 2.0 through 4.3.",
              "source": "IAB Tech Lab"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Validate before trafficking",
          "paragraph": "Use the main validator for a fast pass over the XML before the tag reaches GAM or the IMA SDK, then keep the inspector for the final wrapper-chain check.",
          "href": "/validate/",
          "label": "Open the validator"
        }
      ]
    },
    {
      "slug": "reduce-wrapper-chain-revenue-loss-before-launch",
      "title": "How to Reduce Wrapper-Chain Revenue Loss Before Launch",
      "description": "Wrapper chains do not fail only when they hit a hard limit. They lose money earlier through latency, redirect fragility, and inconsistent tracking behavior. A shorter chain is not just cleaner engineering. It is better economics.",
      "publishedAt": "2026-05-05",
      "updatedAt": "2026-05-11",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Wrapper chains",
      "tags": [
        "Wrapper chains",
        "Revenue recovery",
        "Latency",
        "Ad ops"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Four hops is not the real threshold",
          "paragraphs": [
            "Ad teams often talk about wrapper depth as if there is a single safe line. In reality, commercial damage starts before the formal limit. Each additional hop adds one more network dependency, one more timeout surface, and one more place where tracking can diverge from the final inline response.",
            "By the time the player returns a visible error, the chain has already been leaking opportunity.",
            "This is why the formal wrapper maximum in a spec or SDK should be treated as the cliff edge, not the planning target."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why wrapper chains leak money before they fail",
          "paragraphs": [
            "Every redirect adds latency to time-to-first-frame. On consumer networks and CTV devices that extra second or two is enough to lower fill, increase abandonment, or push the impression into a timeout bucket that never becomes revenue.",
            "Extra hops also make outages harder to attribute. When one partner in the middle of the chain starts returning intermittent 5xx responses, the publisher usually feels it first as underdelivery, not as a neat root-cause report.",
            "Even when the ad finally resolves, longer chains create more opportunities for impression, click, and quartile tracking to drift from the final rendered asset. That affects reporting confidence and partner trust."
          ]
        },
        {
          "type": "list",
          "heading": "What a shorter chain buys you",
          "items": [
            "Faster time-to-first-frame for video ad playback.",
            "Less variance across consumer networks, especially on connected TV devices.",
            "Fewer third-party outages that manifest as unexplained underdelivery.",
            "Cleaner debugging because the failing partner is easier to isolate.",
            "Better odds that impression, click, and quartile tracking remain consistent across the chain."
          ]
        },
        {
          "type": "code",
          "heading": "A simple partner review frame",
          "language": "text",
          "code": "If this partner adds another redirect, ask three questions:\n1. Does it add unique demand or measurement value?\n2. Can the same result be achieved in one hop less?\n3. Has the final chain been tested on the actual receiving player?"
        },
        {
          "type": "list",
          "heading": "What to instrument before launch",
          "items": [
            "Total wrapper depth and which partner owns each hop.",
            "Time spent resolving each redirect, not just the total time at the end.",
            "Final media MIME type, bitrate, and dimensions so player compatibility issues surface early.",
            "Any 3xx, 4xx, or 5xx behavior in intermediate redirects that would be invisible in a one-pass validator.",
            "Tracking URLs that downgrade to HTTP or point to brittle third-party domains.",
            "Whether the trafficked line item changes the chain shape relative to the vendor sample URL."
          ]
        },
        {
          "type": "quote",
          "quote": "Wrapper depth is not just a spec issue. It is a compounding risk multiplier across latency, uptime, and reporting confidence.",
          "attribution": "vastlint operations note"
        },
        {
          "type": "paragraphs",
          "heading": "When to accept another redirect anyway",
          "paragraphs": [
            "Some extra hops are commercially justified. A redirect that genuinely adds incremental demand, critical measurement, or marketplace access may be worth keeping. But it should be defended with evidence, not habit.",
            "The right operating rule is simple: every extra hop has to earn its place. If it cannot explain the revenue or control value it adds, cut it before launch rather than debugging it after underdelivery shows up in pacing."
          ]
        },
        {
          "type": "resources",
          "heading": "Related guides on vastlint",
          "items": [
            {
              "label": "VAST Wrapper Chains: How They Work, Limits & Debugging",
              "href": "/guides/vast-wrapper-chains/",
              "description": "A deeper look at wrapper structure, platform limits, and debugging strategy.",
              "source": "Guide"
            },
            {
              "label": "VAST XML for Google Ad Manager",
              "href": "/guides/vast-google-ad-manager/",
              "description": "Useful if GAM is one of the layers consuming part of your real wrapper budget.",
              "source": "Guide"
            },
            {
              "label": "VAST XML for Google IMA SDK",
              "href": "/guides/vast-google-ima-sdk/",
              "description": "How one of the most common player stacks behaves when chains get too deep or too slow.",
              "source": "Guide"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "Digital Video Ad Serving Template (VAST)",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The spec family behind wrapper behavior, inline responses, and version history.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VAST ad tag parameters for web",
              "href": "https://support.google.com/admanager/answer/10655276",
              "description": "Helpful for spotting request-shape issues that compound wrapper-chain problems in live delivery.",
              "source": "Google Ad Manager"
            },
            {
              "label": "Set up the IMA SDK",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/get-started",
              "description": "Useful for understanding how the player side handles ad loading, lifecycle events, and failures.",
              "source": "Google IMA"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Follow the whole chain, not just the first response",
          "paragraph": "Paste a VAST URL into the inspector and walk every hop before the campaign launches. That is where the hidden loss usually lives.",
          "href": "/inspect/",
          "label": "Inspect a live VAST URL"
        }
      ]
    },
    {
      "slug": "how-to-validate-vast-trackers-before-launch",
      "title": "How to Validate VAST Trackers Before Launch",
      "description": "Tracker validation is not just opening a pixel URL in a browser. This is the practical pre-launch review for impression, quartile, click, and error trackers across wrappers, macros, HTTPS, and player context.",
      "publishedAt": "2026-06-05",
      "updatedAt": "2026-09-26",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "Tracker validation",
      "tags": [
        "Tracking pixels",
        "VAST QA",
        "Ad ops",
        "Wrapper chains"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "Validating trackers means confirming that the right URL is wired to the right playback event in the live VAST response, with valid syntax, HTTPS, sane macros, and no environment drift. Opening one [pixel URL](https://pixellint.org/docs/template-vs-fired-urls/) in a browser or running curl against it is not enough. That only tells you an endpoint responds.",
            "The public docs around VAST and VMAP make the control flow clear: the player or player SDK follows redirects, fetches VAST, chooses media, and responds with tracking events. That is why serious tracker QA starts from the live tag and the real wrapper chain, not from a vendor slide deck or a trafficker's spreadsheet."
          ]
        },
        {
          "type": "list",
          "heading": "What a clean tracker layer should prove before launch",
          "items": [
            "Every Impression, Tracking, ClickThrough, ClickTracking, and Error URI is syntactically valid and HTTPS-safe for the target environment.",
            "Event coverage matches the actual measurement plan: impression, start, quartiles, complete, click, and error where the buyer, seller, or verification workflow expects them.",
            "Macros are either supported by the serving stack or already resolved before the tag goes live.",
            "The trackers point at the right owner and environment, so staging domains, old campaign IDs, or mixed vendors are not hiding in the XML.",
            "Wrapper-added trackers are understood and expected, instead of being mistaken for accidental duplication.",
            "Error paths exist on wrappers, with [ERRORCODE] where appropriate, so failed chains leave evidence instead of silence."
          ]
        },
        {
          "type": "code",
          "heading": "A tracker block should be specific, not merely present",
          "language": "xml",
          "code": "<InLine>\n  <Impression><![CDATA[https://tracker.example.com/imp?cb=[CACHEBUSTING]]]></Impression>\n  <Error><![CDATA[https://tracker.example.com/error?code=[ERRORCODE]&cb=[CACHEBUSTING]]]></Error>\n  <Creatives>\n    <Creative>\n      <Linear>\n        <TrackingEvents>\n          <Tracking event=\"start\"><![CDATA[https://tracker.example.com/start?id=[ADID]]]></Tracking>\n          <Tracking event=\"firstQuartile\"><![CDATA[https://tracker.example.com/q1?id=[ADID]]]></Tracking>\n          <Tracking event=\"complete\"><![CDATA[https://tracker.example.com/complete?id=[ADID]]]></Tracking>\n        </TrackingEvents>\n        <VideoClicks>\n          <ClickThrough><![CDATA[https://brand.example.com/landing]]></ClickThrough>\n          <ClickTracking><![CDATA[https://tracker.example.com/click?id=[ADID]]]></ClickTracking>\n        </VideoClicks>\n      </Linear>\n    </Creative>\n  </Creatives>\n</InLine>"
        },
        {
          "type": "paragraphs",
          "heading": "Start with the live tag, not the sample XML",
          "paragraphs": [
            "This is where teams waste time. The XML attached to an email is rarely the exact response the player will see in production. Ad servers append macros, wrappers add their own Impression and Error URLs, and VMAP or SDK-driven flows request child VAST tags at playback time.",
            "If you validate only the sample inline snippet, you can miss the URLs that actually fire in market. The practical unit of review is the trafficked tag URL, the resolved XML, and the full wrapper chain that sits between them."
          ]
        },
        {
          "type": "list",
          "heading": "The checks that catch most tracker problems quickly",
          "items": [
            "Malformed URLs: missing protocol, illegal spaces, broken escaping, or query strings that will fail once the player tries to request them.",
            "HTTP drift: trackers or click destinations that still use HTTP in an HTTPS-only workflow.",
            "[Unresolved or unsupported macros](https://pixellint.org/docs/ad-server-macros/): placeholder tokens that the current ad server or SDK will not replace.",
            "Duplicate or contradictory events: two copies of the same vendor beacon for one event, or mixed staging and production endpoints for the same campaign.",
            "Missing wrapper error tracking: no Error URL means no useful evidence when a redirect chain fails or times out.",
            "Thin event coverage: tags that technically parse but omit events the reporting workflow depends on."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Wrapper chains change the tracker count",
          "paragraphs": [
            "Wrapper chains are where tracker validation stops being a simple checklist. Each wrapper can contribute its own Impression, Error, and TrackingEvents URLs. By the time the inline ad resolves, the player can be holding a stack of trackers from every hop plus the final creative.",
            "That means four impression URLs in a multi-hop chain may be correct, while two nearly identical start trackers from the same vendor may be sloppy trafficking. Validation is not about minimizing the number of pixels by default. It is about distinguishing expected accumulation from accidental noise."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Error tracking deserves first-class QA",
          "paragraphs": [
            "A lot of teams review impression and quartile trackers carefully, then treat Error as optional. That is backwards. When a wrapper chain breaks, the Error URL is often the only structured clue you get.",
            "If wrappers do not carry an Error URL with the [ERRORCODE] macro, chain failures become underdelivery with no audit trail. That is one of the cheapest fixes to catch before launch and one of the most expensive omissions to discover after launch."
          ]
        },
        {
          "type": "list",
          "heading": "A practical pre-launch workflow",
          "items": [
            "Paste the live tag URL into the tester first so you can review resolved tracking URLs, click paths, HTTP drift, and obvious macro issues in one place.",
            "Use the inspector on any wrapped response so you can see hop count, accumulated trackers, and which party added which beacon.",
            "Validate the resolved XML separately to catch malformed URIs, empty elements, and spec-level issues that get buried inside wrapper debugging.",
            "Run one player-specific check on the real receiving stack, because browser validation does not prove the same tracker behavior on CTV, mobile SDKs, or SSAI paths.",
            "Save the final tracker inventory with ownership notes so measurement disputes do not start with guesswork later."
          ]
        },
        {
          "type": "quote",
          "quote": "A tracker is valid when the right system fires the right URL for the right event in the right environment.",
          "attribution": "vastlint field note"
        },
        {
          "type": "paragraphs",
          "heading": "Validation is wiring QA, not proof of trust",
          "paragraphs": [
            "This is the line that keeps the article distinct from fraud conversations. Validating trackers tells you whether the measurement layer is wired coherently before launch. It does not by itself prove that the eventual impression was trustworthy.",
            "But that distinction is exactly why tracker validation matters. If the tracker layer is malformed, duplicated, or missing error instrumentation, every later conversation about pacing, discrepancies, or fraud starts from noisy evidence."
          ]
        },
        {
          "type": "resources",
          "heading": "Related guides on vastlint",
          "items": [
            {
              "label": "VAST tag testing",
              "href": "/docs/vast-tag-testing/",
              "description": "How to test a live VAST tag, inspect trackers, review click paths, and catch macro or HTTPS issues before trafficking.",
              "source": "Docs"
            },
            {
              "label": "Common VAST errors",
              "href": "/docs/common-vast-errors/",
              "description": "Reference for malformed Impression, Tracking, ClickThrough, and MediaFile URLs, along with other common schema mistakes.",
              "source": "Docs"
            },
            {
              "label": "VAST Wrapper Chains: How They Work, Limits & Debugging",
              "href": "/guides/vast-wrapper-chains/",
              "description": "Why wrappers accumulate trackers and why missing wrapper error URLs turn delivery failures into blind spots.",
              "source": "Guide"
            },
            {
              "label": "Validate VAST XML",
              "href": "/docs/validate-vast-xml/",
              "description": "A focused XML pass for resolved tags when you need the spec-level answer fast.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "Digital Video Ad Serving Template (VAST)",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "Official VAST standards overview and version history for the XML format that carries impression, tracking, click, and error metadata.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VMAP for video ad insertion",
              "href": "https://support.google.com/admanager/answer/4539582",
              "description": "Google Ad Manager documentation describing how players request VAST ads, follow redirects, choose media, and respond with tracking events.",
              "source": "Google Ad Manager"
            },
            {
              "label": "Set up the IMA SDK",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/get-started",
              "description": "Google's player-side ad lifecycle guide, useful for understanding why runtime-specific tracker QA still matters after schema validation.",
              "source": "Google IMA"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Inspect the tracker chain before launch",
          "paragraph": "Start with the live URL, unwrap the wrappers, and review every impression, quartile, click, and error tracker before they become a reporting problem.",
          "href": "/inspect/",
          "label": "Inspect a live VAST URL"
        }
      ]
    },
    {
      "slug": "vpaid-is-deprecated-stop-treating-it-like-a-fallback",
      "title": "VPAID Is Deprecated. Stop Treating It Like a Fallback",
      "description": "IAB positions VPAID as deprecated and replaced by SIMID, while Google's own docs limit VPAID 2 JavaScript support to the IMA HTML5 SDK. In 2026, VPAID is a legacy compatibility mode, not a real fallback strategy for CTV, mobile, or SSAI.",
      "publishedAt": "2026-06-05",
      "updatedAt": "2026-06-05",
      "author": "Alex Sekowski",
      "readingTime": "8 min read",
      "heroKicker": "VPAID migration",
      "tags": [
        "VPAID",
        "SIMID",
        "CTV",
        "SSAI"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "If a VAST tag still uses VPAID, treat it as a legacy web-HTML5 compatibility path, not as a neutral fallback you can safely carry into every runtime. The forward path is standard media for playback, SIMID for interactivity, and OMID for measurement.",
            "That is not just vastlint opinion. The IAB Tech Lab VAST standards page labels VPAID deprecated and replaced with SIMID, the SIMID standard page explains that SIMID and OMID are the focused replacements for VPAID's old combined role, and Google's IMA docs say the HTML5 SDK is the only IMA SDK that supports VPAID 2 JavaScript creatives."
          ]
        },
        {
          "type": "list",
          "heading": "What the public record says now",
          "items": [
            "IAB Tech Lab's VAST standards hub links VPAID as deprecated and replaced with SIMID.",
            "IAB Tech Lab's SIMID page says the industry is replacing VPAID with OMID for measurement and SIMID for interactivity.",
            "The same SIMID page positions SIMID as better aligned with mobile, SSAI, OTT devices, and live streaming, not just browser playback.",
            "Google's IMA HTML5 documentation says only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
            "Google's IMA SIMID documentation separately documents SIMID 1.1 support, which is a strong signal about where the runtime story is moving."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why fallback is the wrong mental model",
          "paragraphs": [
            "A fallback is supposed to broaden compatibility. VPAID does the opposite now. It depends on a browser-like JavaScript execution model, specific SDK behavior, and looser security assumptions than modern CTV, mobile, and SSAI stacks are willing to allow.",
            "That is why VPAID still creates false confidence. A tag can look fine in desktop HTML5 QA and still be the wrong package for the environments that actually matter to a campaign. If the real delivery path includes native mobile SDKs, CTV apps, or server-side stitching, VPAID is not a safety net. It is the risk."
          ]
        },
        {
          "type": "list",
          "heading": "Where VPAID fails first",
          "items": [
            "SSAI: there is no client-side JavaScript runtime at insertion time, so the interactive layer cannot execute the way VPAID expects.",
            "CTV and OTT: native TV players do not expose the browser DOM and shared player context VPAID was built around.",
            "Mobile SDKs: Google's public docs say the IMA HTML5 SDK is the only IMA SDK platform that supports VPAID 2 JavaScript creatives.",
            "Security-sensitive web players: even where VPAID still runs, Google's docs emphasize secure iframe handling, proxy video elements, and compatibility caveats."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Even Google treats VPAID like a narrow compatibility mode",
          "paragraphs": [
            "Google's IMA HTML5 guide does not read like a broad endorsement of VPAID as the future. It reads like a compatibility document. You must explicitly set VPAID mode, the SDK documents security differences between secure and insecure iframe behavior, and it warns creative authors about proxy-element constraints.",
            "At the same time, Google publishes a separate SIMID support guide that documents the SIMID messages IMA HTML5 does and does not support. That is the more useful signal. The ecosystem is not expanding VPAID's footprint. It is documenting how newer secure interaction models behave in real runtimes."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What the replacement stack looks like in practice",
          "paragraphs": [
            "The modern split is simpler than the VPAID era. Keep playback in a normal MediaFile. Put interactive behavior in a SIMID InteractiveCreativeFile. Put verification in AdVerifications with OMID-compatible resources. That separation gives the player control over media, keeps the interactive code sandboxed, and works much better with SSAI, CTV, and stricter platform security.",
            "IAB's SIMID page makes the design goal explicit: separate the interactive layer from the media asset so publishers keep control of the stream and can support use cases like SSAI and live streaming without handing the whole runtime to ad code."
          ]
        },
        {
          "type": "code",
          "heading": "A healthier replacement pattern",
          "language": "xml",
          "code": "<MediaFiles>\n  <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1280\" height=\"720\">\n    <![CDATA[https://cdn.example.com/ads/preroll.mp4]]>\n  </MediaFile>\n  <InteractiveCreativeFile type=\"text/html\" apiFramework=\"SIMID\">\n    <![CDATA[https://cdn.example.com/ads/interactive-layer.html]]>\n  </InteractiveCreativeFile>\n</MediaFiles>\n<AdVerifications>\n  <Verification vendor=\"measurement.example\">\n    <JavaScriptResource apiFramework=\"omid\" browserOptional=\"true\">\n      <![CDATA[https://measurement.example/omid.js]]>\n    </JavaScriptResource>\n  </Verification>\n</AdVerifications>"
        },
        {
          "type": "list",
          "heading": "A pragmatic policy for teams still receiving VPAID tags",
          "items": [
            "Treat VPAID as an explicit legacy exception, not as the default fallback layer in new trafficking.",
            "If a partner insists on VPAID, document the exact runtime where it is still expected to work, usually desktop HTML5, and do not silently assume mobile, CTV, or SSAI compatibility.",
            "Require a standard playback MediaFile alongside any interactive layer so the campaign is not entirely dependent on executable ad code.",
            "Validate for apiFramework=\"VPAID\", missing MP4 fallback, and missing SIMID or OMID replacements before launch approval.",
            "Run runtime-specific QA after standards validation, because a tag that is structurally clean can still fail inside a particular SDK."
          ]
        },
        {
          "type": "quote",
          "quote": "In 2026, VPAID is not a fallback strategy. It is a legacy compatibility exception.",
          "attribution": "vastlint field note"
        },
        {
          "type": "resources",
          "heading": "Sources and further reading",
          "items": [
            {
              "label": "IAB Tech Lab VAST standards hub",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "Official VAST standards overview, version history, and supporting resources. Links VPAID as deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab SIMID standard",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "Official SIMID overview explaining the SIMID and OMID split and the focus on mobile, SSAI, OTT, and live streaming.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: Enable VPAID 2 JavaScript creatives",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Google's current VPAID support guide, including the note that only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "Google IMA HTML5: Review SIMID support",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/simid-support",
              "description": "Google's SIMID support guide for IMA HTML5, including supported and unsupported messages.",
              "source": "Google IMA"
            },
            {
              "label": "VPAID deprecated migration guide",
              "href": "/guides/vast-vpaid-migration/",
              "description": "vastlint's migration checklist for replacing VPAID with SIMID, OMID, and standard playback files.",
              "source": "Guide"
            },
            {
              "label": "SIMID explained",
              "href": "/docs/simid/",
              "description": "Reference on SIMID, InteractiveCreativeFile, sandboxing, and the SIMID versus VPAID model.",
              "source": "Docs"
            },
            {
              "label": "VPAID deprecated explainer",
              "href": "/docs/vpaid/",
              "description": "Reference on how VPAID appears in VAST tags, why it is deprecated, and what replaces it.",
              "source": "Docs"
            },
            {
              "label": "VPAID vs SIMID compares an executable in the player with a sidecar beside the media file",
              "href": "/blog/vpaid-vs-simid/",
              "description": "Why the two frameworks are not a fallback chain.",
              "source": "vastlint"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Check whether a live tag still depends on VPAID",
          "paragraph": "Start with the live URL or resolved XML and catch deprecated VPAID patterns before the campaign hits mobile, CTV, or SSAI traffic.",
          "href": "/tester/",
          "label": "Test a live VAST tag URL"
        }
      ]
    },
    {
      "slug": "mcp-preflight-for-ad-ops-teams",
      "title": "Why Ad Ops Teams Should Preflight VAST with MCP Before Launch",
      "description": "If AI agents are touching campaign setup, creative QA, or partner approvals, they need a deterministic VAST gate. MCP is useful here because it turns validation into a repeatable machine step instead of another manual checklist.",
      "publishedAt": "2026-05-02",
      "updatedAt": "2026-05-11",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Agentic ad ops",
      "tags": [
        "MCP",
        "Ad ops",
        "Automation",
        "Preflight QA"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Manual QA does not scale with agentic workflows",
          "paragraphs": [
            "The moment a team starts using AI for campaign setup, tag review, or launch prep, the old human-only QA path becomes a bottleneck. You need one deterministic place where the system can ask: does this tag pass spec validation, does this URL unwrap correctly, and what issues need to be fixed before delivery?",
            "That is exactly the job a focused MCP tool should do.",
            "The broader MCP ecosystem describes the protocol as an open standard for connecting AI applications to external systems and tools. In ad operations, that matters because VAST validation should be a reliable tool call in the workflow, not a browser tab someone remembers to open when launch pressure is high."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why MCP fits preflight better than ad hoc scripts",
          "paragraphs": [
            "One-off scripts are easy to start and hard to operationalize. They tend to return inconsistent formats, hide assumptions in code that only one person understands, and break the moment the workflow moves from a local machine into a shared agentic environment.",
            "An MCP surface makes the validation step explicit. The tool name, input shape, rule identifiers, and output structure become part of the operating model. That is what lets multiple agents, operators, or automation layers use the same gate with predictable behavior."
          ]
        },
        {
          "type": "list",
          "heading": "What a useful preflight step returns",
          "items": [
            "A pass or fail result that can gate the workflow automatically.",
            "Structured rule IDs and locations so an agent or operator knows what to repair.",
            "Wrapper-chain inspection for third-party URLs, not just raw XML blobs.",
            "Optional auto-fix for deterministic cleanup before a human reviews the final payload.",
            "A consistent summary that can be written into tickets, approval records, or campaign metadata.",
            "Enough detail to separate spec violations from platform-fit issues such as wrapper depth or deprecated creative types."
          ]
        },
        {
          "type": "code",
          "heading": "The shape of the check is simple",
          "language": "json",
          "code": "{\n  \"tool\": \"validate_vast_url\",\n  \"input\": {\n    \"url\": \"https://ads.example.com/vast?placement=pre-roll\",\n    \"max_depth\": 4\n  }\n}"
        },
        {
          "type": "paragraphs",
          "heading": "Where to place the gate in your workflow",
          "paragraphs": [
            "The most useful place to run this check is before the tag reaches trafficking and again before launch approval. The first pass catches bad partner payloads early. The second pass confirms that the live line item still resolves the way your team thinks it does.",
            "Once VAST QA becomes a tool call instead of an ad hoc browser habit, launch quality gets easier to measure. Every agent, trader, or ops analyst is working against the same rule set and the same response format."
          ]
        },
        {
          "type": "list",
          "heading": "A pragmatic rollout plan",
          "items": [
            "Start with validation and wrapper inspection as a non-blocking advisory step.",
            "Promote obvious hard failures to blocking conditions once the team trusts the output.",
            "Write rule IDs and summaries into launch tickets so partner remediation is faster.",
            "Keep safe auto-fix limited to deterministic cleanup rather than opinionated rewriting.",
            "Use the same MCP surface in human workflows and agent workflows so QA drift does not appear between them."
          ]
        },
        {
          "type": "resources",
          "heading": "Related docs on vastlint",
          "items": [
            {
              "label": "MCP docs",
              "href": "/docs/mcp/",
              "description": "How the hosted MCP surface exposes VAST validation, rule catalog, wrapper inspection, and safe auto-fix.",
              "source": "Docs"
            },
            {
              "label": "AdCP docs",
              "href": "/docs/adcp/",
              "description": "Governance and protocol context for integrating validation into ad-creative workflows.",
              "source": "Docs"
            },
            {
              "label": "Validate VAST XML",
              "href": "/docs/validate-vast-xml/",
              "description": "The core validator behavior and how teams can use it as a first gate before workflow automation.",
              "source": "Docs"
            },
            {
              "label": "Agentic docs",
              "href": "/docs/agentic/",
              "description": "Background on where agentic workflows fit into the broader vastlint operating model.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "resources",
          "heading": "Authoritative references",
          "items": [
            {
              "label": "What is the Model Context Protocol (MCP)?",
              "href": "https://modelcontextprotocol.io/introduction",
              "description": "The official introduction to MCP and why standardized tool access matters for AI applications.",
              "source": "Model Context Protocol"
            },
            {
              "label": "Digital Video Ad Serving Template (VAST)",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "The canonical VAST spec overview that your preflight step should ultimately be checking against.",
              "source": "IAB Tech Lab"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "See the MCP surface",
          "paragraph": "The hosted MCP endpoint exposes validation, wrapper inspection, rule listing, and safe auto-fix so preflight can become a standard part of campaign automation.",
          "href": "/docs/mcp/",
          "label": "View MCP docs"
        }
      ]
    },
    {
      "slug": "vastlint-vs-adplayer-pro-vast-inspector",
      "title": "vastlint vs AdPlayer.Pro VAST Inspector",
      "description": "vastlint validates VAST XML against a public, standards-derived rule set with wrapper unwrapping, creative parsing, and CI-friendly output. AdPlayer.Pro's VAST Inspector is a browser preview tool built to show whether a tag plays in their player, not whether it complies with the spec. Here is where each fits.",
      "publishedAt": "2026-07-03",
      "updatedAt": "2026-07-03",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Tool comparison",
      "tags": [
        "AdPlayer.Pro",
        "VAST validator",
        "VAST tester",
        "Ad ops"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "If the job is to check whether a VAST document complies with the IAB specification, resolve a wrapper chain, and get rule-level diagnostics you can act on, vastlint is the tool for that job. It validates against a public, standards-derived rule set, unwraps redirects, parses creatives and tracking, and produces output that works the same in a browser, a CI pipeline, or an MCP-connected agent.",
            "AdPlayer.Pro's VAST Inspector answers a narrower question: does this tag play in AdPlayer.Pro's own video player. It accepts a VAST, VPAID, Google IMA, or Freewheel tag, runs it through their player, and shows a live preview plus a raw event log. That is useful as a playback smoke test, but it is not a spec compliance check.",
            "The two tools are not really competing on the same axis. vastlint tells you if the tag is correct. AdPlayer.Pro's inspector tells you if the tag plays in their player. Teams that only run the second check are trusting the player to surface problems that are actually XML-level."
          ]
        },
        {
          "type": "list",
          "heading": "The fastest way to choose between them",
          "items": [
            "Use vastlint if you need to know whether the VAST XML itself complies with the spec, not just whether it happens to play.",
            "Use vastlint if you need wrapper-chain resolution with visibility into every hop, not just the final playable result.",
            "Use vastlint if you want rule-level output you can paste into a bug report, a PR check, or an agent workflow.",
            "Use AdPlayer.Pro's inspector if you specifically want to see the tag rendered inside their player as a playback sanity check.",
            "Use AdPlayer.Pro's inspector if you're evaluating AdPlayer.Pro itself as a player or ad server vendor.",
            "Use both if you want a structural validation pass and a separate player-rendering pass, in that order."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why vastlint is the stronger starting point",
          "paragraphs": [
            "vastlint is built around the question every ad-ops or engineering team eventually has to answer: does this tag comply with the spec, and if not, exactly which rule does it break and how do you fix it. That means validating the XML against rules derived from the published IAB VAST XSD schemas and normative prose, across VAST 2.0 through 4.3, and surfacing findings with fix guidance rather than a pass/fail player result.",
            "It also separates the concerns that a preview-only tool collapses into one step: test a live tag URL, inspect each wrapper hop on its own, and validate the resolved XML independently. That separation matters because a tag can play successfully in a permissive player while still violating the spec in ways that break stricter players, SSAI stitchers, or downstream measurement.",
            "That's the practical split. vastlint is stronger on spec compliance, wrapper visibility, and reusable output. AdPlayer.Pro's inspector is stronger as a quick playback check inside one specific player."
          ]
        },
        {
          "type": "list",
          "heading": "The gaps vastlint closes",
          "items": [
            "Rule-level validation against a public, standards-derived methodology, not a player-passes-or-it-doesn't result.",
            "Wrapper-chain inspection that shows every hop, not just the final resolved ad.",
            "Coverage through VAST 4.3, including the parts of the spec no published IAB XSD covers directly.",
            "Output built for reuse: CLI, CI checks, npm packages, and MCP tools, not just a browser session.",
            "A validation surface that isn't anchored to any single player's playback behavior."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What AdPlayer.Pro's inspector is actually built for",
          "paragraphs": [
            "AdPlayer.Pro's public VAST Inspector page frames itself around testing \"your VAST, VPAID or Google IMA video ad tag\" or checking AdPlayer.Pro's own player against sample VAST and VMAP tags, with Freewheel also mentioned in the page's metadata. The workflow is a client selector (VAST or Google IMA), a choice between a sample tag or a pasted custom tag, a Test Ad button, an embedded player, and an event log.",
            "There is no visible rule catalog, no spec version claims, no wrapper-hop breakdown, and no XML diagnostics on the page itself. It is, functionally, a demo surface for AdPlayer.Pro's own video player and ad server product, not a standards-validation tool. That framing is consistent with the rest of the site, which is a commercial video ad server and white-label platform with the inspector as one of several lead-generation pages alongside a stream tester.",
            "That's a reasonable thing for a player vendor to build. It answers \"will this tag work in our player,\" which matters if you're evaluating AdPlayer.Pro specifically. It doesn't answer \"is this tag spec-compliant,\" which is a different, and for most ad-ops workflows, prior, question."
          ]
        },
        {
          "type": "list",
          "heading": "What AdPlayer.Pro's inspector is useful for",
          "items": [
            "A quick check that a tag renders and plays inside AdPlayer.Pro's own player.",
            "A side-by-side look at VAST, VPAID, and Google IMA sample tags if you're evaluating their player.",
            "A raw event log for the specific playback session, useful for debugging that player's own event firing.",
            "Sample VAST and VMAP tags if you just need something to click through quickly."
          ]
        },
        {
          "type": "quote",
          "quote": "A tag that plays isn't the same as a tag that's correct. AdPlayer.Pro checks the first. vastlint checks the second.",
          "attribution": "vastlint field note"
        },
        {
          "type": "paragraphs",
          "heading": "Use them in this order",
          "paragraphs": [
            "Starting from a player preview makes it easy to conflate two different failure modes: an XML-level spec violation and a player-specific playback quirk. If a tag fails in AdPlayer.Pro's inspector, you don't yet know whether the XML is wrong or the player is just stricter or more permissive than whatever will run it in production.",
            "The cleaner sequence is to validate the XML in vastlint first, resolve the wrapper chain, and confirm the tag is spec-compliant before ever loading it into a specific player's preview. If you still want a playback sanity check afterward, whether in AdPlayer.Pro's inspector or your own production player, you're now testing player behavior against a tag you already know is correct.",
            "That order keeps the two questions separate, which is the whole point: spec compliance is a property of the XML, and playback behavior is a property of the player."
          ]
        },
        {
          "type": "code",
          "heading": "Recommended workflow when AdPlayer.Pro's inspector is part of QA",
          "language": "bash",
          "code": "# 1. Validate the VAST XML (or live tag URL) in vastlint against the public rule set\n# 2. Inspect the wrapper chain hop by hop in vastlint\n# 3. Fix any spec violations vastlint surfaces\n# 4. Only then load the tag into AdPlayer.Pro's inspector (or your production player) as a playback check\n# 5. Treat player-specific playback issues as separate from XML-level spec issues"
        },
        {
          "type": "list",
          "heading": "When vastlint is the better first choice",
          "items": [
            "You need to know if the tag is spec-compliant, not just whether one specific player can render it.",
            "You need wrapper-chain visibility instead of a single collapsed playback result.",
            "You need output that plugs into CI, a CLI, or an agent workflow instead of a manual browser session.",
            "You need a validation surface that isn't tied to any one vendor's player.",
            "You want to separate XML correctness from playback behavior before you start debugging either one."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "When AdPlayer.Pro's inspector still earns a spot",
          "paragraphs": [
            "AdPlayer.Pro's inspector is worth using when you're specifically evaluating AdPlayer.Pro's player or ad server, or when you want one more concrete playback pass after the tag has already cleared spec validation. It is not a substitute for that validation step. It doesn't claim to check the tag against the IAB VAST specification, and it doesn't surface rule-level diagnostics.",
            "That's the fair comparison. AdPlayer.Pro built a demo tool for their own player. vastlint built a validator for the spec. Use the second one first."
          ]
        },
        {
          "type": "resources",
          "heading": "Sources and related docs",
          "items": [
            {
              "label": "AdPlayer.Pro VAST Inspector",
              "href": "https://adplayer.pro/developer/vast_inspector",
              "description": "AdPlayer.Pro's public VAST/VPAID/Google IMA tag tester page, built around their own player preview and event log.",
              "source": "AdPlayer.Pro"
            },
            {
              "label": "Rule derivation methodology",
              "href": "/docs/methodology/",
              "description": "How vastlint derives rules from IAB XSD schemas, normative prose, and related standards.",
              "source": "Docs"
            },
            {
              "label": "Validate VAST XML online",
              "href": "/docs/validate-vast-xml/",
              "description": "How to choose between validating resolved XML and testing a live tag URL.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Validate the spec before you trust the player",
          "paragraph": "Resolve the wrapper chain and validate the XML against the public rule set before loading the tag into any single player's preview. That keeps XML correctness and playback behavior as separate, debuggable problems.",
          "href": "/tester/",
          "label": "Test a live VAST tag URL"
        }
      ]
    },
    {
      "slug": "vastlint-vs-test-a-tag",
      "title": "Test a Tag vs vastlint: VAST Tester Alternative",
      "description": "Paste the live URL at vastlint.org/tester/. Test a Tag is a free preview for HTML, MRAID, VAST, and VMAP. It does not validate against the spec. vastlint checks XML against public IAB rules and inspects wrapper hops.",
      "publishedAt": "2026-07-03",
      "updatedAt": "2026-08-29",
      "author": "Alex Sekowski",
      "readingTime": "6 min read",
      "heroKicker": "Tool comparison",
      "tags": [
        "Test A Tag",
        "VAST validator",
        "VAST tester",
        "Ad ops"
      ],
      "published": true,
      "body": [
        {
          "type": "paragraphs",
          "heading": "Short answer",
          "paragraphs": [
            "Paste the live VAST URL at https://vastlint.org/tester/. Free, no signup: fetch, preview, tracking. Test A Tag is a small, free, no-signup utility for HTML, MRAID, VAST, VAST URI, VMAP, or VMAP URI preview in an isolated frame. It does not validate against the IAB spec. Wrapper hops are https://vastlint.org/inspect/.",
            "vastlint answers a different question. It checks whether the VAST XML itself complies with the IAB specification, rule by rule, across VAST 2.0 through 4.3, and it can walk a wrapper chain hop by hop instead of only showing the final rendered result. Test A Tag has no rule engine, no error or warning output, and no wrapper-chain view.",
            "They're not really substitutes. Test A Tag is a fast, disposable preview and sharing tool. vastlint is a compliance checker. A tag can render fine in Test A Tag's preview frame and still violate the spec in ways that only show up against a stricter player or an SSAI stitcher downstream."
          ]
        },
        {
          "type": "list",
          "heading": "The fastest way to choose between them",
          "items": [
            "Use vastlint if you need to know whether the VAST XML complies with the spec, not just whether it renders.",
            "Use vastlint if you need to see every wrapper hop on its own, not just the final resolved creative.",
            "Use vastlint if you want rule IDs and fix guidance you can paste into a ticket or a PR check.",
            "Use Test A Tag if you just want to paste something (HTML, MRAID, VAST, or VMAP) and see it render, no signup, no setup.",
            "Use Test A Tag if you want to stash a handful of tags locally or send a colleague a pre-loaded link.",
            "Use both if the tag matters: validate the XML in vastlint first, then use Test A Tag for a quick throwaway render or to hand a link to someone else."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why vastlint is the stronger starting point",
          "paragraphs": [
            "vastlint starts from the spec, not the player. It validates VAST XML against rules derived from the published IAB VAST XSD schemas and normative prose, across VAST 2.0 through 4.3, and reports findings with a rule ID, severity, and fix guidance rather than a render-or-doesn't-render result.",
            "It also separates concerns that a single preview box collapses together: test a live tag URL, inspect each wrapper hop independently, and validate the resolved XML on its own. A tag can look fine in an isolated preview frame while still being structurally invalid in ways that break a stricter SDK, an SSAI stitcher, or downstream reporting.",
            "That's the practical split. vastlint is stronger on spec compliance, wrapper visibility, and output you can act on. Test A Tag is stronger as a zero-friction way to eyeball a creative."
          ]
        },
        {
          "type": "list",
          "heading": "The gaps vastlint closes",
          "items": [
            "Rule-level validation against a public, standards-derived methodology, not just a render-or-doesn't render result.",
            "Wrapper-chain inspection showing every hop, not a single collapsed preview.",
            "Coverage through VAST 4.3, with a documented approach for the parts no published IAB XSD covers directly.",
            "Findings with a rule ID, severity, and fix guidance instead of no error reporting at all.",
            "Output built for reuse: CLI, CI checks, npm packages, and an MCP server, not only a browser tab."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What Test A Tag is actually built for",
          "paragraphs": [
            "Test A Tag's own description is direct about its scope: a service \"designed to preview creatives and ad tags directly on various browsers,\" supporting HTML5, MRAID, and video tags (VAST and VMAP), relying on Google's IMA SDK for video. It's framed explicitly as a convenience tool built to make previewing creatives \"a little easier for the already overworked adops professional,\" not as a validator.",
            "The interface is a single textarea that auto-detects whatever you paste, a preview tab with a reload button (useful for tags with frequency caps that need a fresh ad call), and a Stash tab. The Stash is plain browser localStorage, capped at 20 entries, device-specific, and gone if the browser data is cleared. The Share button encodes the pasted creative into a URL so someone else's session opens with it pre-loaded.",
            "There's no signup, no support, and by its own disclaimer, no warranty: it's a free side tool, not a supported product. That also means there's nothing to validate against; it's rendering what you gave it, not checking it against anything."
          ]
        },
        {
          "type": "list",
          "heading": "What Test A Tag is useful for",
          "items": [
            "A zero-setup way to paste a creative or tag and see it render, with automatic format detection across HTML, MRAID, VAST, and VMAP.",
            "Reloading a tag quickly to test frequency-capped or fresh-ad-call behavior.",
            "Keeping a short local list of frequently used test tags without an account.",
            "Sending a colleague a link that opens with the exact same creative pre-loaded, without them needing to paste anything."
          ]
        },
        {
          "type": "quote",
          "quote": "Test A Tag tells you it rendered. vastlint tells you why it did, or why it shouldn't have.",
          "attribution": "vastlint field note"
        },
        {
          "type": "paragraphs",
          "heading": "Use them in this order",
          "paragraphs": [
            "If the first thing you do with a new tag is paste it into a preview frame, a passing render can quietly stand in for a compliance check it never performed. That's fine for a disposable creative you're eyeballing once, but it's a bad habit for anything going into a live campaign, an SSAI break, or a partner integration.",
            "The cleaner order is to validate the VAST XML in vastlint first, resolve any wrapper chain hop by hop, and fix whatever the rule engine flags. Once the tag is known to be spec-compliant, Test A Tag is a fine place to do a quick visual pass or hand a colleague a working link.",
            "That ordering keeps \"is this XML correct\" and \"does this render for me right now\" as separate questions, which is the point: one is a property of the document, the other is a property of a specific preview session."
          ]
        },
        {
          "type": "code",
          "heading": "Recommended workflow when Test A Tag is part of QA",
          "language": "bash",
          "code": "# 1. Validate the VAST XML (or live tag URL) in vastlint against the public rule set\n# 2. Inspect the wrapper chain hop by hop in vastlint\n# 3. Fix any spec violations vastlint surfaces\n# 4. Paste the tag into Test A Tag for a quick visual render, or share a pre-loaded link with a colleague\n# 5. Treat a passing Test A Tag preview as a render check, not a compliance check"
        },
        {
          "type": "list",
          "heading": "When vastlint is the better first choice",
          "items": [
            "You need to know if the tag is spec-compliant, not just whether it renders in one preview frame.",
            "You need wrapper-chain visibility instead of a single collapsed preview result.",
            "You need rule IDs, severity, and fix guidance you can act on or paste into a ticket.",
            "You need output that plugs into CI, a CLI, or an agent workflow instead of a manual browser tab.",
            "The tag is going into a real campaign, not just being eyeballed once."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "When Test A Tag still earns a spot",
          "paragraphs": [
            "Test A Tag is genuinely useful when you want the lowest-friction way to glance at a creative, reload it a few times, or send someone a working link without asking them to paste anything. Its own scope is narrow by design: preview, stash, share. It doesn't claim to check anything against the IAB VAST specification, and it has no error or warning output to speak of.",
            "That's the fair comparison. Test A Tag built a fast preview tool. vastlint built a validator for the spec. Use the second one first, and keep the first one around for the quick look afterward."
          ]
        },
        {
          "type": "resources",
          "heading": "Sources and related docs",
          "items": [
            {
              "label": "Test A Tag",
              "href": "https://test-a-tag.com",
              "description": "Test A Tag's public preview tool for HTML, MRAID, VAST, and VMAP creatives and tags.",
              "source": "Test A Tag"
            },
            {
              "label": "Rule derivation methodology",
              "href": "/docs/methodology/",
              "description": "How vastlint derives rules from IAB XSD schemas, normative prose, and related standards.",
              "source": "Docs"
            },
            {
              "label": "Validate VAST XML online",
              "href": "/docs/validate-vast-xml/",
              "description": "How to choose between validating resolved XML and testing a live tag URL.",
              "source": "Docs"
            }
          ]
        },
        {
          "type": "cta",
          "heading": "Validate the spec before you trust the render",
          "paragraph": "Resolve the wrapper chain and validate the XML against the public rule set before treating any preview render as a pass. That keeps spec compliance and visual QA as separate, debuggable steps.",
          "href": "/tester/",
          "label": "Test a live VAST tag URL"
        }
      ]
    },
    {
      "slug": "what-replaced-vpaid",
      "title": "What Replaced VPAID Is a Media File, a SIMID Sidecar, and an OMID Verification",
      "description": "IAB replaced VPAID with two standards: SIMID for interactivity and OMID for measurement. Playback stays a media file the player owns. MRAID 3.0 borrowed some VPAID events for in-app reporting and did not take the video-player job. vastlint checks the nodes in the tag. It does not run them.",
      "seoTitle": "What replaced VPAID lines up a media file, SIMID, and OMID",
      "seoDescription": "VPAID split into a media file, SIMID for interaction, and OMID for measurement. vastlint checks those nodes in the VAST tag. It does not run them.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "VPAID",
        "SIMID",
        "OMID",
        "VAST",
        "MRAID"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each job, in one row",
          "caption": "IAB split the executable into a file the player owns, a SIMID sidecar, and an OMID verification. vastlint checks those nodes. It does not run them.",
          "columns": [
            "Job",
            "Spec",
            "Where it sits",
            "If it is missing"
          ],
          "rows": [
            {
              "cells": [
                "Playback",
                "Media file",
                "MediaFile the player can decode",
                "Nothing plays"
              ],
              "href": "/blog/vpaid-alternative/"
            },
            {
              "cells": [
                "Interaction",
                "SIMID",
                "InteractiveCreativeFile, apiFramework SIMID",
                "The media file can still play"
              ],
              "href": "/blog/vpaid-vs-simid/"
            },
            {
              "cells": [
                "Measurement",
                "OMID",
                "AdVerifications, apiFramework omid",
                "The ad can play unmeasured"
              ],
              "href": "/blog/omid-alternative/"
            },
            {
              "cells": [
                "Legacy executable",
                "VPAID",
                "MediaFile, apiFramework VPAID",
                "Often nothing left to play"
              ],
              "href": "/blog/vpaid-vs-simid/"
            },
            {
              "cells": [
                "In-app rich media",
                "MRAID",
                "An SDK webview, not a VAST media file",
                "A playable is not a preroll"
              ],
              "href": "/blog/vpaid-vs-mraid/"
            },
            {
              "cells": [
                "The document",
                "VAST",
                "The XML response",
                "The interfaces have nothing to sit in"
              ],
              "href": "/blog/vast-vs-vpaid/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/what-replaced-vpaid.png?v=2",
          "alt": "Three cards. A media file is playback. SIMID is the interactive sidecar. OMID is the measurement script in AdVerifications. VPAID used to bundle all three.",
          "width": 1440,
          "height": 820,
          "caption": "IAB split the executable into a file the player owns, a SIMID sidecar, and an OMID verification. vastlint checks those nodes. It does not run them.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "What replaced VPAID is not a new name for the same executable. IAB Tech Lab's SIMID page says the working group is replacing VPAID with two focused standards: OMID for measurement and verification, and SIMID for interactivity. Playback stays a media file. SIMID 1.2, the version described on that page as of January 3, 2024, keeps the interactive layer separate from the media asset, and both are delivered by VAST 4.x. A stitcher can still handle the file. The creative does not become the player.",
            "MRAID did not inherit the video-player job. IAB's MRAID 3.0 note adds creative-side viewability, audibility, and selected VPAID events so in-app video can report more uniformly. That is an event vocabulary inside a mobile webview. It is not the replacement IAB names for a VAST player. vastlint checks whether a VAST 2.0–4.4 tag still has a decodable media file, a SIMID file only where one was declared, and a verification node where measurement was declared. It does not execute VPAID, open a SIMID session, run OM SDK, or certify MRAID."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why one column on the trafficking sheet keeps the old object alive",
          "paragraphs": [
            "A sheet with a single framework cell asks for one string. VPAID used to be a plausible answer because the executable could play the ad, draw the overlay, and emit the quartile. The replacement refuses that compression. If the spot has no interaction, the cell should be empty and the media file should be real. If someone must click, the cell is SIMID, and a media file still has to sit beside it. If a vendor must measure, the cell is not a framework on the media file. It is OMID inside AdVerifications, or, on older documents, an Extension of type AdVerifications.",
            "Google's IMA docs draw the runtime line in public. Only the HTML5 SDK supports VPAID 2 JavaScript creatives. SIMID support is a separate page. A 2026 tag that still prefers VPAID because some web player once needed it keeps an executable on a path that also serves televisions and stitchers. Those runtimes do not gain a creative by receiving a script."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to do with a tag that still says VPAID",
          "paragraphs": [
            "Read the inline, not the wrapper you were handed in QA. Find every MediaFile and InteractiveCreativeFile, and write down the apiFramework. A VPAID media file with no sibling the player can decode is the deprecated shape. A SIMID URL with no sibling media file is that shape wearing the new name. An OMID script placed in the interactive file, or a SIMID URL placed in JavaScriptResource, has swapped the two halves of the split.",
            "Keep the vendor decision off this page. IAS, DoubleVerify, Pixalate, and HUMAN are choices inside measurement, which is the OMID job. They are not substitutes for SIMID, and SIMID is not a verification product. vastlint will not pick a vendor. It will show whether the document still contains the node that vendor would have to read."
          ]
        },
        {
          "type": "list",
          "heading": "The split, written as a check",
          "items": [
            "A media file the player can decode without loading JavaScript.",
            "SIMID only as an interactive file beside that media, when interaction is actually required.",
            "OMID in AdVerifications, not inside the creative.",
            "Any remaining VPAID media file, treated as legacy web compatibility.",
            "MRAID left in the in-app rich-media path, not renamed into a VAST apiFramework as a fallback."
          ]
        },
        {
          "type": "quote",
          "quote": "The executable became a file the player owns, a sidecar for the click, and a verification script for the measurement, and those three do not collapse back into one cell.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "See which of the three the inline actually has",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab Open Measurement SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "OM SDK page, updated November 4, 2025. Measurement providers collect signals through the OMID API. The current API docs listed there are OMID 1.6.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab MRAID 3.0",
              "href": "https://iabtechlab.com/standards/mraid/",
              "description": "MRAID is the in-app rich media interface. Version 3.0 adds creative-side viewability and audibility, and selected VPAID events for in-app video reporting.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: VPAID 2 JavaScript",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "Google IMA HTML5: SIMID support",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/simid-support",
              "description": "SIMID support is documented on its own page, including which messages the HTML5 SDK implements.",
              "source": "Google IMA"
            },
            {
              "label": "VPAID vs SIMID compares an executable with a sidecar",
              "href": "/blog/vpaid-vs-simid/",
              "description": "The pair this index opens from.",
              "source": "vastlint"
            },
            {
              "label": "A VPAID alternative is three objects",
              "href": "/blog/vpaid-alternative/",
              "description": "Playback, interaction, and measurement, written as a replacement.",
              "source": "vastlint"
            },
            {
              "label": "VPAID reference",
              "href": "/docs/vpaid/",
              "description": "How VPAID appears in a VAST tag, and why it is deprecated.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "simid-vs-omid",
      "title": "SIMID vs OMID Compares an Interactive Sidecar With a Measurement Script",
      "description": "SIMID is the interactive file beside a media file the player owns. OMID is the verification script in AdVerifications. IAB names them as the two replacements for VPAID, and they are not two values of one apiFramework. vastlint checks which element each string sits on. It does not open either session.",
      "seoTitle": "SIMID vs OMID lines up a sidecar and a measurement script",
      "seoDescription": "SIMID is the interactive sidecar. OMID is the measurement script in AdVerifications. vastlint checks which element each string sits on. It does not run either session.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "SIMID",
        "OMID",
        "VPAID",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each interface, in one row",
          "caption": "The two strings replaced different halves of VPAID. vastlint checks which element each one sits on. It does not open either session.",
          "columns": [
            "Spec",
            "Owns",
            "Element",
            "apiFramework"
          ],
          "rows": [
            {
              "cells": [
                "SIMID",
                "Interaction",
                "InteractiveCreativeFile",
                "SIMID"
              ],
              "href": "/blog/simid-alternative/"
            },
            {
              "cells": [
                "OMID",
                "Measurement",
                "JavaScriptResource in AdVerifications",
                "omid"
              ],
              "href": "/blog/omid-alternative/"
            },
            {
              "cells": [
                "Media file",
                "Playback",
                "MediaFile",
                "None required"
              ],
              "href": "/blog/what-replaced-vpaid/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/simid-vs-omid.png?v=2",
          "alt": "SIMID is an InteractiveCreativeFile beside a media file. OMID is a JavaScriptResource with apiFramework omid inside AdVerifications.",
          "width": 1440,
          "height": 820,
          "caption": "The two strings replaced different halves of VPAID. vastlint checks which element each one sits on. It does not open either session.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "SIMID vs OMID is the pair people collapse because both names arrived when VPAID was split. IAB Tech Lab's SIMID page says the replacement is two standards: OMID for measurement and verification, SIMID for interactivity. SIMID is an interactive document beside a media file the player owns. The player loads it in a sandboxed frame and talks to it over a defined channel. OMID is the API a verification script uses once the player has OM SDK. In the tag, that script is a JavaScriptResource with apiFramework omid, inside AdVerifications on VAST 4.1 and later.",
            "They are not two legal values of one attribute. A SIMID URL in the verification node does not measure the impression. An OMID script in InteractiveCreativeFile does not draw the overlay. vastlint checks that split in the VAST 2.0–4.4 document: the interactive file against a real media file, and the verification node a measurement script would have to occupy. It does not open a SIMID session and it does not run OMID."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What each one does when the other fails",
          "paragraphs": [
            "If the SIMID frame never loads, the media file is still a media file, provided you gave the player one. Duration and quartiles stay with the playhead. The click layer is gone. That is a failed interaction, not a failed ad, and it is the reason the sidecar exists. If the OMID script never loads, the media file can still play and the SIMID layer can still take a click. The impression is then unmeasured. verificationNotExecuted is the VAST path for that miss. A quartile pixel is not a substitute for it.",
            "IAB's OM SDK page, updated November 4, 2025, lists OMID 1.6 as the current API docs and still documents earlier versions. SIMID 1.2 is the iteration described on the SIMID page. vastlint does not implement either API. A tag can be structurally ready for both and still fail in a player that has no OM SDK, or in a player whose SIMID support stops at a subset of messages. Google's IMA HTML5 guide documents that subset on its own page, separate from VPAID."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The tag-level swaps that look like a migration",
          "paragraphs": [
            "The common miss is a single apiFramework cell copied onto the wrong element. SIMID belongs on InteractiveCreativeFile, with type text/html, next to a MediaFile. OMID belongs on the verification resource. Putting either string on a MediaFile and deleting the playable file recreates the VPAID failure: if the script does not run, nothing plays. Putting both jobs inside the interactive file, the way VPAID bundled them, hides measurement in a document the stitcher may ignore.",
            "Wrappers hide the choice until the last hop. The wrapper can look like a plain MP4. The inline can be SIMID with a broken media file, or OMID with an empty resource URL. The comparison that matters is the inline the player or the stitcher finally parses. The two nodes in a VAST 4.3 inline look like this. browserOptional on JavaScriptResource is the 4.3 attribute. Earlier 4.1 and 4.2 documents use the same parent elements without it."
          ]
        },
        {
          "type": "code",
          "heading": "SIMID beside the file, OMID outside it",
          "language": "xml",
          "code": "<MediaFiles>\n  <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1280\" height=\"720\">\n    <![CDATA[https://cdn.example.com/ad.mp4]]>\n  </MediaFile>\n  <InteractiveCreativeFile type=\"text/html\" apiFramework=\"SIMID\">\n    <![CDATA[https://cdn.example.com/interactive.html]]>\n  </InteractiveCreativeFile>\n</MediaFiles>\n<AdVerifications>\n  <Verification vendor=\"measurement.example\">\n    <JavaScriptResource apiFramework=\"omid\" browserOptional=\"true\">\n      <![CDATA[https://cdn.example.com/omid.js]]>\n    </JavaScriptResource>\n  </Verification>\n</AdVerifications>"
        },
        {
          "type": "list",
          "heading": "What to look for in the inline",
          "items": [
            "A media file the player can decode without the interactive frame.",
            "SIMID only on InteractiveCreativeFile, and only when interaction is required.",
            "OMID only on the verification resource, inside AdVerifications or a legacy Extension of that type.",
            "No VPAID media file standing in for either half.",
            "The inline after wrappers, not the wrapper from QA."
          ]
        },
        {
          "type": "quote",
          "quote": "An interactive sidecar and a measurement script can both be present, and they still cannot stand in for each other.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "See whether the two strings landed on the right elements",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab Open Measurement SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "OM SDK page, updated November 4, 2025. Measurement providers collect signals through the OMID API. The current API docs listed there are OMID 1.6.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: SIMID support",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/simid-support",
              "description": "SIMID support is documented on its own page, including which messages the HTML5 SDK implements.",
              "source": "Google IMA"
            },
            {
              "label": "What replaced VPAID is three objects",
              "href": "/blog/what-replaced-vpaid/",
              "description": "The index for this split.",
              "source": "vastlint"
            },
            {
              "label": "How to validate OMID in VAST tags",
              "href": "/blog/how-to-validate-omid-in-vast-tags/",
              "description": "The structural checks on AdVerifications.",
              "source": "vastlint"
            },
            {
              "label": "SIMID reference",
              "href": "/docs/simid/",
              "description": "InteractiveCreativeFile, the sandbox, and the media file beside it.",
              "source": "vastlint"
            },
            {
              "label": "OMID reference",
              "href": "/docs/omid/",
              "description": "How AdVerifications carries a verification resource.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vpaid-vs-omid",
      "title": "VPAID vs OMID Compares an Executable That Reported Itself With a Verification Script",
      "description": "VPAID could play the ad and emit its own quartiles from inside the creative. OMID is the measurement API a verification script uses through OM SDK, and it does not play the ad. IAB names OMID as the measurement half of the VPAID replacement. vastlint checks the verification node. It does not execute either one.",
      "seoTitle": "VPAID vs OMID lines up a self-reported quartile and a verification script",
      "seoDescription": "VPAID can emit its own quartiles and is deprecated. OMID measures through OM SDK and does not play the ad. vastlint checks the verification node. It does not run either one.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "VPAID",
        "OMID",
        "SIMID",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each object, in one row",
          "caption": "A quartile from the creative is not OMID. vastlint checks the verification node. It does not execute VPAID or run OM SDK.",
          "columns": [
            "Spec",
            "Can play the ad",
            "Who reports playback",
            "Where it sits"
          ],
          "rows": [
            {
              "cells": [
                "VPAID",
                "Yes, it can be the player",
                "The creative, if it chooses",
                "MediaFile apiFramework VPAID"
              ]
            },
            {
              "cells": [
                "OMID",
                "No",
                "A verification script via OM SDK",
                "AdVerifications"
              ]
            },
            {
              "cells": [
                "SIMID",
                "No, the player owns the file",
                "The player, for quartiles",
                "InteractiveCreativeFile"
              ],
              "href": "/blog/simid-vs-omid/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vpaid-vs-omid.png?v=2",
          "alt": "VPAID is a deprecated executable that can play the ad and emit its own events. OMID is a verification resource that does not play the ad.",
          "width": 1440,
          "height": 820,
          "caption": "A quartile from the creative is not OMID. vastlint checks the verification node. It does not execute VPAID or run OM SDK.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "VPAID vs OMID is what a trafficking sheet asks when measurement used to live inside the executable. A VPAID unit can be the playback engine. The player hands it a slot, the unit loads its own media, and impressions and quartiles can be fired by the creative rather than by the player's playhead. That bundling is why verification code shipped inside VPAID. OMID pulls the measurement back out. IAB's SIMID page names OMID for measurement and verification, and SIMID for interactivity, as the pair that replaces VPAID. OMID does not draw the ad and does not own the playhead.",
            "Google's IMA docs limit VPAID 2 JavaScript support to the HTML5 SDK. A television, a native app, and a server-side stitcher are outside that environment even when they play an ordinary MP4. An OMID resource does not restore the executable for those devices. It gives a player that already integrated OM SDK a script to read signals from. vastlint checks whether a VAST 2.0–4.4 tag still declares that verification node, and whether a VPAID media file is the only thing left to play. It does not execute VPAID and it does not run OM SDK."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "A creative quartile is not a verification",
          "paragraphs": [
            "The number people try to preserve is the quartile. A VPAID unit that emits firstQuartile feels measured. The event came from the same JavaScript that was supposed to be measured. OMID's point is that a third-party script reads signals the player exposes, including viewability, and the creative is not that script. IAB's OM SDK page describes the split directly: integrators send measurement signals to the OMID API, and measurement providers place tags that collect them. The current API docs listed on that page, updated November 4, 2025, are OMID 1.6. Earlier versions remain documented because players in the field are not all on one release.",
            "In the XML, the provider's tag is a Verification. On VAST 4.1 and later the parent is AdVerifications. Older documents sometimes carry the same block as an Extension with type AdVerifications. apiFramework on the JavaScriptResource is omid, lowercase in the examples that validate. A resource URL that is empty or not HTTPS does not become measurement because the vendor name is familiar. A missing verificationNotExecuted tracker makes the failure silent."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What not to migrate into the other name",
          "paragraphs": [
            "Replacing the VPAID media file with an OMID script, and deleting the MP4, leaves a measurement resource and no ad. Replacing OMID with a new VPAID unit because the vendor's old snippet was VPAID puts the executable back on a CTV path. The interactive half, if you still need a click, is SIMID beside a media file, not a second copy of the verification script. Measurement vendors are a choice inside OMID. They are not a choice between OMID and VPAID.",
            "Read the inline. A wrapper can advertise a vendor and drop AdVerifications on the hop the player sees. vastlint will flag the structure. It will not tell you whether the vendor's script, once loaded by a compliant player, agreed with another vendor's script."
          ]
        },
        {
          "type": "list",
          "heading": "A VPAID unit is not an OMID integration",
          "items": [
            "A media file remains after any VPAID file is removed.",
            "Measurement is a Verification resource, not a quartile the creative emits.",
            "apiFramework omid sits on that resource, not on the media file.",
            "SIMID, if the ad is interactive, sits beside the media file and does not carry the measurement.",
            "The inline, not the wrapper, is where the node has to survive."
          ]
        },
        {
          "type": "quote",
          "quote": "The executable that reports its own playback and the script that reads the player are different objects, and only one of them is measurement.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "See whether measurement is still inside the executable",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab Open Measurement SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "OM SDK page, updated November 4, 2025. Measurement providers collect signals through the OMID API. The current API docs listed there are OMID 1.6.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: VPAID 2 JavaScript",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "SIMID vs OMID",
              "href": "/blog/simid-vs-omid/",
              "description": "The other half of the same split.",
              "source": "vastlint"
            },
            {
              "label": "An OMID alternative is a vendor script, not a second API",
              "href": "/blog/omid-alternative/",
              "description": "What can stand in for OMID, and what cannot.",
              "source": "vastlint"
            },
            {
              "label": "How to validate OMID in VAST tags",
              "href": "/blog/how-to-validate-omid-in-vast-tags/",
              "description": "The XML checks before any player runs OM SDK.",
              "source": "vastlint"
            },
            {
              "label": "OMID reference",
              "href": "/docs/omid/",
              "description": "AdVerifications, JavaScriptResource, and what vastlint validates.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vpaid-vs-mraid",
      "title": "VPAID vs MRAID Compares a Video-Player Executable With an In-App Container Bridge",
      "description": "VPAID was a video-player API, now deprecated and replaced by SIMID for interactivity and OMID for measurement. MRAID is the bridge between a rich-media creative and a mobile app SDK. MRAID 3.0 added selected VPAID events for in-app reporting. That overlap is not a substitute inside a VAST tag. vastlint checks VPAID in the document. It does not certify MRAID.",
      "seoTitle": "VPAID vs MRAID lines up a video-player API and an in-app bridge",
      "seoDescription": "VPAID is a deprecated video-player API. MRAID is the in-app rich-media bridge. Shared event names are not a shared runtime. vastlint checks the VAST tag and does not certify MRAID.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "VPAID",
        "MRAID",
        "SIMID",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each host, in one row",
          "caption": "Shared event names are not a shared runtime. vastlint checks VPAID in the VAST tag. It does not certify MRAID.",
          "columns": [
            "Spec",
            "Host",
            "Job",
            "What it is not"
          ],
          "rows": [
            {
              "cells": [
                "VPAID",
                "A VAST player that runs JavaScript",
                "Playback, interaction, and often measurement",
                "A current CTV path"
              ]
            },
            {
              "cells": [
                "MRAID",
                "A mobile SDK webview",
                "Expand, resize, interstitial, playable",
                "The IAB replacement for VPAID"
              ]
            },
            {
              "cells": [
                "SIMID",
                "A VAST player, sandboxed",
                "Interaction beside a media file",
                "An MRAID container"
              ],
              "href": "/blog/simid-vs-mraid/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vpaid-vs-mraid.png?v=2",
          "alt": "VPAID is a deprecated video player API replaced by SIMID and OMID. MRAID is the in-app rich media bridge. MRAID 3.0 added selected VPAID events, which is not a substitute in a VAST tag.",
          "width": 1440,
          "height": 820,
          "caption": "Shared event names are not a shared runtime. vastlint checks VPAID in the VAST tag. It does not certify MRAID.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "VPAID vs MRAID is a name collision between two host APIs. VPAID, the Video Player-Ad Interface Definition, let an executable run in a video player, often as the thing that played the ad. IAB marks it deprecated. The SIMID page names the replacement: OMID for measurement and verification, SIMID for interactivity. MRAID, the Mobile Rich Media Ad Interface Definitions, is the API a creative calls inside an in-app webview: expand, resize, open, orientation, full-screen interstitials. The host is the app SDK, not a VAST player.",
            "MRAID 3.0 is the reason the names get welded together. IAB's MRAID 3.0 note says selected VPAID events were integrated so in-app video creatives could report more uniformly, alongside creative-side viewability and audibility. Those are events inside the MRAID container. They do not make an MRAID playable into a VAST inline, and they do not make a VPAID media file into a legal mobile interstitial. vastlint checks apiFramework VPAID on a VAST 2.0–4.4 media file, and whether a decodable file remains. It does not execute VPAID and it does not certify an SDK's MRAID implementation."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where each one fails",
          "paragraphs": [
            "VPAID fails closed on the devices that do not offer a browser-like player. Google's IMA documentation says only the HTML5 SDK supports VPAID 2 JavaScript creatives. A stitcher cannot splice the script into an MPEG segment and keep the script's behavior. The error looks like a media-file miss. The trafficking sheet still said the line item had a creative.",
            "MRAID fails when the SDK webview is missing or speaks an older subset. MRAID 3.0 says it is backward compatible with 2.0 containers and can degrade. That sentence is about in-app rich media. It is not a promise that a connected TV will run the creative. A VAST linear campaign that sets apiFramework to MRAID because the mobile SDK knew that word has renamed the interface. It has not given the television a file."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to ship on each path",
          "paragraphs": [
            "In-stream video gets a VAST document, a media file, SIMID only when there is a real interaction, and OMID when a vendor must measure. In-app expandable units and playables stay on MRAID, in an SDK that actually implements the version the creative calls. The two paths can belong to one campaign. They are not fallbacks for each other.",
            "If a partner sends one tag and calls it both, split the artifact. The VAST XML is vastlint's document. The MRAID creative is a different file, loaded by a different host. Checking one will not bless the other."
          ]
        },
        {
          "type": "list",
          "heading": "Questions that separate the two",
          "items": [
            "Is the host a video player or a mobile SDK webview?",
            "Is the creative a VAST media file, or the ad itself inside the webview?",
            "Are the shared words VPAID events inside MRAID 3.0, or a VAST apiFramework?",
            "Does a decodable media file remain if the executable never runs?",
            "Is measurement OMID, or the creative reporting its own events?"
          ]
        },
        {
          "type": "quote",
          "quote": "A shared event name inside a mobile container does not turn that container into a VAST player.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "See whether the VAST tag still depends on VPAID",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab MRAID 3.0",
              "href": "https://iabtechlab.com/standards/mraid/",
              "description": "MRAID is the in-app rich media interface. Version 3.0 adds creative-side viewability and audibility, and selected VPAID events for in-app video reporting.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: VPAID 2 JavaScript",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "SIMID vs MRAID",
              "href": "/blog/simid-vs-mraid/",
              "description": "The sandbox beside a media file, against the in-app bridge.",
              "source": "vastlint"
            },
            {
              "label": "What replaced VPAID",
              "href": "/blog/what-replaced-vpaid/",
              "description": "SIMID and OMID, not MRAID.",
              "source": "vastlint"
            },
            {
              "label": "VPAID vs VAST",
              "href": "/docs/vpaid-vs-vast/",
              "description": "VAST is the document. VPAID was an executable inside it.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "simid-vs-mraid",
      "title": "SIMID vs MRAID Compares a Sandboxed Sidecar With the Ad Inside an App Webview",
      "description": "SIMID is an interactive file beside a VAST media file. The player owns playback and the creative talks over postMessage from a sandbox. MRAID is the API that same creative would call if it were the ad inside a mobile SDK webview. A playable is not a SIMID preroll. vastlint checks the VAST side of SIMID. It does not execute MRAID.",
      "seoTitle": "SIMID vs MRAID lines up a VAST sidecar and an in-app bridge",
      "seoDescription": "SIMID sits beside a VAST media file. MRAID is the creative's bridge to a mobile app SDK. vastlint checks the SIMID node. It does not execute MRAID.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "SIMID",
        "MRAID",
        "VPAID",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each creative, in one row",
          "caption": "A playable is not a SIMID preroll. vastlint checks the VAST side of SIMID. It does not execute MRAID.",
          "columns": [
            "Spec",
            "What the ad is",
            "Who owns playback",
            "Channel"
          ],
          "rows": [
            {
              "cells": [
                "SIMID",
                "A file beside the video",
                "The VAST player",
                "postMessage, sandboxed"
              ]
            },
            {
              "cells": [
                "MRAID",
                "The creative in the webview",
                "The app SDK's container",
                "mraid methods on the host"
              ]
            },
            {
              "cells": [
                "VPAID",
                "Often the player itself",
                "The executable",
                "A shared JavaScript context"
              ],
              "href": "/blog/vpaid-vs-mraid/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/simid-vs-mraid.png?v=2",
          "alt": "SIMID is a sandboxed interactive file beside a VAST media file. MRAID is the API a creative calls inside a mobile app webview.",
          "width": 1440,
          "height": 820,
          "caption": "A playable is not a SIMID preroll. vastlint checks the VAST side of SIMID. It does not execute MRAID.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "SIMID vs MRAID comes up when a mobile creative and a video creative share a brief. SIMID, Secure Interactive Media Interface Definition, is the interactive layer IAB separated from the media asset. The player plays a file it selected. The interactive document loads in a sandboxed frame and requests player operations over the SIMID channel. If the frame fails, the file can still play. IAB's SIMID page, updated January 3, 2024, describes SIMID 1.2 in those terms, including secure session IDs and explicit notes for squeeze-back layouts, and it names this split as the way to support mobile, SSAI, and OTT without handing the player to ad code.",
            "MRAID is older as an in-app idea and solves a different host. Since 2011 it has been how a rich-media creative talks to an app: expand, resize, interstitials, and, in 3.0, a stricter sense of viewability, audibility, and environment. The creative is the ad. There is no sibling MP4 the television can fall back to, because this path is not a television preroll. vastlint checks the VAST structures SIMID requires: InteractiveCreativeFile, a secure URL, and a media file beside it. It does not call mraid.getState, and it does not certify the SDK."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why the fallback in either direction fails",
          "paragraphs": [
            "A SIMID player that is handed an MRAID creative does not gain an overlay. The SIMID session expects the SIMID protocol. MRAID methods on the other side of that frame are a different bridge, and the player was not offering an app webview. The media file, if you included one, can still play. The interaction will not.",
            "An MRAID SDK that is handed a SIMID URL as if it were the creative HTML may render a document that immediately looks for a player channel that is not there. Playables and expandable banners are authored against MRAID on purpose. They are not a degraded SIMID. VPAID is not the tie-breaker. It is the deprecated video-player executable, and MRAID 3.0's use of selected VPAID events does not make the two creatives interchangeable."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where measurement sits, so it does not get folded in",
          "paragraphs": [
            "SIMID does not measure the impression. OMID does, through AdVerifications, once the player runs OM SDK. MRAID 3.0 lets the creative read viewability itself. That creative-side signal is not a third-party verification. A campaign that needs both an in-app playable and an in-stream spot needs both delivery paths, and the measurement on the in-stream spot still has to be in the VAST document.",
            "vastlint will tell you whether the in-stream document is structurally able to carry SIMID and OMID. It will not preview the playable, and it will not tell you that the playable satisfied MRAID 3.0."
          ]
        },
        {
          "type": "list",
          "heading": "Pick the host before the acronym",
          "items": [
            "In-stream: a VAST media file, SIMID only for a real interaction, OMID if a vendor must measure.",
            "In-app rich media or playable: MRAID, in an SDK that implements the calls the creative makes.",
            "Do not set apiFramework MRAID on a VAST media file and call it a SIMID alternative.",
            "Do not send a SIMID URL to an MRAID-only container and call it a video ad.",
            "Do not treat MRAID viewableChange as the OMID integration."
          ]
        },
        {
          "type": "quote",
          "quote": "A sidecar beside a file the player owns and a creative that is the ad inside an app webview do not degrade into each other.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "Check the VAST side of a SIMID creative",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab MRAID 3.0",
              "href": "https://iabtechlab.com/standards/mraid/",
              "description": "MRAID is the in-app rich media interface. Version 3.0 adds creative-side viewability and audibility, and selected VPAID events for in-app video reporting.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab Open Measurement SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "OM SDK page, updated November 4, 2025. Measurement providers collect signals through the OMID API. The current API docs listed there are OMID 1.6.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: SIMID support",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/simid-support",
              "description": "SIMID support is documented on its own page, including which messages the HTML5 SDK implements.",
              "source": "Google IMA"
            },
            {
              "label": "VPAID vs MRAID",
              "href": "/blog/vpaid-vs-mraid/",
              "description": "Why the older video API is not the in-app bridge.",
              "source": "vastlint"
            },
            {
              "label": "A SIMID alternative depends on the job",
              "href": "/blog/simid-alternative/",
              "description": "When the right answer is no interactive framework at all.",
              "source": "vastlint"
            },
            {
              "label": "SIMID reference",
              "href": "/docs/simid/",
              "description": "The element, the sandbox, and the media file that has to remain.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "omid-vs-mraid",
      "title": "OMID vs MRAID Compares a Third-Party Measurement API With the Creative's Own Container Events",
      "description": "OMID is how a verification vendor reads signals through OM SDK. MRAID 3.0 lets the creative itself read viewability and audibility, and it added selected VPAID events for in-app video. The creative reporting its own view is not a verification vendor. vastlint checks AdVerifications. It does not score viewability and it does not certify MRAID.",
      "seoTitle": "OMID vs MRAID lines up a verification script and the creative's own events",
      "seoDescription": "OMID is third-party measurement through OM SDK. MRAID viewability is the creative reporting itself. vastlint checks AdVerifications. It does not score viewability.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "OMID",
        "MRAID",
        "VPAID",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each signal, in one row",
          "caption": "The creative reporting its own viewability is not OMID. vastlint checks AdVerifications. It does not score viewability.",
          "columns": [
            "Spec",
            "Who reports",
            "About what",
            "In a VAST tag"
          ],
          "rows": [
            {
              "cells": [
                "OMID",
                "A verification script",
                "Viewability and other player signals",
                "AdVerifications"
              ]
            },
            {
              "cells": [
                "MRAID 3.0",
                "The creative",
                "Viewability, audibility, selected video events",
                "Not a VAST element"
              ]
            },
            {
              "cells": [
                "VPAID",
                "The executable",
                "Whatever the creative emits",
                "MediaFile apiFramework VPAID"
              ],
              "href": "/blog/vpaid-vs-omid/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/omid-vs-mraid.png?v=2",
          "alt": "OMID lets a verification vendor read signals through OM SDK. MRAID 3.0 lets the creative read viewability and audibility itself.",
          "width": 1440,
          "height": 820,
          "caption": "The creative reporting its own viewability is not OMID. vastlint checks AdVerifications. It does not score viewability.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "OMID vs MRAID is the measurement version of a host mix-up. OMID, the Open Measurement Interface Definition, is the API inside IAB's OM SDK. Players and apps that integrate the SDK expose signals. Measurement providers place scripts that collect them. IAB's OM SDK page, updated November 4, 2025, lists impression measurement, third-party verification, and a common integration across mobile, web, and CTV. The current API docs on that page are OMID 1.6. In a VAST tag the provider's script is declared under AdVerifications, or under a legacy Extension of that type.",
            "MRAID 3.0 gives the creative its own view of the container: viewability support so the creative can measure against industry thresholds, audibility, and selected VPAID events for in-app video reporting. The reporter is the ad. That can be useful for a playable that needs to know it is on screen. It is not a third party checking the ad. vastlint checks the shape of the VAST verification node, including vendor, resource URL, and apiFramework omid. It does not compute viewability, and it does not inspect an MRAID creative's event calls."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Why a creative-side viewable event keeps getting pasted into a verification slot",
          "paragraphs": [
            "VPAID trained the habit. The unit that played the ad also said it was viewable. MRAID 3.0's viewability feature can look like the modern form of that habit, because the creative again learns whether it is on screen. The difference IAB drew for video is that verification moves to OMID, where more than one provider can listen, and the creative is sandboxed away from the player if it is interactive SIMID. A single creative calling a viewableChange listener has one author: the party that shipped the ad.",
            "None of that makes MRAID false. An expandable in-app unit should use the container's viewability rather than guessing from a timer. The mistake is to delete AdVerifications from a VAST campaign because the mobile banner already had an MRAID viewability call. Those are two impressions, two hosts, and two reporters."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What vastlint will and will not settle",
          "paragraphs": [
            "On the VAST document, vastlint can show a missing verification vendor, an insecure script URL, a duplicated vendor, or a verification tracker that is not on verificationNotExecuted. Those are reasons the OMID path never starts. They are not a viewability score, and they are not an MRAID compliance result. IAB runs a separate compliance program for OM SDK integrations. An SDK can be MRAID-capable and still lack OM SDK.",
            "If the question is which verification firm to hire, that choice sits inside OMID. IAS, DoubleVerify, and the rest are scripts in the verification node. MRAID is not on that shortlist. vastlint will not rank the firms."
          ]
        },
        {
          "type": "list",
          "heading": "Keep the reporter attached to the right host",
          "items": [
            "In-stream measurement: OMID in AdVerifications, player has OM SDK.",
            "In-app creative behavior: MRAID, including its own viewability if the unit needs it.",
            "Do not treat MRAID viewableChange as the verification vendor.",
            "Do not treat a VPAID quartile as OMID.",
            "Do not expect vastlint to score either signal. It checks the VAST node that OMID would occupy."
          ]
        },
        {
          "type": "quote",
          "quote": "A creative that reports its own time in view and a third-party script that reads the player are not the same measurement.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "Check the verification node the OMID script would use",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab Open Measurement SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "OM SDK page, updated November 4, 2025. Measurement providers collect signals through the OMID API. The current API docs listed there are OMID 1.6.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab MRAID 3.0",
              "href": "https://iabtechlab.com/standards/mraid/",
              "description": "MRAID is the in-app rich media interface. Version 3.0 adds creative-side viewability and audibility, and selected VPAID events for in-app video reporting.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VPAID vs OMID",
              "href": "/blog/vpaid-vs-omid/",
              "description": "The older habit of letting the executable report itself.",
              "source": "vastlint"
            },
            {
              "label": "An OMID alternative is a vendor inside the API",
              "href": "/blog/omid-alternative/",
              "description": "What can replace a verification script.",
              "source": "vastlint"
            },
            {
              "label": "How to validate OMID in VAST tags",
              "href": "/blog/how-to-validate-omid-in-vast-tags/",
              "description": "The XML checks, before any viewability number exists.",
              "source": "vastlint"
            },
            {
              "label": "OMID reference",
              "href": "/docs/omid/",
              "description": "What the VAST side of OMID requires.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "simid-alternative",
      "title": "A SIMID Alternative Depends on Whether Anyone Has to Click",
      "description": "If the spot needs no interaction, the alternative to SIMID is a media file and no framework. If it needs a click on a player that implements SIMID, there is no second IAB interactive standard to swap in. VPAID is deprecated, OMID does not draw the unit, and MRAID is a different host. vastlint is not a SIMID player. It checks the nodes.",
      "seoTitle": "A SIMID alternative lines up the job and no second interactive standard",
      "seoDescription": "No click means a media file, not another framework. A click still means SIMID. VPAID, OMID, and MRAID are other jobs. vastlint checks the tag and does not play SIMID.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "SIMID",
        "VPAID",
        "OMID",
        "MRAID",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Each job someone might have meant",
          "caption": "vastlint is not a SIMID alternative. It checks the media file and the interactive node. It does not open a SIMID session.",
          "columns": [
            "Job",
            "What to ship",
            "What is not the alternative",
            "vastlint"
          ],
          "rows": [
            {
              "cells": [
                "Playback only",
                "A media file",
                "SIMID, VPAID, MRAID",
                "Checks the file is there"
              ]
            },
            {
              "cells": [
                "A click on video",
                "Media file plus SIMID",
                "VPAID as a fallback",
                "Checks the sidecar sits beside a file"
              ]
            },
            {
              "cells": [
                "Measurement",
                "OMID in AdVerifications",
                "SIMID, or a creative quartile",
                "Checks the verification node"
              ],
              "href": "/blog/omid-alternative/"
            },
            {
              "cells": [
                "In-app playable",
                "MRAID in an SDK",
                "A SIMID URL",
                "Does not certify MRAID"
              ],
              "href": "/blog/simid-vs-mraid/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/simid-alternative.png?v=2",
          "alt": "If the ad needs no interaction, the alternative to SIMID is a media file. If it needs interaction, SIMID stays the IAB interactive layer. VPAID, OMID, and MRAID answer other jobs.",
          "width": 1440,
          "height": 820,
          "caption": "vastlint is not a SIMID alternative. It checks the media file and the interactive node. It does not open a SIMID session.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "SIMID alternative is the search that appears when a platform will not load the interactive frame. The phrase treats SIMID as a product with substitutes. IAB's SIMID page describes one interactive standard: a layer separated from the media asset, both delivered by VAST 4.x, so the player keeps control of the stream. SIMID 1.2, noted on that page as of January 3, 2024, adds secure session IDs, a signal for unknown size, and explicit squeeze-back guidance. It does not name a second interactive framework to use when SIMID is unavailable.",
            "The honest alternative depends on the job. If nobody has to click, do not ship an interactive framework at all. A media file is the ad. If someone has to click and the player implements SIMID, SIMID is the interface, beside that file. VPAID is the deprecated executable, and Google's IMA docs limit VPAID 2 JavaScript to the HTML5 SDK, so it is not a safety net for the television that rejected SIMID. OMID measures. It does not draw the overlay. MRAID talks to an app webview, not to a VAST stitcher. vastlint is not a SIMID runtime and not a substitute creative. It checks whether the VAST 2.0–4.4 tag still has a playable file and a well-formed interactive node. It does not open the session."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What people paste in when they want a spare",
          "paragraphs": [
            "The spare is usually VPAID, because old sheets had a fallback row. Devices that implement SIMID already have a media file to play if you gave them one. Devices that implement neither, including most televisions and native players, will not run VPAID either. Offering the executable widens the set of things that can break and narrows the set of screens that can play the ad. IAB's replacement language is specific: OMID for measurement, SIMID for interactivity. A fallback row that reverses that order puts the deprecated object back on the path.",
            "The other spare is a vendor's interactive layer with a private apiFramework. That can be real on a platform that documents it. It is not SIMID, and it is not something vastlint will execute. The structural question stays the same. Is there a media file if the private layer fails, and is measurement still in AdVerifications rather than inside the layer?"
          ]
        },
        {
          "type": "paragraphs",
          "heading": "A platform that skips SIMID can still take the ad",
          "paragraphs": [
            "SSAI and a lot of CTV want the file and will ignore a sidecar they do not implement. That is a successful degradation only when the file exists. A tag whose only creative is the SIMID document has copied the VPAID failure mode into the new element: nothing to play if the interactive part is skipped. IAB's design note for SIMID is that the separation exists so those platforms can keep the stream. Use the separation. Do not delete the file to make the tag look simpler.",
            "Measurement survives the same cut only if OMID is in the document the player or the OM SDK integration actually sees. A SIMID alternative that drops AdVerifications has changed two jobs to solve one. vastlint catches the missing file and the missing verification node. It will not invent an interactive format the platform refused."
          ]
        },
        {
          "type": "list",
          "heading": "A usable answer to the search",
          "items": [
            "No interaction: media file only. SIMID is optional and should be absent.",
            "Interaction on a SIMID player: media file plus InteractiveCreativeFile.",
            "Platform will not load SIMID: keep the media file, drop the sidecar, do not add VPAID.",
            "Measurement: OMID, independent of whether the sidecar loaded.",
            "In-app playable: MRAID, as its own delivery, not as a renamed VAST file."
          ]
        },
        {
          "type": "quote",
          "quote": "The alternative to an interactive sidecar is often no sidecar, and the file the player already needed.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "See whether the tag still plays if the sidecar is ignored",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab Open Measurement SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "OM SDK page, updated November 4, 2025. Measurement providers collect signals through the OMID API. The current API docs listed there are OMID 1.6.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab MRAID 3.0",
              "href": "https://iabtechlab.com/standards/mraid/",
              "description": "MRAID is the in-app rich media interface. Version 3.0 adds creative-side viewability and audibility, and selected VPAID events for in-app video reporting.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: VPAID 2 JavaScript",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "Google IMA HTML5: SIMID support",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/simid-support",
              "description": "SIMID support is documented on its own page, including which messages the HTML5 SDK implements.",
              "source": "Google IMA"
            },
            {
              "label": "VPAID vs SIMID",
              "href": "/blog/vpaid-vs-simid/",
              "description": "Why the deprecated executable is not the spare.",
              "source": "vastlint"
            },
            {
              "label": "Is SIMID better than VPAID",
              "href": "/blog/is-simid-better-than-vpaid/",
              "description": "Better at the interactive job, and unnecessary when there is no click.",
              "source": "vastlint"
            },
            {
              "label": "How to validate SIMID",
              "href": "/blog/how-to-validate-simid-in-vast-tags/",
              "description": "The structural checks on the interactive file and the media beside it.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vpaid-alternative",
      "title": "A VPAID Alternative Is a Media File, SIMID When Someone Must Click, and OMID When Someone Must Measure",
      "description": "There is no single product that replaces VPAID. Playback is a media file the player decodes. Interaction is SIMID beside that file. Measurement is OMID in AdVerifications. MRAID is an in-app bridge, not the video-player replacement. vastlint is not a VPAID runtime. It checks that the executable is not the only file.",
      "seoTitle": "A VPAID alternative lines up a media file, SIMID, and OMID",
      "seoDescription": "Replace VPAID with a media file, SIMID only if there is a click, and OMID if a vendor must measure. vastlint checks that shape. It does not play the ad.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "VPAID",
        "SIMID",
        "OMID",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "The three replacements",
          "caption": "vastlint is not a VPAID runtime. It checks that the executable is not the only file. It does not play the ad.",
          "columns": [
            "Old VPAID job",
            "Replacement",
            "Element",
            "Leave it out when"
          ],
          "rows": [
            {
              "cells": [
                "Playback",
                "Media file",
                "MediaFile",
                "Never. Without it nothing plays"
              ]
            },
            {
              "cells": [
                "Click or overlay",
                "SIMID",
                "InteractiveCreativeFile",
                "The spot is not interactive"
              ],
              "href": "/blog/simid-alternative/"
            },
            {
              "cells": [
                "Viewability and verification",
                "OMID",
                "AdVerifications",
                "Nobody was hired to measure"
              ],
              "href": "/blog/omid-alternative/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vpaid-alternative.png?v=2",
          "alt": "A VPAID alternative is a playable media file, SIMID only when interaction is required, and OMID when a vendor must measure.",
          "width": 1440,
          "height": 820,
          "caption": "vastlint is not a VPAID runtime. It checks that the executable is not the only file. It does not play the ad.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "VPAID alternative is the search for one successor to an executable that used to do three jobs. IAB does not offer one successor. The SIMID page says VPAID is being replaced by OMID for measurement and verification and by SIMID for interactivity, with the interactive layer separated from the media asset and both delivered by VAST 4.x. The player keeps the file. That file is the part VPAID was allowed to swallow, and it is the part a television can still play.",
            "vastlint is not that alternative. It does not render a creative, execute JavaScript, or stand in for a player. It checks VAST 2.0–4.4 structure: a media file a player can select, SIMID only on an interactive file that has something beside it, and a verification node when the tag claims measurement. A green result means the document matches that split. It does not mean a particular TV ran the ad."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What fails if you replace the name and keep the shape",
          "paragraphs": [
            "A SIMID document as the only creative is the VPAID shape with a new apiFramework. Players that skip the sidecar, which is a normal SSAI outcome, then have nothing to splice. Google's IMA HTML5 page still documents VPAID 2 as an HTML5-only compatibility mode, which is a narrowing, not a recommendation to keep it as the universal spare. Shipping VPAID for the web row and SIMID for everyone else, inside one vast tag aimed at both, is two products. It is not a migration.",
            "Measurement has the same trap. A script that fires a quartile from inside the creative is the creative claiming it played. OMID is a verification resource the player's OM SDK can expose signals to. IAB's OM SDK page lists OMID 1.6 as the current API docs as of November 4, 2025. vastlint does not speak that API. It checks that the VAST resource pointing at a vendor script is present, secure, and not duplicated into nonsense."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "MRAID is not the video spare either",
          "paragraphs": [
            "MRAID 3.0 integrated selected VPAID events for in-app video reporting. Teams read that sentence as permission to treat MRAID as the VPAID alternative on mobile. The host is still an app webview. Expandables and playables belong there. A VAST preroll does not become one of them because the apiFramework string changed. If the campaign has both a playable and a preroll, they are two deliveries.",
            "The replacement shape in a VAST 4.3 inline is a media file, an optional SIMID file, and an optional OMID verification. browserOptional is the 4.3 detail on the verification script. Omit the SIMID file when there is no interaction. Omit the verification when nobody is measuring. Do not omit the media file."
          ]
        },
        {
          "type": "code",
          "heading": "The replacement shape in a VAST 4.3 inline",
          "language": "xml",
          "code": "<MediaFiles>\n  <MediaFile delivery=\"progressive\" type=\"video/mp4\" width=\"1280\" height=\"720\">\n    <![CDATA[https://cdn.example.com/ad.mp4]]>\n  </MediaFile>\n  <InteractiveCreativeFile type=\"text/html\" apiFramework=\"SIMID\">\n    <![CDATA[https://cdn.example.com/interactive.html]]>\n  </InteractiveCreativeFile>\n</MediaFiles>\n<AdVerifications>\n  <Verification vendor=\"measurement.example\">\n    <JavaScriptResource apiFramework=\"omid\" browserOptional=\"true\">\n      <![CDATA[https://cdn.example.com/omid.js]]>\n    </JavaScriptResource>\n  </Verification>\n</AdVerifications>"
        },
        {
          "type": "list",
          "heading": "Replace the job, not the acronym",
          "items": [
            "Always leave a media file the player can decode.",
            "Add SIMID only for a real interaction, as a sidecar.",
            "Add OMID only for a real measurement vendor, in AdVerifications.",
            "Treat a remaining VPAID file as legacy HTML5, not as the CTV copy.",
            "Keep MRAID on the in-app rich-media placement."
          ]
        },
        {
          "type": "quote",
          "quote": "Three jobs left the executable, and a single replacement string cannot carry all three back in.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "See whether a VPAID file is still the only creative",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab Open Measurement SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "OM SDK page, updated November 4, 2025. Measurement providers collect signals through the OMID API. The current API docs listed there are OMID 1.6.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab MRAID 3.0",
              "href": "https://iabtechlab.com/standards/mraid/",
              "description": "MRAID is the in-app rich media interface. Version 3.0 adds creative-side viewability and audibility, and selected VPAID events for in-app video reporting.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: VPAID 2 JavaScript",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "What replaced VPAID",
              "href": "/blog/what-replaced-vpaid/",
              "description": "The index of the split.",
              "source": "vastlint"
            },
            {
              "label": "VPAID is deprecated",
              "href": "/blog/vpaid-is-deprecated-stop-treating-it-like-a-fallback/",
              "description": "Why a VPAID fallback narrows the devices that can play.",
              "source": "vastlint"
            },
            {
              "label": "VPAID migration guide",
              "href": "/guides/vast-vpaid-migration/",
              "description": "The checklist for moving a live tag off the executable.",
              "source": "vastlint"
            },
            {
              "label": "VPAID reference",
              "href": "/docs/vpaid/",
              "description": "How the deprecated apiFramework shows up in XML.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "omid-alternative",
      "title": "An OMID Alternative Is Another Verification Script, Not a Different Measurement API",
      "description": "OMID is the measurement API inside OM SDK. Swapping vendors means swapping the script in AdVerifications. A VPAID quartile, an impression pixel, and an MRAID viewability event are the creative or the tag claiming measurement. vastlint checks the verification node. It does not run OM SDK and it does not measure the impression.",
      "seoTitle": "An OMID alternative lines up a vendor script and no second API",
      "seoDescription": "An OMID alternative is another vendor's script in AdVerifications, not VPAID or MRAID. vastlint checks that node. It does not measure the impression.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "OMID",
        "VPAID",
        "MRAID",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "What can stand in, and what cannot",
          "caption": "vastlint checks the verification node. It does not run OM SDK and it does not measure the impression.",
          "columns": [
            "Candidate",
            "What it actually is",
            "Replaces OMID?",
            "vastlint"
          ],
          "rows": [
            {
              "cells": [
                "Another vendor script",
                "OMID, different provider",
                "Yes, inside the same API",
                "Checks the new node"
              ]
            },
            {
              "cells": [
                "Impression pixel",
                "A beacon",
                "No",
                "Checks the URL is well formed"
              ]
            },
            {
              "cells": [
                "VPAID quartile",
                "The creative reporting itself",
                "No",
                "Flags the executable"
              ]
            },
            {
              "cells": [
                "MRAID viewableChange",
                "The in-app creative reporting itself",
                "No",
                "Does not see MRAID"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/omid-alternative.png?v=2",
          "alt": "An OMID alternative inside the standard is another verification vendor's script. A VPAID quartile, an impression pixel, and an MRAID viewability event are not that API.",
          "width": 1440,
          "height": 820,
          "caption": "vastlint checks the verification node. It does not run OM SDK and it does not measure the impression.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "OMID alternative usually means a verification contract is under review. The API is not what is under review. IAB's OM SDK page describes one interface: apps and players expose signals, and measurement providers place tags that collect them through OMID. The page, updated November 4, 2025, lists OMID 1.6 as the current API docs and keeps the earlier versions available. Changing from one accredited provider to another is a different JavaScriptResource in AdVerifications. It is the same apiFramework.",
            "vastlint is not an OMID alternative. It does not integrate OM SDK, collect viewability, or detect invalid traffic. It checks whether a VAST 2.0–4.4 document still contains a verification block a provider script could occupy: vendor, HTTPS resource, apiFramework, and a verificationNotExecuted path that can explain a miss. A player without OM SDK can still ignore a perfect block. The document check comes before that runtime question."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The things that look like measurement and are not the API",
          "paragraphs": [
            "An impression pixel says a URL was requested. It does not say what fraction of the pixels were on screen, and it does not let a second vendor listen. A VPAID unit that emits quartiles is the deprecated bundle, creative and meter in one executable, and Google limits VPAID 2 JavaScript to the IMA HTML5 SDK. MRAID 3.0 lets an in-app creative read viewability and audibility itself. The author of that signal is the creative. None of these occupy the OMID slot, and deleting AdVerifications because one of them exists removes the third-party path on purpose.",
            "Pre-4.1 tags sometimes carry the verification block as an Extension with type AdVerifications. That is a compatibility shape, not a different API. A 4.1 or later inline should use the AdVerifications element. vastlint knows both shapes well enough to tell you the node is missing or malformed. It does not know whether the vendor host still answers."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Choosing a firm is a different article",
          "paragraphs": [
            "IAS, DoubleVerify, Pixalate, and HUMAN publish different objects: cluster studies, protected-campaign rates, open-auction shares, pre-bid suggestions. Those comparisons do not pick an API. Whichever firm you hire for post-bid video measurement still has to be declared where the player expects a verification resource. Two firms means two Verification nodes, not two flavors of SIMID.",
            "SIMID remains the interactive sidecar, unrelated to which firm measures. Putting the vendor script inside the SIMID file collapses the split VPAID was retired for. Keep the script in AdVerifications even when the interactive file is elaborate."
          ]
        },
        {
          "type": "list",
          "heading": "Before calling something an OMID replacement",
          "items": [
            "The replacement script still uses apiFramework omid.",
            "It still sits in AdVerifications, or a legacy Extension of that type on older tags.",
            "An impression pixel stays a beacon.",
            "A VPAID quartile stays a creative event.",
            "An MRAID viewability call stays inside the app creative."
          ]
        },
        {
          "type": "quote",
          "quote": "You can change the firm that listens. You cannot replace the listening API with the creative's own report and still be talking about OMID.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "Check the node the next verification script would occupy",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab Open Measurement SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "OM SDK page, updated November 4, 2025. Measurement providers collect signals through the OMID API. The current API docs listed there are OMID 1.6.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab MRAID 3.0",
              "href": "https://iabtechlab.com/standards/mraid/",
              "description": "MRAID is the in-app rich media interface. Version 3.0 adds creative-side viewability and audibility, and selected VPAID events for in-app video reporting.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: VPAID 2 JavaScript",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "OMID vs MRAID",
              "href": "/blog/omid-vs-mraid/",
              "description": "Why the creative's own viewability event is not the API.",
              "source": "vastlint"
            },
            {
              "label": "VPAID vs OMID",
              "href": "/blog/vpaid-vs-omid/",
              "description": "Why a self-reported quartile is the old shape.",
              "source": "vastlint"
            },
            {
              "label": "How to validate OMID in VAST tags",
              "href": "/blog/how-to-validate-omid-in-vast-tags/",
              "description": "Vendor, resource, and verificationNotExecuted.",
              "source": "vastlint"
            },
            {
              "label": "OMID reference",
              "href": "/docs/omid/",
              "description": "The VAST side of the measurement API.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "is-simid-better-than-vpaid",
      "title": "SIMID Is Better Than VPAID Only When the Spot Needs a Sandboxed Click",
      "description": "SIMID is the better interactive layer because the player keeps the media file and the creative stays sandboxed, which is what IAB wrote it for. It is not better at being the player, and a non-interactive spot needs neither framework. vastlint does not score them. It shows whether the tag still depends on the executable.",
      "seoTitle": "Is SIMID better than VPAID lines up a job and no universal winner",
      "seoDescription": "SIMID is better when you need a sandboxed click beside a media file. Neither framework belongs on a spot with no interaction. vastlint checks the tag and does not score them.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "SIMID",
        "VPAID",
        "OMID",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Better at which job",
          "caption": "vastlint does not score the two frameworks. It shows whether the tag still depends on the executable.",
          "columns": [
            "Job",
            "SIMID",
            "VPAID",
            "Need either?"
          ],
          "rows": [
            {
              "cells": [
                "Sandboxed click",
                "This is the job",
                "Shared JavaScript context",
                "Only if someone must click"
              ]
            },
            {
              "cells": [
                "SSAI and CTV",
                "File can still be stitched",
                "Executable often will not run",
                "The file, not the framework"
              ]
            },
            {
              "cells": [
                "Measurement",
                "Use OMID instead",
                "Often bundled inside the unit",
                "OMID, separately"
              ]
            },
            {
              "cells": [
                "Being the player",
                "Refuses this",
                "Can do it, and that is the problem",
                "No"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/is-simid-better-than-vpaid.png?v=2",
          "alt": "SIMID is the better interactive layer because the player keeps the media file. A spot with no interaction needs neither framework.",
          "width": 1440,
          "height": 820,
          "caption": "vastlint does not score the two frameworks. It shows whether the tag still depends on the executable.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "Is SIMID better than VPAID is a ranking question aimed at two interfaces that do not want the same job. IAB's SIMID page says the industry is replacing VPAID with OMID for measurement and SIMID for interactivity, and that the point of SIMID is to separate the interactive layer from the media asset so publishers keep control of the stream, including SSAI and live. On that job, SIMID is the better design: if the sidecar fails, a real media file can still play, and the creative cannot reach into the player. VPAID can be the playback engine. When it fails, there is often no file left. Google's IMA docs add a runtime fact: only the HTML5 SDK supports VPAID 2 JavaScript creatives.",
            "That does not make SIMID the winner on every row of a trafficking sheet. A spot with no interaction needs a media file and no framework. Adding SIMID there adds a session the player must implement, for a click that does not exist. vastlint does not score the two. It checks VAST 2.0–4.4 structure and shows whether a VPAID file is still the only creative, or whether a SIMID file is missing the sibling media file that makes the newer design true. It does not execute either framework."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where VPAID still looks better on a lab machine",
          "paragraphs": [
            "A desktop HTML5 player that already runs VPAID will play a unit that draws its own controls and fires its own events. In that room, the executable looks more capable, because it was allowed to be the player. The capability is the liability everywhere else. A stitcher cannot preserve it. A television player does not offer the JavaScript context. A security review does not want ad code in the player's own context. IAB's deprecation is a statement about that spread, not a claim that old HTML5 sessions suddenly crash.",
            "SIMID 1.2, as described on the IAB page updated January 3, 2024, is explicit about session IDs, unknown creative size, and squeeze-back layouts. It is still a protocol a player must implement. Google documents a subset of SIMID messages for IMA HTML5. A tag that is structurally SIMID can still be outside a given player's subset. Better on the standard is not a promise about one SDK's message list."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "How to answer the question on a live tag",
          "paragraphs": [
            "Write the job down first. Interaction: SIMID beside a media file. Measurement: OMID, not either framework. Playback alone: the media file. Legacy HTML5 that still requires VPAID: an exception with the runtime named, not a default on the CTV copy. If the sheet asks for a single winner, it is asking to collapse those rows.",
            "Then look at the inline. Both strings can appear. Their presence is not a ranking. A VPAID file as the only media file loses on any player that will not run it. A SIMID file with no media file loses the advantage SIMID was written to have. vastlint is the check for that structure, not a vote."
          ]
        },
        {
          "type": "list",
          "heading": "A direct answer",
          "items": [
            "For a click beside a video the player controls: SIMID.",
            "For measurement: neither. Use OMID.",
            "For a non-interactive spot: neither. Use a media file.",
            "For being the playback engine: VPAID can, and that is why it was deprecated.",
            "For a score inside vastlint: there isn't one. The tool shows the structure."
          ]
        },
        {
          "type": "quote",
          "quote": "SIMID is better at the job it was given, which was to stop being the player.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "See which framework the inline still depends on",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: VPAID 2 JavaScript",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "Google IMA HTML5: SIMID support",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/simid-support",
              "description": "SIMID support is documented on its own page, including which messages the HTML5 SDK implements.",
              "source": "Google IMA"
            },
            {
              "label": "VPAID vs SIMID",
              "href": "/blog/vpaid-vs-simid/",
              "description": "The architectural comparison behind the ranking question.",
              "source": "vastlint"
            },
            {
              "label": "A VPAID alternative is three objects",
              "href": "/blog/vpaid-alternative/",
              "description": "What to ship instead of a winner string.",
              "source": "vastlint"
            },
            {
              "label": "VPAID and SIMID together",
              "href": "/blog/vpaid-and-simid-together/",
              "description": "Why listing both is not a way to get the better one.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vpaid-and-simid-together",
      "title": "VPAID and SIMID Together Are Two Runtimes, Not a Compatibility Plan",
      "description": "A VAST tag can declare a VPAID media file and a SIMID interactive file at once. Players that run SIMID still need a real media file, not a VPAID sibling. Players that only run VPAID will not run the sidecar. The set that matches the standards is a media file, SIMID when there is a click, and OMID when there is measurement. vastlint can see both apiFramework values. It does not execute either.",
      "seoTitle": "VPAID and SIMID together lines up two runtimes and no fallback",
      "seoDescription": "Shipping VPAID and SIMID together is two runtimes, not coverage. The working set is a media file, SIMID if needed, and OMID if needed. vastlint sees both strings and runs neither.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "VPAID",
        "SIMID",
        "OMID",
        "VAST"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Together, and what it fails to cover",
          "caption": "vastlint can see both apiFramework values in one inline. It does not execute either one.",
          "columns": [
            "What you ship",
            "Who can play it",
            "Who cannot",
            "What you meant"
          ],
          "rows": [
            {
              "cells": [
                "VPAID file only",
                "Some HTML5 players",
                "CTV, SSAI, native",
                "A creative"
              ]
            },
            {
              "cells": [
                "SIMID file only",
                "Nobody, if there is no media file",
                "Anyone who skips the sidecar",
                "A creative"
              ]
            },
            {
              "cells": [
                "VPAID and SIMID, no media file",
                "Whichever runtime happens to run",
                "The other runtime",
                "Coverage"
              ]
            },
            {
              "cells": [
                "Media file, optional SIMID, optional OMID",
                "Players that take the file",
                "Only the click, if SIMID is skipped",
                "The split IAB described"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vpaid-and-simid-together.png?v=2",
          "alt": "A VAST tag can declare VPAID and SIMID together. That is two runtimes. The working set is a media file, SIMID when interaction is required, and OMID when measurement is required.",
          "width": 1440,
          "height": 820,
          "caption": "vastlint can see both apiFramework values in one inline. It does not execute either one.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "VPAID and SIMID together is the compatibility idea that survives deprecation memos. The tag lists a VPAID media file for old web players and a SIMID interactive file for everyone else. IAB's SIMID page does not describe that pair as a fallback chain. It says VPAID is being replaced, OMID takes measurement, SIMID takes interactivity, and the interactive layer is separate from the media asset so the player keeps the stream. The asset is a media file. VPAID was allowed to be that asset. SIMID is not allowed to be that asset.",
            "A player that implements SIMID and finds no media file does not owe you a VPAID session as consolation. A player that only implements VPAID does not open the SIMID sidecar. You have two products in one response, and each audience misses one of them. vastlint checks both apiFramework values in a VAST 2.0–4.4 inline, and whether a non-executable file remains. It does not execute VPAID and it does not open a SIMID session. Seeing both strings is not a pass."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The together that matches the standards",
          "paragraphs": [
            "Media file, always, if you want the ad to play when interaction is skipped. SIMID, only when there is an interaction, as InteractiveCreativeFile with type text/html. OMID, only when a vendor must measure, in AdVerifications. That trio is the replacement. VPAID is absent from it. If a named HTML5 seat still requires VPAID, that is a separate tag or a documented exception, not a silent sibling on the CTV copy.",
            "Google publishes the two as separate HTML5 documents: VPAID 2 limited to the HTML5 SDK, and SIMID support with its own list of messages. A player can implement a subset of SIMID and none of VPAID. Counting on both to be present because both were in the XML overstates what either document promised."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Wrappers make the double declaration look like one creative",
          "paragraphs": [
            "Hop one can be a plain wrapper. The inline can carry VPAID as the media file and SIMID as a URL that 404s, or the reverse. QA that stops on the wrapper blesses the campaign. The player that unwraps finds out which half is real. Inspect the chain, then validate the inline you would actually serve.",
            "Measurement does not get to hide inside whichever half runs. If the VPAID unit used to carry the viewability script, moving that script into the SIMID file repeats the bundle. Put it in the verification node so it does not depend on which framework the player chose to ignore."
          ]
        },
        {
          "type": "list",
          "heading": "If both strings are in the inline",
          "items": [
            "Confirm a decodable media file exists that is neither framework.",
            "Treat the VPAID file as legacy HTML5, not as the spare for SIMID.",
            "Treat SIMID as optional interaction, not as the media.",
            "Keep OMID in AdVerifications.",
            "Do not read a structural pass as proof that both runtimes executed."
          ]
        },
        {
          "type": "quote",
          "quote": "Two frameworks in one response are two bets, and the screen that can run one of them was never the audience for the other.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "See both apiFramework values in the inline",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: VPAID 2 JavaScript",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "Google IMA HTML5: SIMID support",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/simid-support",
              "description": "SIMID support is documented on its own page, including which messages the HTML5 SDK implements.",
              "source": "Google IMA"
            },
            {
              "label": "Is SIMID better than VPAID",
              "href": "/blog/is-simid-better-than-vpaid/",
              "description": "Why the ranking still depends on the job.",
              "source": "vastlint"
            },
            {
              "label": "A VPAID alternative",
              "href": "/blog/vpaid-alternative/",
              "description": "The three objects that replace the pair.",
              "source": "vastlint"
            },
            {
              "label": "VPAID vs SIMID",
              "href": "/blog/vpaid-vs-simid/",
              "description": "Why they are not one fallback chain.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vast-vs-vpaid",
      "title": "VAST vs VPAID Compares the Ad Document With an Executable Inside It",
      "description": "VAST is the XML a player or stitcher parses. VPAID is a separate API that a VAST media file can point at with apiFramework VPAID. Deprecating VPAID does not deprecate VAST. SIMID and OMID are the replacements for the executable, still carried by VAST. vastlint validates the document and flags the VPAID file. It does not execute the script.",
      "seoTitle": "VAST vs VPAID lines up the document and an executable inside it",
      "seoDescription": "VAST is the XML ad response. VPAID is a deprecated executable a media file can reference. vastlint validates VAST and does not execute VPAID.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "VAST",
        "VPAID",
        "SIMID",
        "OMID"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Document and executable",
          "caption": "vastlint validates the VAST document and flags a VPAID media file. It does not execute the script.",
          "columns": [
            "Name",
            "What it is",
            "Status",
            "If you remove it"
          ],
          "rows": [
            {
              "cells": [
                "VAST",
                "The ad response",
                "Current, including 4.x",
                "There is no ad to traffic"
              ]
            },
            {
              "cells": [
                "VPAID",
                "JavaScript the response can reference",
                "Deprecated",
                "The document can still play a media file"
              ]
            },
            {
              "cells": [
                "SIMID",
                "Interactive file the response can reference",
                "The interactive replacement",
                "The media file can still play"
              ],
              "href": "/blog/vast-vs-simid/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vast-vs-vpaid.png?v=2",
          "alt": "VAST is the XML ad response. VPAID is a deprecated apiFramework on a media file inside that response.",
          "width": 1440,
          "height": 820,
          "caption": "vastlint validates the VAST document and flags a VPAID media file. It does not execute the script.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "VAST vs VPAID sounds like a choice of templates. It is a container and one thing the container used to hold. VAST, the Video Ad Serving Template, is the XML: which media to fetch, which tracking URLs to call, how wrappers chain, where a verification node sits. VPAID is a JavaScript API. A VAST document references it by putting apiFramework VPAID on a MediaFile. The player that supports it loads that resource and expects the VPAID interface. IAB's VAST standards hub marks VPAID deprecated and points the interactive job at SIMID. The document format stays.",
            "Deprecation of the executable is not a migration off VAST. SIMID and OMID are still declared inside VAST 4.x. A team that throws out the VAST tag because VPAID is deprecated has thrown out the file, the trackers, and the verification along with the script. vastlint validates the VAST document from 2.0 through 4.4 and can show that a media file is VPAID, that no decodable sibling remains, and that verification is missing. It does not execute the script. A longer reference lives at the VPAID vs VAST doc. This note is the short comparison."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What each one can be wrong about",
          "paragraphs": [
            "A valid-looking VAST document can still be the wrong ad: wrong duration, empty tracking URL, wrapper that never resolves. That is a VAST problem, and it exists on tags that never mention VPAID. A VPAID problem is narrower. The document may be well formed and still offer only an executable that CTV and SSAI will not run. Google's IMA docs limit VPAID 2 JavaScript to the HTML5 SDK. Both problems can be true of one response. Fixing the XML schema errors does not remove the executable. Removing the executable does not fill an empty impression URL.",
            "People also say VPAID when they mean any interactive video. The current interactive declaration is SIMID on InteractiveCreativeFile, beside a media file. The current measurement declaration is OMID in AdVerifications. Neither one replaces the VAST element that wraps them."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "How to read a tag that mentions both",
          "paragraphs": [
            "If the root is VAST and a media file says VPAID, you have a current document carrying a deprecated creative. Keep the document. Replace the creative with a media file, add SIMID only for a real interaction, and add OMID only for a real vendor. If someone offers a VPAID unit with no VAST at all, you do not have an ad response a stitcher can parse. You have a script.",
            "Wrappers are still VAST. The VPAID file is often on the last inline, not on the wrapper QA opened. vastlint's inspector follows that chain. The validator then checks the document you unwrap to. Neither step runs the creative."
          ]
        },
        {
          "type": "list",
          "heading": "Keep the names in their places",
          "items": [
            "VAST is the response you traffic.",
            "VPAID is an optional, deprecated media file inside it.",
            "SIMID is an optional interactive file inside it.",
            "OMID is an optional verification resource inside it.",
            "Removing VPAID does not mean removing VAST."
          ]
        },
        {
          "type": "quote",
          "quote": "The template and the executable were never competing formats, and only one of them was deprecated.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the document, including any VPAID file it still carries",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: VPAID 2 JavaScript",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/vpaid2js",
              "description": "Only the IMA HTML5 SDK supports VPAID 2 JavaScript creatives.",
              "source": "Google IMA"
            },
            {
              "label": "VPAID vs VAST",
              "href": "/docs/vpaid-vs-vast/",
              "description": "The longer reference this note compresses.",
              "source": "vastlint"
            },
            {
              "label": "What replaced VPAID",
              "href": "/blog/what-replaced-vpaid/",
              "description": "SIMID, OMID, and the media file, still inside VAST.",
              "source": "vastlint"
            },
            {
              "label": "VAST vs SIMID",
              "href": "/blog/vast-vs-simid/",
              "description": "The same container question for the interactive replacement.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vast-vs-simid",
      "title": "VAST vs SIMID Compares the Ad Document With One Interactive File It Can Point At",
      "description": "VAST is the XML response. SIMID is an interactive creative that response can reference from InteractiveCreativeFile, beside a media file the player owns. SIMID does not replace VAST. A SIMID URL with no media file is an incomplete ad. vastlint validates the document, including that sibling file. It does not open a SIMID session.",
      "seoTitle": "VAST vs SIMID lines up the document and a sidecar inside it",
      "seoDescription": "VAST is the ad document. SIMID is an interactive file inside it, beside a media file. vastlint checks that shape. It does not open a SIMID session.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "VAST",
        "SIMID",
        "VPAID",
        "OMID"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Document and sidecar",
          "caption": "vastlint validates the document, including whether the SIMID node has a sibling media file. It does not open a SIMID session.",
          "columns": [
            "Name",
            "What it is",
            "Required for a basic ad",
            "If it fails"
          ],
          "rows": [
            {
              "cells": [
                "VAST",
                "The response",
                "Yes",
                "Nothing is trafficked"
              ]
            },
            {
              "cells": [
                "Media file",
                "Playback inside the response",
                "Yes",
                "Nothing plays"
              ]
            },
            {
              "cells": [
                "SIMID",
                "Interaction inside the response",
                "Only when there is a click",
                "The file can still play"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vast-vs-simid.png?v=2",
          "alt": "VAST is the XML document. SIMID is an interactive file that document can reference beside a media file.",
          "width": 1440,
          "height": 820,
          "caption": "vastlint validates the document, including whether the SIMID node has a sibling media file. It does not open a SIMID session.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "VAST vs SIMID is the same category error as VAST vs VPAID, aimed at the replacement. VAST is the document a player or a stitcher requests: media files, trackers, wrappers, icons, verification. SIMID is one interactive resource that document may name. IAB's SIMID page says the interactive layer and the media asset are both delivered by VAST 4.x, separated so the player keeps the stream. SIMID 1.2, described there as of January 3, 2024, is a protocol between that player and a sandboxed creative. It is not a new ad-serving template.",
            "A campaign cannot switch from VAST to SIMID. It can add SIMID to a VAST inline, or it can leave SIMID out. vastlint validates the VAST document, including whether an InteractiveCreativeFile that says SIMID has a type, a secure URL, and a media file beside it. It does not open a SIMID session, and a session that fails in a particular player's message subset can still belong to a document vastlint accepted."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The incomplete form",
          "paragraphs": [
            "The failure that looks like a modern tag is a SIMID URL and no media file. The apiFramework is current. The player that skips unknown interactive files, which stitchers do, has no bytes to insert. That is the VPAID failure mode with the deprecated name removed. IAB's reason for the split was to avoid it. The check is the sibling MediaFile, not the presence of the letters SIMID.",
            "Measurement is a third element, still inside VAST. OMID lives in AdVerifications. It is not part of the SIMID file, and it is not an alternative template either. A comparison that offers VAST, SIMID, and OMID as three choices of format has listed a document, a sidecar, and a measurement API."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Version and player limits stay on their own lines",
          "paragraphs": [
            "SIMID is a VAST 4.x interactive creative in IAB's description. Older VAST versions in the wild still carry VPAID instead. vastlint reads 2.0 through 4.4 so a wrapper on an old version and an inline on a new one are both visible. Support for SIMID messages is a player fact. Google's IMA HTML5 guide lists what that SDK implements. A document can be ahead of a player, or a player can be ahead of a sloppy document. Those are different defects.",
            "If the question is which template to traffic, the answer is VAST. If the question is whether this VAST response includes a sound interactive layer, look for the media file first and the SIMID file second."
          ]
        },
        {
          "type": "list",
          "heading": "Read the response in that order",
          "items": [
            "A VAST root and an inline the player will actually fetch.",
            "A media file selected without JavaScript.",
            "SIMID only if the creative has an interaction.",
            "OMID only if a vendor is measuring, outside the SIMID file.",
            "No assumption that a valid document has executed the sidecar."
          ]
        },
        {
          "type": "quote",
          "quote": "The document can point at the sidecar, and the sidecar does not become the document.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the VAST response the SIMID file sits in",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "Google IMA HTML5: SIMID support",
              "href": "https://developers.google.com/interactive-media-ads/docs/sdks/html5/client-side/simid-support",
              "description": "SIMID support is documented on its own page, including which messages the HTML5 SDK implements.",
              "source": "Google IMA"
            },
            {
              "label": "VAST vs VPAID",
              "href": "/blog/vast-vs-vpaid/",
              "description": "The same container question for the deprecated executable.",
              "source": "vastlint"
            },
            {
              "label": "A SIMID alternative",
              "href": "/blog/simid-alternative/",
              "description": "When the sidecar should be absent.",
              "source": "vastlint"
            },
            {
              "label": "SIMID reference",
              "href": "/docs/simid/",
              "description": "Element, sandbox, and examples.",
              "source": "vastlint"
            },
            {
              "label": "How to validate SIMID in VAST tags",
              "href": "/blog/how-to-validate-simid-in-vast-tags/",
              "description": "The structural checks.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vast-vs-omid",
      "title": "VAST vs OMID Compares the Ad Document With the Measurement API a Verification Script Uses",
      "description": "VAST declares the ad, including a verification resource. OMID is the API that resource uses after a player with OM SDK exposes signals. OMID does not describe the creative, and VAST does not by itself measure viewability. vastlint checks the verification block. It does not run OM SDK.",
      "seoTitle": "VAST vs OMID lines up the document and the measurement API",
      "seoDescription": "VAST carries the verification node. OMID is the API a player exposes through OM SDK. vastlint checks the node. It does not run OM SDK.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "VAST",
        "OMID",
        "SIMID",
        "Ad verification"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Document and API",
          "caption": "vastlint checks the VAST verification block. It does not run OM SDK.",
          "columns": [
            "Name",
            "Role",
            "Where you see it",
            "What it does not do"
          ],
          "rows": [
            {
              "cells": [
                "VAST",
                "Describe and deliver the ad",
                "The XML response",
                "Prove viewability"
              ]
            },
            {
              "cells": [
                "OMID",
                "Let a vendor read player signals",
                "A script the XML points at",
                "Describe the creative"
              ]
            },
            {
              "cells": [
                "OM SDK",
                "The integration that speaks OMID",
                "The player or the app",
                "Appear as a VAST element"
              ]
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vast-vs-omid.png?v=2",
          "alt": "VAST declares a verification resource. OMID is the API that resource uses after the player exposes OM SDK.",
          "width": 1440,
          "height": 820,
          "caption": "vastlint checks the VAST verification block. It does not run OM SDK.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "VAST vs OMID shows up when a measurement requirement gets written down as a format choice. VAST is the ad response. From 4.1 it has an AdVerifications element so the response can name verification resources. Older responses sometimes use an Extension with that type. OMID is not a sibling template. It is the API those resources speak once a player or app has integrated OM SDK. IAB's OM SDK page, updated November 4, 2025, says integrators send signals to OMID and providers place tags that collect them. The current API docs listed there are OMID 1.6.",
            "A VAST document with a perfect verification block is not a viewability result. A player without OM SDK will not produce one, no matter how clean the XML is. An OMID session with no VAST at all is a different integration, common in some app SDKs, and it is not this tool's document. vastlint checks the VAST side: the verification envelope, the vendor, the resource URL, apiFramework omid, and the tracking that explains a script that never ran. It does not run OM SDK and it does not measure the impression."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What people substitute for the API",
          "paragraphs": [
            "Quartile trackers in VAST are playhead events. They are not OMID. An impression URL is a beacon. SIMID is the interactive sidecar and does not become measurement by sitting next to the media file. VPAID could emit all of these from inside the creative, which is the bundle OMID was meant to end. Keeping a VPAID unit because it already sends a quartile is a decision to skip the API, not a VAST-versus-OMID compromise.",
            "Vendor choice is inside the verification node. Two providers means two Verification entries, both OMID, both in the same VAST document. vastlint can see a duplicated vendor identifier and an insecure script URL. It cannot see which firm's number you should believe."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "The order of work",
          "paragraphs": [
            "Traffic a VAST response that includes the verification block your contract requires. Confirm the player on that path integrates OM SDK for the version your provider needs. Then argue about viewability. Reversing the order produces a measured-looking dashboard for a tag that dropped the node in a wrapper, or a beautiful node on a player that never loads it.",
            "Wrappers are the usual drop. The first hop still shows AdVerifications in the trafficker's copy. A later inline omits it and the impression still fires. The OMID script never had a URL to load. That is a VAST defect with a measurement consequence. vastlint is aimed at the defect."
          ]
        },
        {
          "type": "list",
          "heading": "Separate the layers before the meeting",
          "items": [
            "VAST is the response, including the verification declaration.",
            "OM SDK is the player integration.",
            "OMID is the API those two meet on.",
            "Quartiles, impression pixels, and SIMID are none of the three.",
            "A valid verification block is not a viewability percentage."
          ]
        },
        {
          "type": "quote",
          "quote": "The document can point at a measurement script, and the document is not the measurement.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "Check the verification block inside the VAST response",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab Open Measurement SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "OM SDK page, updated November 4, 2025. Measurement providers collect signals through the OMID API. The current API docs listed there are OMID 1.6.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "An OMID alternative is another script",
              "href": "/blog/omid-alternative/",
              "description": "Vendor swaps stay inside the API.",
              "source": "vastlint"
            },
            {
              "label": "How to validate OMID in VAST tags",
              "href": "/blog/how-to-validate-omid-in-vast-tags/",
              "description": "What the XML check covers.",
              "source": "vastlint"
            },
            {
              "label": "OMID reference",
              "href": "/docs/omid/",
              "description": "AdVerifications and the limits of a structural check.",
              "source": "vastlint"
            },
            {
              "label": "VAST vs SIMID",
              "href": "/blog/vast-vs-simid/",
              "description": "The interactive file is a third name, not a third template.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "vast-vs-mraid",
      "title": "VAST vs MRAID Compares a Video Ad Response With an In-App Webview Bridge",
      "description": "VAST is XML a video or audio player parses. MRAID is how a rich-media creative talks to a mobile app SDK. A VAST tag is not an MRAID creative, and an MRAID playable is not a VAST inline. vastlint validates VAST. It does not render MRAID.",
      "seoTitle": "VAST vs MRAID lines up a video ad response and an in-app bridge",
      "seoDescription": "VAST is a video ad response. MRAID is an in-app webview bridge. vastlint validates VAST and does not render MRAID.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "VAST",
        "MRAID",
        "SIMID",
        "VPAID"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Two deliveries",
          "caption": "vastlint validates VAST. It does not render MRAID.",
          "columns": [
            "Name",
            "Who loads it",
            "Typical unit",
            "Interactive add-on"
          ],
          "rows": [
            {
              "cells": [
                "VAST",
                "A player or a stitcher",
                "In-stream video or audio",
                "SIMID, beside a media file"
              ]
            },
            {
              "cells": [
                "MRAID",
                "An app SDK webview",
                "Expandable, interstitial, playable",
                "The creative itself"
              ]
            },
            {
              "cells": [
                "VPAID",
                "A browser-like video player",
                "Legacy executable",
                "It was the add-on and the media"
              ],
              "href": "/blog/vpaid-vs-mraid/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/vast-vs-mraid.png?v=2",
          "alt": "VAST is an ad response a video player parses. MRAID is the bridge between a rich-media creative and a mobile app SDK.",
          "width": 1440,
          "height": 820,
          "caption": "vastlint validates VAST. It does not render MRAID.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "VAST vs MRAID is a delivery question, not a version question. VAST is the response a video or audio player fetches: a URL or a blob of XML describing media files and tracking. A stitcher can parse it without showing a webview. MRAID is the Mobile Rich Media Ad Interface Definitions, the bridge a creative uses inside an in-app webview. IAB's MRAID 3.0 note covers expand, resize, interstitials, creative-side viewability and audibility, and selected VPAID events so in-app video can report more consistently. The creative is loaded by the SDK. It is not a VAST root element.",
            "You do not convert one into the other by changing an extension. A playable that calls MRAID will not become a preroll because someone wrapped the HTML in a VAST media file and set an apiFramework. A VAST MP4 will not become an expandable banner because the line item sits in an app. vastlint validates the VAST document against published rules for 2.0 through 4.4. It does not load the creative in a webview, and it does not certify MRAID 3.0."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Where the campaigns actually overlap",
          "paragraphs": [
            "A single buy can include an in-stream video and an in-app playable. Those are two creatives and two specs. The video creative's interaction, if any, is SIMID inside VAST. The playable's container API is MRAID. Measurement on the video side is OMID in AdVerifications. Measurement on the playable is whatever the SDK and the MRAID creative expose, which is not automatically the same log.",
            "The overlap that causes bad tags is vocabulary. MRAID 3.0 borrowed VPAID event names. People then set VAST apiFramework to MRAID or to VPAID and expect the app to sort it out. The app's MRAID container and the app's VAST player, when both exist, are still different entry points. vastlint only sees the VAST entry point."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "What to send each team",
          "paragraphs": [
            "Send the video trafficker a VAST tag with a media file, SIMID only if the video has a click layer, and OMID if video measurement was sold. Send the in-app creative team an MRAID asset matched to the SDK's version. Do not send either team the other team's file as a backup.",
            "If the only artifact in the ticket is a VAST URL, MRAID is out of scope until a second asset appears. Validate the URL. Do not describe that validation as an MRAID result. vastlint's scope is the sentence that keeps the excerpt honest."
          ]
        },
        {
          "type": "list",
          "heading": "Decide which file you are holding",
          "items": [
            "XML with a VAST root: validate it as VAST.",
            "HTML that calls MRAID: that is the in-app creative, outside this validator.",
            "A VAST media file whose apiFramework says MRAID: still check for a decodable file, and do not call it an MRAID certification.",
            "Both assets in one campaign: two checks, two hosts.",
            "VPAID in the VAST file: deprecated video executable, not the MRAID bridge."
          ]
        },
        {
          "type": "quote",
          "quote": "A video ad response and an in-app webview bridge can share a campaign and still cannot share a file.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the VAST response",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab MRAID 3.0",
              "href": "https://iabtechlab.com/standards/mraid/",
              "description": "MRAID is the in-app rich media interface. Version 3.0 adds creative-side viewability and audibility, and selected VPAID events for in-app video reporting.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VPAID vs MRAID",
              "href": "/blog/vpaid-vs-mraid/",
              "description": "The executable people confuse with the in-app bridge.",
              "source": "vastlint"
            },
            {
              "label": "An MRAID alternative depends on the unit",
              "href": "/blog/mraid-alternative/",
              "description": "When in-stream video should leave MRAID.",
              "source": "vastlint"
            },
            {
              "label": "VAST vs SIMID",
              "href": "/blog/vast-vs-simid/",
              "description": "The interactive layer that does belong inside VAST.",
              "source": "vastlint"
            }
          ]
        }
      ]
    },
    {
      "slug": "mraid-alternative",
      "title": "An MRAID Alternative Depends on Whether the Unit Is a Playable or a Video Ad",
      "description": "Expandable in-app rich media and playables still speak MRAID. In-stream video should arrive as VAST, with a media file, SIMID only if someone must click, and OMID if a vendor must measure. VPAID is not the video alternative. vastlint validates the VAST document. It does not certify MRAID 3.0.",
      "seoTitle": "An MRAID alternative lines up a playable and a video ad",
      "seoDescription": "Playables stay on MRAID. In-stream video moves to VAST, SIMID, and OMID. vastlint validates the VAST document and does not certify MRAID.",
      "publishedAt": "2026-09-29",
      "author": "Alex Sekowski",
      "readingTime": "7 min read",
      "heroKicker": "Standards",
      "tags": [
        "MRAID",
        "VAST",
        "SIMID",
        "VPAID",
        "OMID"
      ],
      "published": true,
      "featured": false,
      "body": [
        {
          "type": "table",
          "heading": "Which job the search meant",
          "caption": "vastlint validates the VAST document. It does not certify MRAID 3.0.",
          "columns": [
            "Unit",
            "Stay or leave",
            "What you ship",
            "vastlint"
          ],
          "rows": [
            {
              "cells": [
                "Expandable or playable",
                "Stay",
                "MRAID in an SDK webview",
                "Does not certify it"
              ]
            },
            {
              "cells": [
                "In-stream video",
                "Leave",
                "VAST, media file, optional SIMID, optional OMID",
                "Validates the VAST"
              ]
            },
            {
              "cells": [
                "Legacy VPAID video",
                "Leave",
                "The same VAST split, not MRAID",
                "Flags the executable"
              ],
              "href": "/blog/vpaid-alternative/"
            }
          ]
        },
        {
          "type": "image",
          "src": "/blog/img/mraid-alternative.png?v=2",
          "alt": "An MRAID alternative for in-stream video is a VAST tag with a media file, SIMID only if the ad is interactive, and OMID if a vendor must measure. Expandable in-app units still use MRAID.",
          "width": 1440,
          "height": 820,
          "caption": "vastlint validates the VAST document. It does not certify MRAID 3.0.",
          "credit": "Diagram by vastlint.org. An independent open-source project. The diagram restates figures already cited in this post."
        },
        {
          "type": "paragraphs",
          "paragraphs": [
            "MRAID alternative is an ambiguous search, because MRAID was built so a rich-media creative could run across apps without a new container API per SDK. IAB's MRAID 3.0 note still describes that job: expand, resize, interstitials, viewability and audibility for the creative, a standardized close, and selected VPAID events for in-app video reporting. For an expandable banner or a playable, the alternative to MRAID is often a proprietary SDK call, which is the fragmentation MRAID was written to reduce. vastlint has nothing to certify on that creative. It does not implement the bridge.",
            "The other meaning, and the one this site can actually help with, is a video line that was forced through an in-app HTML unit. In-stream video has a document already: VAST. Interaction on that video is SIMID, beside a media file, not a renamed MRAID creative. Measurement is OMID in AdVerifications. VPAID is the deprecated video executable, not the upgrade path out of MRAID and not the upgrade path into it. vastlint checks that VAST 2.0–4.4 shape. It does not render the playable you decided to keep."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "Do not use the borrowed events as a migration map",
          "paragraphs": [
            "MRAID 3.0 says selected VPAID events are part of in-app video reporting. That sentence lets a video creative inside the webview emit a familiar quartile. It does not say a VAST player should load MRAID, and it does not say an MRAID container should load VPAID. The hosts stay different. A quartile with a familiar name can still be the creative talking to the SDK, which is a different log from an OMID verification script.",
            "If the SDK vendor offers a private rich-media API as the MRAID alternative, judge it as a container, the way you would judge MRAID: does the placement need expand and a webview, or does it need a media file in a video player? vastlint will not score that private API either."
          ]
        },
        {
          "type": "paragraphs",
          "heading": "A practical split for the ticket",
          "paragraphs": [
            "Label the unit before you pick a spec. Playable or expandable in-app: MRAID, or the SDK's documented container, and a test harness that actually loads MRAID. In-stream, including in-app video that plays in a player: VAST. Add SIMID only for a real click layer. Add OMID only for a hired verification vendor. Remove VPAID from the default path.",
            "Paste the VAST half into vastlint. Send the MRAID half to whatever preview the SDK expects. One green result does not cover both files. A pass on the VAST document is a VAST check. It is not an MRAID certification."
          ]
        },
        {
          "type": "list",
          "heading": "Answer the search by the unit",
          "items": [
            "Playable or expandable: MRAID remains the in-app interface to compare other containers against.",
            "In-stream video: VAST plus a media file.",
            "A click on that video: SIMID, not MRAID.",
            "A third-party measurement: OMID, not the creative's viewableChange.",
            "A VPAID file: legacy, not the bridge between these."
          ]
        },
        {
          "type": "quote",
          "quote": "The alternative is a different delivery when the unit is a video ad, and a different container when the unit is a playable.",
          "attribution": "standards triage note"
        },
        {
          "type": "cta",
          "heading": "Validate the VAST half of the campaign",
          "paragraph": "Run VAST 2.0–4.4 tags against specification-derived rules. Nothing is stored. vastlint does not execute VPAID, open a SIMID session, run OMID, or certify an MRAID SDK.",
          "href": "/validate/",
          "label": "Open the VAST validator"
        },
        {
          "type": "resources",
          "heading": "Sources",
          "items": [
            {
              "label": "IAB Tech Lab MRAID 3.0",
              "href": "https://iabtechlab.com/standards/mraid/",
              "description": "MRAID is the in-app rich media interface. Version 3.0 adds creative-side viewability and audibility, and selected VPAID events for in-app video reporting.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab VAST",
              "href": "https://iabtechlab.com/standards/vast/",
              "description": "VAST standards hub. VPAID is marked deprecated and replaced with SIMID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab SIMID",
              "href": "https://iabtechlab.com/standards/simid/",
              "description": "SIMID page, updated January 3, 2024. SIMID 1.2 separates the interactive layer from the media asset. Both are delivered by VAST 4.x. OMID is named for measurement and SIMID for interactivity, as the replacement for VPAID.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "IAB Tech Lab Open Measurement SDK",
              "href": "https://iabtechlab.com/standards/open-measurement-sdk/",
              "description": "OM SDK page, updated November 4, 2025. Measurement providers collect signals through the OMID API. The current API docs listed there are OMID 1.6.",
              "source": "IAB Tech Lab"
            },
            {
              "label": "VAST vs MRAID",
              "href": "/blog/vast-vs-mraid/",
              "description": "Why the two files are not backups.",
              "source": "vastlint"
            },
            {
              "label": "SIMID vs MRAID",
              "href": "/blog/simid-vs-mraid/",
              "description": "The sidecar versus the webview creative.",
              "source": "vastlint"
            },
            {
              "label": "A VPAID alternative",
              "href": "/blog/vpaid-alternative/",
              "description": "What replaces the executable on the video path.",
              "source": "vastlint"
            }
          ]
        }
      ]
    }
  ]
}
