Blog · CTV
A CTV app delisted from the store can still bid. The auction keys on bundle ID, not shelf status.
On August 14, a vendor published an expanded CTV app pre-bid blocklist built from daily monitoring of 378,622 app-platform pairs across nine operating systems, covering 52,102 unique apps. One of nine risk reason codes is delistedApp: apps removed from official stores that continue to generate ad traffic. That code exists because the programmatic path and the app store path diverge. A bid request can look well formed while the inventory it claims no longer exists on any shelf buyers could verify.
What the auction actually sees
OpenRTB identifies application inventory through app.bundle, the store identifier, and optionally app.storeurl, app.name, and app.publisher. None of those fields assert that the app is currently listed, maintained, authorized in app-ads.txt, or compliant with store terms. They are claims about identity, not about eligibility.
Delisting is a store-side event. A Roku channel pulled for policy violation, a Fire TV app abandoned after three years without an update, an Android TV package removed from Google Play: each removes the public proof that the app is a legitimate publisher surface. Devices that already installed the app, sideloaded builds, and fraud operators spoofing bundle IDs can still emit bid requests. SSPs and exchanges that do not reconcile bundle against live store metadata will keep auctioning the name long after the store stopped standing behind it.
That is not a hypothetical edge case in the August blocklist announcement. The delistedApp reason code is explicit: apps removed from app stores that continue to generate ad traffic. The same feed also flags missing app-ads.txt (inventory generating impressions without an authorization file), abandoned apps (no developer update in three or more years), apps with General Invalid Traffic above 5 percent or Sophisticated Invalid Traffic above 15 percent over a rolling three-month window, and made-for-advertising placement patterns. Delisting sits beside IVT thresholds, not inside them.
Why impression-level IVT misses it
The announcement draws a line the industry has been blurring: app-level structural risk versus impression-level invalid traffic classification. Under Media Rating Council guidance on invalid traffic detection and filtration, known dangerous or fraudulent sources can be handled as lists separate from per-impression measurement. Impressions from apps on a high-risk list are not automatically counted as IVT; IVT applies when impression-level invalid signals fire on that specific event.
That separation matters for buyers who treat a low post-bid IVT rate as proof of clean supply. A delisted app can still serve real devices with real IPs. The fraud is in the inventory claim, not necessarily in every beacon. Waiting for impression-level classification means paying for some fraction of requests before the pattern shows up in post-bid filters, and it means conflating two decisions: whether this app should ever be in the auction, and whether this particular impression looks bot-like.
Pre-bid blocklists invert the order. Exclude flagged bundle and store pairs before pricing. The August feed ships daily through RTB fabric APIs, FTP, and object storage, keyed by bundle ID with platform metadata and one or more reason codes per row. Buyers can block all nine codes or only delisted and missing app-ads.txt if that matches their compliance posture.
The mechanism on the bidstream
Supply-path checks most teams already run, ads.txt and app-ads.txt against schain nodes, sellers.json lookups, MFA domain lists, do not ask whether the bundle is still published. A delisted app can fail app-ads.txt for a different reason (missing file) or pass authorization on a domain while the store listing is gone. The blocklist is an orthogonal signal: store and compliance telemetry merged into an app ID deny list.
// Typical CTV bid request fragment
"app": {
"bundle": "com.example.streamtv", // identity claim
"storeurl": "https://...", // may 404 after delisting
"publisher": { "id": "..." }
}
// Nothing here answers: is this bundle live in the store today?
// Pre-bid blocklist: match bundleId + platform → delistedApp → no-bidSSPs can enforce at ingress: drop requests whose bundle-platform pair appears on the feed. DSPs can filter in the bidder before sending a seatbid. Exchanges sitting in the middle need a policy for whether they pass reason codes downstream or silently suppress. Either way, the fix is upstream of creative delivery; no VAST validator on the response side learns that the app should not have been in the auction.
Coverage is uneven by platform. The source notes that risk type coverage differs across CTV operating systems based on each platform's transparency and metadata availability. Roku, Fire TV, Samsung, Apple TV, LG webOS, and others do not expose the same store APIs. A blocklist is only as current as the vendor's crawl cadence. That is still faster than discovering delisted inventory through monthly IVT reconciliation.
What to do
- Subscribe to an app-level deny feed if you buy CTV programmatically. Impression IVT and app blocklists solve different failures. You need both if delisted and unauthorized apps are in your supply mix.
- Log
app.bundleand platform on every CTV request you sell. When a buyer disputes inventory, you cannot correlate to a blocklist row without those fields populated consistently across resold paths. - Cross-check app-ads.txt on ingress, not only in quarterly audits. Missing app-ads.txt is its own reason code in the same schema; unauthorized and delisted often overlap in the wild.
- Validate shape before policy. A blocklist match on a malformed bundle string is useless. Paste production CTV requests into the bid request tester and gate
app.bundlepresence in CI per the OpenRTB validation guide. - Split reporting: app-level blocks versus impression IVT. If your dashboard merges them, a falling IVT rate can hide rising structural risk as fraud concentrates on unblocked apps.
The honest limit
A blocklist is a vendor-maintained opinion with thresholds (5 percent GIVT, 15 percent SIVT, three-year abandonment) you may disagree with. It does not replace schain authorization or your own MFA policy. It closes a specific hole: inventory that should not exist in the market anymore but still speaks OpenRTB fluently.
Sources
Field names are from OpenRTB as published by IAB Tech Lab. The analysis is our own. RTBlint is independent and not affiliated with IAB, IAB Tech Lab, or Pixalate.