Blog · CTV

CTV pre-bid show targeting can splice a Content object from app.bundle alone while the exchange still forwards an empty content block.

On September 21, a verification vendor published OpenEPG DB 1.0 with a pre-bid API for open programmatic CTV. The catalog maps 375,000+ raw bundle ID variations to 580,000+ TV shows across 13,900+ FAST and linear channels, covering 6,192 U.S. streaming apps on nine OS platforms. The API requires zero publisher opt-in. It parses OpenRTB 2.6 bid requests using two required inputs, app.bundle and device.ua, and returns the same request with program metadata spliced into app.content. That is a bidstream event, not a creative delivery event, and it changes what "missing content.title" means in production.

Two copies of the same impression

A FAST aggregator can send a structurally valid CTV request where app.content is empty or thin. The seller is not lying about the app. The publisher simply does not pass show names in open exchange traffic, and the gap is widest on multi-channel FAST inventory where one bundle carries hundreds of channels. Buyers who hard-require content.title filter that traffic. Buyers who attach a pre-bid enrichment hop may receive a different JSON for the same impression milliseconds later.

The vendor describes the output as a native OpenRTB 2.6 Content object that can include content.title, content.series, content.genre, content.contentrating, and content.channel.id plus content.channel.name, with a statistical confidence score from 0.00 to 1.00 on each resolved response. Channel identifiers or channel names already on the request feed match confidence. None of that requires a publisher SDK.

RTBlint is independent and not affiliated with Pixalate or any exchange. The point is not which vendor ships the hop. The point is that show-level targeting on CTV can move entirely off the seller payload and onto inference from bundle, user agent, and optional channel signals. Your QA sample depends on which hop you capture.

What the metric actually measures

Post-bid rankings and monthly indices measure spend and reach at show level after the fact. We already wrote about that population when the July OpenEPG Index mapped 532,000+ U.S. streaming shows from bundle IDs without publisher opt-in. This release is the pre-bid mirror: the same class of resolution, invoked before the bidder prices the impression, with explicit OpenRTB field output rather than a dashboard export.

The September 21 announcement states that show-level data for streaming TV usually comes from program schedules content owners submit to metadata providers, or from automatic content recognition. Neither appears in most open programmatic bid requests. Pre-bid enrichment is a third source: public EPG plus open-exchange signals, returned as spec fields the buyer already targets against.

Confidence scores matter for buyers. A genre filter applied at 0.95 confidence is not the same policy as one applied at 0.60. If your DSP stores only the enriched payload and drops the score, you cannot reconcile why two impressions with the same title string cleared different brand-safety rules. Split reporting: raw seller JSON, enriched JSON, and the score if the API exposes it.

Mechanism on the wire

The vendor documents a three-step flow. Input is a standard OpenRTB 2.6 bid request with app.bundle and device.ua. Resolution matches those fields, plus any channel identifier or channel name on the request, against the EPG catalog in real time. Output is the same bid request with resolved program metadata in app.content. Integration overhead is listed as zero SDKs and zero lines of publisher code.

// Seller-origin request (common on FAST aggregators)
"app": {
  "bundle": "com.example.fast",
  "content": {}
},
"device": { "ua": "..." }

// After pre-bid enrichment hop (same auction, different JSON)
"app": {
  "bundle": "com.example.fast",
  "content": {
    "title": "...",
    "series": "...",
    "genre": "...",
    "contentrating": "...",
    "channel": { "id": "...", "name": "..." }
  }
}

A bidder that logs requests at ingress sees the empty block. A bidder that logs after enrichment sees titles. Both logs are true. Neither alone describes the supply path. If your blocklist keys on content.genre without checking whether enrichment ran, you can block inventory that would have been eligible post-hop, or buy inventory whose title was inferred rather than declared by the seller.

Bundle normalization is part of the story. The catalog maps 375,000+ raw bundle variations to parent apps. The same CTV app reaching you under three bundle strings through three paths is still three allowlist entries unless you normalize. Pre-bid EPG adds another normalization layer on top of bundle fraud mechanics reports already document for platform mimicry. Our bundle mimicry post and the live show-level spend post cover adjacent failure modes; this post is the pre-bid splice.

Why FAST aggregators break content QA

Tubi, Samsung TV Plus, and The Roku Channel appear explicitly in the release as FAST channels the DB covers. One app bundle can represent hundreds of linear-style channels inside a single wrapper app. Sellers often send stable app.bundle with no per-channel content object because the ad server does not know which show is playing at bid time, or because metadata contracts never required open-exchange disclosure.

Pre-bid resolution is how buyers get genre and title without a publisher metadata deal. It is also how two buyers on the same exchange see different content quality on the same underlying supply: one integrated the API in private beta, one still reads raw logs. Private beta availability for DSPs, SSPs, and exchanges means the split is live in market structure even before it is visible in your spreadsheet of seller fill rates.

OpenRTB never marks whether content.title was publisher-declared or vendor-inferred. There is no content.provenance flag in 2.6. Governance teams that treat enriched titles as contractual representations from the seller are misreading the chain. Legal and ops need a label in the buyer stack, not in the spec.

What to do

  • Log raw and enriched JSON separately. Store capture point (SSP edge, exchange, DSP pre-filter) on every sample. Comparing fill without that dimension confuses seller omission with buyer filter.
  • Keep confidence with the enriched fields. If you filter on inferred genre, persist the score that justified the match.
  • Do not treat post-bid indices as pre-bid coverage. Monthly show rankings describe measured spend populations. They do not prove your bidder received enriched content on every eligible request.
  • Normalize bundle IDs before EPG match. 375,000+ variation mappings exist because sellers send messy bundles. Your allowlist should not fight the same normalization the API applies.
  • Validate structural content anyway. Enrichment can populate content.genre while cattax is still wrong for content.cat. Inference does not fix enum drift on other fields.

RTBlint checks OpenRTB JSON for structural and consistency rules. It does not resolve EPG or infer shows. It will flag empty content on a CTV request, type mismatches on genre lists, and implausible device and app pairings. Paste the payload your bidder actually prices, not only the seller-origin copy.

Validate a bid request · CTV bid request reference

Sources