IndiCue Ad Insertion – User Guide (v1.3.0)
v1.3.0

Server-Side Ad Insertion User Guide

Updated April 13, 2026  ·  IndiCue SSAI Platform

What's new in v1.3.0

This revision adds MPEG-DASH support alongside existing HLS. Section 3.2 is new. Section 3.1 has been lightly updated to clarify HLS-specific context. The macro table, implementation steps, and example URLs in Sections 3.3 and 4.5 have been updated to reflect both protocols.

1. Introduction

This guide explains how to implement Smart Ad Stitching technology using the provided URL structure and macros. Its goal is to help content owners, broadcasters, and publishers seamlessly integrate Server-Side Ad Insertion (SSAI) into their CTV (Connected TV) environments.

By following the steps and examples in this document, you'll learn how to configure SSAI parameters, understand how each macro works, and deliver a smooth, ad-supported streaming experience over both HLS and MPEG-DASH.

2. Overview

Server-Side Ad Insertion (SSAI) is a technique that inserts ads directly into your video stream from the server, rather than the app or player. This approach has several key benefits:

  • Better user experience: Ads become part of the content stream, so viewers enjoy smooth transitions without buffering or app-side interruptions.
  • Ad Blocker Resistance: Because ads are served inside the main stream, they're less likely to be blocked by device ad-blockers.
  • Personalized Ads: SSAI supports dynamic targeting, allowing you to serve ads tailored to user data or viewing context.
  • Seamless Content Integration: The isNoSlate option lets you weave ads alongside content without pausing playback.
  • Protocol Flexibility: The ad stitcher supports both HLS (.m3u8) and MPEG-DASH (.mpd) source manifests, letting you serve the format best suited to your device ecosystem.

3.1 Prepare the Master Playlist URL (HLS)

Your master playlist URL is the foundation of the streaming and ad insertion process for HLS streams. It tells the SSAI system where to find your video content and where to insert ads.

Understanding the HLS Master Playlist

The HLS (HTTP Live Streaming) master playlist (.m3u8) is a crucial element in streaming. It references multiple variant playlists, each representing the same content encoded at different bitrates or resolutions. This setup allows the player to automatically choose the best quality based on the viewer's device and network connection.

Encoding the URL

To send the master playlist URL as a parameter, it must first be Base64 encoded.

  • Why Base64? Encoding ensures your URL can safely be passed as a query parameter by converting special characters into standardized ASCII format.
  • How to Encode: Use a Base64 encoding tool such as Base64 Guru, or a Base64 function in your own application.
    Example: https://example.com/stream.m3u8aHR0cDovL2V4YW1wbGUuY29tL3N0cmVhbS5tM3U4
  • Once the URL is encoded, replace the {m} macro in your provided ad insertion template with the encoded Base64 string.

3.2 DASH Support NEW

MPEG-DASH Overview

MPEG-DASH (Dynamic Adaptive Streaming over HTTP) is an ISO-standard adaptive bitrate protocol widely supported across Android TV, Fire TV, Samsung Tizen, and LG webOS. For devices that do not support HLS natively — or deployments where DASH is preferred — the Ad Insertion can accept a DASH manifest (.mpd) as the source, stitch ads at SCTE-35/SCTE-214 event boundaries, and return a stitched DASH manifest to the player.

How DASH Stitching Works

The overall flow mirrors HLS stitching: the DASH manifest URL is Base64 encoded and passed in the {m} macro, just like an HLS source. The stitcher detects the manifest type automatically based on the .mpd extension or the Content-Type: application/dash+xml response header.

  1. Pass a .mpd manifest URL in the {m} macro (Base64 encoded), exactly as you would for HLS.
  2. Ad breaks are signaled via EventStream elements in the MPD, using schemeIdUri="urn:scte:scte35:2014:xml+bin" — the standard SCTE-35 in-band signaling method for DASH.
  3. No-slate mode (isNoSlate=true) and adInterval work identically to HLS. Use them for DASH streams that do not contain SCTE-214 event signaling.
  4. The stitched output is a DASH MPD with ad periods inserted. The player must be a DASH-capable player (e.g., ExoPlayer, Shaka Player, dash.js).

DASH vs. HLS — Key Differences for SSAI

FeatureHLS (.m3u8)DASH (.mpd)
Source macro ({m})
Ad break signalingSCTE-35 in #EXT-X-CUE-OUTSCTE-35/214 in EventStream
No-slate mode (isNoSlate)
Pre-roll (preroll)
cuePoint macro
Low-latency (LL) modeLL-HLSLL-DASH (contact support)
Player requirementHLS-capable (AVPlayer, ExoPlayer, etc.)DASH-capable (ExoPlayer, Shaka, dash.js)
Stitched manifest output.m3u8 with ad segments.mpd with ad Period elements

Example: DASH Source URL

Base64-encode your MPD URL:

