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

Server-Side Ad Insertion User Guide

Updated July 6, 2026

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 HLS.

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.

3.1 Prepare the Master Playlist URL

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

Understanding the Master Playlist

The 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 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 source URL {m} The Base64-encoded source URL for the HLS manifest. 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. Use this when no EXT-X-CUE-OUT markers exist. 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. 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. 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} Use only SCTE-35 cues from EXT-X-CUE-OUT markers. 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.

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 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.

  • 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.

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}

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.

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

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