Tech Stack · Standards & Specs

OpenRTB for CTV advertising: how the bid request works

OpenRTB (Open Real-Time Bidding) is the IAB Tech Lab protocol that governs how publishers send bid requests to DSPs and how DSPs respond with bids. Every programmatic CTV impression in India — whether through JioHotstar, SonyLIV, or Zee5 — is transacted over OpenRTB. Understanding its structure demystifies why some campaigns underdeliver, how deal IDs flow through the stack, and what signals a DSP actually has available when deciding whether and how much to bid.

What is OpenRTB?

OpenRTB is a JSON-based protocol specification published by the IAB Tech Lab. It defines the schema for a bid request (publisher → DSP) and bid response (DSP → publisher). The current major version is OpenRTB 2.6, which introduced several CTV-specific improvements over 2.5. OpenRTB 3.0 exists but has had slow adoption; most India SSPs (Magnite, PubMatic) and DSPs (DV360, TTD) operate on 2.5 or 2.6.

The full OpenRTB auction cycle for a single CTV slot:

  1. Viewer starts a piece of content; an ad break begins
  2. Publisher's ad server (GAM/SpringServe/PubMatic) determines a slot needs filling
  3. SSP constructs a bid request and fans it out to connected DSPs simultaneously (within ~20ms)
  4. Each DSP evaluates the bid request against active campaigns and responds with a bid price, creative ID, and VAST tag URL (or a no-bid)
  5. SSP runs the auction, selects the winner, returns a winning VAST tag to the ad server
  6. Ad server stitches the ad into the stream (SSAI) or passes the VAST tag to the player (client-side)

CTV bid request structure

A simplified OpenRTB 2.6 CTV bid request contains these top-level objects:

ObjectPurposeCTV-specific content
idUnique auction IDUUID per impression opportunity
imp[]Impression object(s)One entry per ad slot in the pod; contains video object and deal
appApp contextBundle ID (e.g., com.hotstar.android.tv), app name, store URL, categories
deviceDevice contextDevice type (3=CTV), UA string, IP, IFA (device ID), connection type
userUser contextHashed user ID, audience segments, buyeruid if available
siteNot used for CTVAbsent — CTV uses app object, not site
atAuction type1 = first-price (standard for India CTV); 2 = second-price (legacy)
tmaxTimeout (ms)Typically 150–300ms for CTV; longer than display

App object vs site object

This is the single most important structural difference between CTV and web OpenRTB. Web bid requests use a site object containing domain and page URL. CTV bid requests use an app object containing the app bundle ID and store URL. DSPs use the app bundle to apply brand safety targeting, frequency capping, and inventory allowlists.

India CTV app bundle IDs that DSPs and buyers should know:

  • JioHotstar (Android TV): com.hotstar.android.tv
  • SonyLIV (Android TV): com.sonyliv
  • Zee5 (Android TV): com.graymatrix.did
  • YouTube (Android TV): com.google.android.youtube.tv
  • Samsung TV Plus (Tizen): varies by region (3201504001965 for India)