https://example.com/live/manifest.mpd?m=aHR0cHM6Ly9leGFtcGxlLmNvbS9saXZlL21hbmlmZXN0Lm1wZA==

Then construct your stitcher URL exactly as you would for HLS, using the encoded MPD URL as the m value:

https://demo-telos.live.indicue.com/stream.m3u8?m=aHR0cHM6Ly9leGFtcGxlLmNvbS9saXZlL21hbmlmZXN0Lm1wZA==&u={u}&adDuration={adDuration}&aid={aid}

3.3 Ad Insertion Macros

Ad Insertion macros control how ads are requested and inserted during playback. These macros also pass additional parameters needed for ad calls.

Keep in mind:

  • You must include all required parameters for your ad request along with these macros.
  • For examples and detailed guidance, refer to the SSP Macros Documentation.
  • The Ad Insertion service acts as a proxy: it passes through all non-stitcher parameters but doesn't generate them directly from the SSP.

Stitcher Control Parameters

NameMacroDescriptionExampleAllowed ValuesConstraints
Master playlist / manifest source URL {m} The Base64-encoded source URL. Accepts both HLS (.m3u8) and MPEG-DASH (.mpd) manifests. The stitcher detects the protocol automatically. m=aHR0cDovL... Base64 encoded URL string Required Must be a valid Base64-encoded URL.
User ID{u} A unique identifier for the user accessing the stream. u=testuserString Required
Ad triggers included in playlist source?{isNoSlate} Controls whether ads are inserted as additional content without replacing the main content. For HLS use this when no EXT-X-CUE-OUT markers exist. For DASH, use when no EventStream cue points are present. isNoSlate=trueBoolean (true, false, 1, 0) Optional Default: false.
Ad insertion interval{adInterval} Time interval in seconds between consecutive ad insertions. Only works when no-slate mode is enabled (HLS and DASH). adInterval=600Integer (seconds) Optional Required if isNoSlate=1.
Ad pod duration{adDuration} Maximum duration of each ad break in seconds. adDuration=60Integer (seconds) Required if ads are being inserted.
Pre-roll ad block{preroll} Enables pre-roll ads before main content. Supported for both HLS and DASH. preroll=1Boolean Optional Default: false.
Pre-roll offset{prerollOffset} Duration in seconds before preroll ads play. Result depends on segment duration. prerollOffset=5Integer (seconds) Optional Default: 8 seconds.
Cue Point{cuePoint} For HLS: use only SCTE-35 cues from EXT-X-CUE-OUT markers. For DASH: use only EventStream SCTE-35/214 cues. cuePoint=1Boolean (true, 1, TRUE) Optional Default: false.
Format override{format} Override default encoding ladder for a specific OTT partner (bitrate, codecs, etc.). format=ott-studio-p31String Optional

CTV Ad Request Parameters

NameMacroDescriptionExampleConstraints
Source ID{aid}Identifies the Source ID within the stitching system. Used for reporting and analytics.aid=478241Required
Traffic Router{troute}Identifies the Traffic Router ID. Required when linking to a Traffic Router.troute=83Required if using Traffic Router
Site full URL{site_full_url}Full URL of the site where video content is being streamed.site_full_url=test.comOptional
Device User Agent{ua}User-Agent string from the device. Used for analytics and content adaptation.ua=Mozilla/5.0...Optional
IP Address{uip}IP address of the device. Used for geolocation and personalization. Handle with care.uip=192.168.1.1Optional
App Name{app_name}Name of the application making the request.app_name=ExampleAppOptional
App Bundle{app_bundle}Unique bundle identifier for the application (reverse DNS format).app_bundle=com.example.appOptional
Device Model{device_model}Model of the device accessing the stream.device_model=iPhone10,6Optional
Device Manufacturer{device_make}Manufacturer of the device (e.g., Apple, Samsung).device_make=AppleOptional
Device Type{device_type}Type of device: 1=PC, 2=Smartphone, 3=Tablet, 4=Smart TV, 5=Set-Top Box.device_type=4Optional
App Store URL{app_store_url}URL of the application in the app store.app_store_url=https://itunes.apple.com/...Optional
Device ID{device_id}Unique identifier for the device. Important for session tracking.device_id=abcd1234Optional
GDPR{gdpr}Signals whether data processing is subject to GDPR.gdpr=1Optional
TCF String{gdpr_consent}IAB TCF consent string under GDPR.gdpr_consent=COtybn4...Required if gdpr=1
US Privacy{us_privacy}U.S. state privacy string (CCPA). Fixed 4-character format (e.g., 1YNN).us_privacy=1YNNOptional
Limit Ad Tracking{lmt}0 = tracking unrestricted; 1 = tracking must be limited.lmt=0Optional
COPPA{coppa}1 = user is under 13 (COPPA applies); 0 = COPPA does not apply.coppa=1Optional

4. Ad Insertion Implementation

This section provides a step-by-step guide to implementing "Telos" ad insertion. The steps below apply to both HLS and DASH unless noted.

4.1 Set Up User Identification

The User ID ({u}) is a unique identifier assigned to each viewer or session. Replace the {u} macro with the actual user ID — this can be a string (e.g., a username) or a numeric identifier assigned by your system.

4.2 Configure Ad Insertion Parameters

  1. Set "No Slate" Mode (Optional):
    The {isNoSlate} flag controls whether ads are inserted as additional content. Default is false. Set to true if your stream (HLS or DASH) does not include cue points. When true, the maximum ad block length is set by {adDuration}, but the actual length depends on available fill.
  2. Specify Ad Insertion Interval (Optional):
    The {adInterval} determines how frequently ads are inserted (in seconds). Required when isNoSlate=true.
  3. Define Ad Duration:
    The {adDuration} specifies the maximum duration of each ad block in seconds (e.g., adDuration=30). Required if ads are being inserted.

4.3 Enable Pre-Roll Ads (Optional)

Pre-roll ads play before the main content begins and are supported for both HLS and DASH.

  • Activate Pre-Roll: Set {preroll} to true or 1.
  • Define Pre-Roll Offset: Use {prerollOffset} to specify a delay in seconds before pre-roll ads play. Default is 8 seconds.

4.4 Provide Device, App, and Content Information

Providing detailed device, app, and content information helps optimize ad delivery across platforms.

  • Device Information: {ua} (User-Agent), {uip} (IP Address), {device_model}
  • App Information: {app_name}, {app_bundle}, {app_store_url}
  • Additional Device Details: {device_make}, {device_type}, {device_id}
  • Content Data: Content ID, Content URL, Content Series, Language, Genre, Categories. See indicue.com/macros for the full list.

4.5 Test the URL

Before deploying to production, test the URL in a controlled environment to confirm that ads are inserted as expected and the stream plays correctly. Use stream analyzers or your ad insertion platform's testing features.

HLS Example Template

https://demo-telos.live.indicue.com/stream.m3u8?m={m}&u={u}&isNoSlate={isNoSlate}&adInterval={adInterval}&adDuration={adDuration}&preroll={preroll}&site_full_url={site_full_url}&ua={ua}&uip={uip}&app_name={app_name}&app_bundle={app_bundle}&device_model={device_model}&device_make={device_make}&device_type={device_type}&app_store_url={app_store_url}&device_id={device_id}&aid={aid}

DASH Example Template NEW

https://demo-telos.live.indicue.com/stream.mpd?m={m_dash_base64}&u={u}&isNoSlate={isNoSlate}&adInterval={adInterval}&adDuration={adDuration}&preroll={preroll}&site_full_url={site_full_url}&ua={ua}&uip={uip}&app_name={app_name}&app_bundle={app_bundle}&device_model={device_model}&device_make={device_make}&device_type={device_type}&device_id={device_id}&aid={aid}
Note

The endpoint path is the same for both HLS and DASH. The stitcher automatically detects the source manifest type from the Base64-decoded {m} value. Ensure your player is configured for the appropriate playback protocol (HLS-capable or DASH-capable) before testing.

4.6 Finalize the Production URL

Double-check that all relevant macros have been replaced with the correct values. Missing or incorrect values can lead to errors or failed ad insertions.

HLS Production URL Example

https://ott-studio.telos.indicue.com/stream.m3u8?m=aHR0cDovL2hscy10cmFuc2NvZGVyLnR2c3RpdGNoLmNvbS9uby1zbGF0ZS9tYXN0ZXIubTN1OA==&u=testuser&isNoSlate=true&adInterval=60&adDuration=60&preroll=1&site_full_url=test.com&ua=Mozilla/5.0%20(Linux;%20U;%20Android%202.2)%20AppleWebKit/533.1%20(KHTML,%20like%20Gecko)%20Version/4.0%20Mobile%20Safari/533.1&uip=167.235.198.190&app_name=test_app_name&app_bundle=test_app_bundle&device_model=Android%202.2&device_make=Android&device_type=2&app_store_url=test_app_store_url.com&device_id=1&aid=1401

DASH Production URL Example NEW

https://ott-studio.telos.indicue.com/stream.mpd?m=aHR0cHM6Ly9leGFtcGxlLmNvbS9saXZlL21hbmlmZXN0Lm1wZA==&u=testuser&isNoSlate=true&adInterval=60&adDuration=60&preroll=1&site_full_url=test.com&ua=Mozilla/5.0%20(Linux;%20Android%2012;%20SHIELD%20Android%20TV)%20AppleWebKit/537.36&uip=167.235.198.190&app_name=test_app_name&app_bundle=com.example.tvapp&device_model=SHIELD%20Android%20TV&device_make=NVIDIA&device_type=4&device_id=abcd5678&aid=1401

Replace ott-studio with your subdomain. Contact your Indicue sales representative if you haven't yet been issued your subdomain.