When configuring app allowlists or blocklists in a DSP, use the bundle ID — not the app name, which is less reliable. App spoofing (a fraudulent app claiming to be JioHotstar's bundle ID) is a known IVT vector; third-party verification via IAS/DV cross-checks declared bundle against observed app behaviour.

Video object for CTV

The imp[].video object defines the ad slot's video requirements. For CTV:

  • mimes: ["video/mp4"] — CTV players accept MP4. No Flash, no VPAID.
  • minduration / maxduration: Defines acceptable creative lengths (e.g., 15–30 seconds). A DSP must match a creative within this range or it cannot bid.
  • protocols: VAST version support flags (3 = VAST 3.0, 7 = VAST 4.0, 8 = VAST 4.1). A DSP creative using unsupported VAST version will error.
  • startdelay: 0 = pre-roll; -1 = mid-roll (generic); -2 = mid-roll (last slot). Signals pod position.
  • placement: 1 = in-stream (standard for CTV). Not interstitial or banner.
  • linearity: 1 = linear (standard video). Not non-linear overlay.
  • skip: 0 = non-skippable (most India premium CTV); 1 = skippable.
  • w / h: 1920 × 1080 (or 1280 × 720 for older devices). Affects which transcoded file the player requests.

A common bid failure mode: a DSP has a 30-second creative but the publisher's video object specifies maxduration: 15. The DSP cannot match → no bid → unfilled slot. Buyers troubleshooting low win rates should check creative duration against the publisher's declared video object parameters.

Device object: CTV signals

The device object carries the signals a DSP uses for audience targeting and fraud detection:

  • devicetype: 3 = CTV (as defined in OpenRTB spec). This flag tells the DSP the impression is on a TV screen, triggering CTV-specific campaign logic.
  • ifa: Identifier For Advertisers — the device-level ID for frequency capping and audience matching. On Android TV this is the GAID; on Apple TV it is the IDFA; on Samsung Tizen it is the TIFA. Key for cross-publisher frequency management.
  • ifa_type: Distinguishes GAID, IDFA, TIFA, RIDA (Roku ID). DSPs need this to correctly map the IFA to their audience graph.
  • ip: Household IP address. Used for IP-based household matching (see pixel attribution article). Publishers in India sometimes pass a truncated IP (last octet masked) for privacy compliance.
  • ua: User agent string. Typically identifies the OS (Android TV 11, Tizen 6.5) and app version. Used by fraud detection systems to verify declared device type matches observed UA.
  • connectiontype: 2 = wired ethernet; 3 = WiFi; 5 = cellular (3G); 6 = LTE. India CTV buyers should note: a connectiontype: 5 or 6 on a CTV impression (not a mobile web impression) may indicate a smart TV on a mobile hotspot — lower-quality targeting signal.

Deal ID in OpenRTB

For PMP and PG deals, the bid request carries a pmp object inside the impression:

"pmp": {
  "private_auction": 1,
  "deals": [
    {
      "id": "DEAL-SONYLIV-PRABH-001",
      "bidfloor": 200.0,
      "bidfloorcur": "USD",
      "at": 1,
      "wseat": ["dv360-seat-id", "ttd-seat-id"]
    }
  ]
}

Key fields:

  • private_auction: 1 — Only buyers listed in deals[].wseat can win this impression. Open auction buyers are excluded.
  • deals[].id — The deal ID the publisher created and shared with the buyer. The DSP must be configured with this deal ID in the campaign targeting to respond.
  • deals[].bidfloor — The minimum acceptable bid for this deal. Note: this is typically in USD even for India publishers (OpenRTB convention). The publisher's ad server converts to INR internally.
  • deals[].wseat — Whitelist of buyer seat IDs allowed to bid. If a DSP's seat ID is not listed, it cannot win even if it sends a bid.

The most common PMP deal failure in India CTV: the buyer's DSP seat ID is not in the wseat list because the publisher's deal setup used the wrong seat ID. Always confirm the exact DSP seat ID with the SSP when setting up a new deal.

India publisher bid request notes

Currency: All three major India CTV publishers (JioHotstar/Google, SonyLIV/Magnite, Zee5/PubMatic) denominate bid requests and floors in USD. Buyers bidding in INR need to ensure the DSP's currency conversion is current — stale conversion rates cause under- or over-bidding.

User ID availability: JioHotstar passes a Google-encrypted user ID (via Google's PPID / Protected Audience framework). SonyLIV and Zee5 pass publisher-encrypted user IDs when available. Not all sessions have a user ID (unlogged-in users on free tiers). Sessions without a user ID rely on device IFA and IP for targeting — lower signal quality.

Content object: OpenRTB 2.6 includes a content object where publishers can declare content metadata (genre, language, content rating, episode). India publishers vary in how consistently they populate this. JioHotstar content metadata is relatively rich via Google's content API. Zee5 content object is less consistently populated on older library titles. Contextual targeting via content object is growing but not uniformly reliable across India CTV.