Login
Welcome
Login

Implementation Guide (CSAI)

TABLE OF CONTENTS



1. Introduction

This document describes the Client-Side-Ad-Insertion (CSAI) integration of the SDK into the CTV Apps.
For the Server-Guided-Ad-Insertion (SGAI) integration please refer to these sections: Integration overview - SGAI and the Implementation Guide (SGAI).

The Teads CTV SDK is a TypeScript-based solution designed to enable seamless integration of VAST-compliant ad experiences into Connected TV (CTV) applications.
It provides a robust, event-driven API for fetching, managing, and displaying ads, with a focus on cross-platform compatibility (including older smart TV browsers), privacy compliance, and ease of integration. 

Key Features:

  • Simple integration via a loader script
  • Support for InPlay and InPause ad placements
  • Event-driven ad lifecycle management
  • GDPR and privacy compliance
  • Optimized for a wide range of CTV devices

Supported Platforms:

  • Chromium-based Smart TVs (including legacy versions)
  • Other modern smart TV browsers
  • JavaScript/TypeScript client applications

Requirements:

  • Internet access to load the SDK from the CDN
  • Ability to inject JavaScript into your CTV app
  • DOM access for ad rendering

2. Quick Start

2.1. Include the Loader Script

Add the following script tag to your application's HTML to load the SDK loader:

<script defer src="https://ctv.teads.tv/sdk/dist/loader.js"></script>

Note: The final loader URL may be updated. Please refer to the latest documentation or your Teads contact for the production URL.


2.2. Minimal Integration Example


Set up the window.teadsSdkReady callback to initialize the SDK once it is loaded:

<script>
window.teadsSdkReady = function() {
  // Define your application and placement contexts
  const appContext = {
    dom: {
      refElement: document.getElementById('ad-container'),
      videoElement: document.getElementById('main-video'), // optional
    },
    application: {
      appId: 'YOUR_APP_ID',
      appStoreUrl: 'YOUR_APP_STORE_URL',
    },
    contentMetaData: {
      genre: 'Documentary',
      language: 'en',
      livestream: false,
      network: 'NetworkName',
      channel: 'ChannelName',
    },
    // Optionally add device and user info for GDPR/compliance
  };
  const placementContext = {
    playerHeight: 1080,
    playerWidth: 1920,
    placementId: 241975, // Provided by Teads
    minDuration: 0,
    maxDuration: 60
  };
  // Create the SDK instance and initialize an InPlay placement
  const teadsSDK = window.teads.SDK.create(appContext);
  const inplayPlacement = teadsSDK.initInPlay(placementContext);
  // Listen for ad events
  inplayPlacement.addEventListener('adLoaded', function() {
    inplayPlacement.playAd();
  });
  // Load an ad
  inplayPlacement.loadAd();
};
</script>
<!-- Somewhere in your HTML -->
<div id="ad-container">
  <video id="main-video"></video>
</div>


This minimal example demonstrates how to load the SDK, set up the required contexts, initialize a placement, and load/play an ad.
For a more advanced integration, refer to the following sections.


3. SDK Initialization

3.1. Setting up window.teadsSdkReady

The SDK loader script will automatically call the global function window.teadsSdkReady once the SDK is fully loaded and available. You must define this function before the loader script is included or ensure it is defined before the SDK is ready. 

Example:

window.teadsSdkReady = function() {  // SDK is ready to use };


3.2. Creating the SDK Instance with AppContext

To create an SDK instance, call window.teads.SDK.create(appContext), where appContext is an object containing information about your application, device, user, and content.

AppContext fields:

  • dom.refElement (HTMLElement, required): The container element for ad rendering.
  • dom.videoElement (HTMLVideoElement, optional): The video element associated with the content.
  • application.appId (string, required): Your app's unique identifier.
  • application.appStoreUrl (string, required): The app's store URL.
  • contentMetaData (object, optional): Metadata about the content (genre, language, etc.).
  • device (object, optional): Device info (userAgent, deviceType, deviceId).
  • user (object, optional): User info (GDPR, consent, IP).

     

Example:

const teadsSDK = window.teads.SDK.create(appContext);


3.3. Initializing Placements (initInPlay, initInPause)

The SDK supports different ad placements. Use the SDK instance to initialize a placement by calling initInPlay(placementContext) or initInPause(placementContext). Each returns a placement object with the ad API. 

PlacementContext fields:

  • playerHeight (number, required): Height of the video player.
  • playerWidth (number, required): Width of the video player.
  • placementId (number, required): Unique identifier for the placement (provided by Teads).
  • minDuration (number, optional): Minimum ad duration.
  • maxDuration (number, optional): Maximum ad duration.

Example:

const inplayPlacement = teadsSDK.initInPlay(placementContext);
// or
const inpausePlacement = teadsSDK.initInPause(placementContext);


Note:

  • Only one instance per placement type (singleton) is supported per page/app.
  • You can add event listeners and control ads via the placement object.


4. Context & Placement Reference

4.1. AppContext

The AppContext type is required when creating the SDK instance. It is composed of several nested types:  

AppContext

FieldTypeRequiredDescription
domDomOptionsYesDOM elements for ad rendering (see DomOptions)
applicationApplicationInfoYesApplication details (see ApplicationInfo)
contentMetaDataContentMetaDataYesMetadata about the content (see ContentMetaData)
deviceDeviceInfoNoDevice information (see DeviceInfo)
userUserInfoNoUser information (see UserInfo)

DomOptions

FieldTypeRequiredDescription
refElementHTMLElementYesThe container element for ad rendering
videoElementHTMLVideoElementNoThe video element associated with your content (if applicable)

ApplicationInfo

FieldTypeRequiredDescription
appIdstringYesUnique identifier for your app (e.g., "G15147002586")
appStoreUrlstringYesURL to your app in the app store (e.g., "https://www.samsung.com/us/appstore/app/G15147002586")

ContentMetaData

FieldTypeRequiredDescription
genrestringNoGenre of the content (e.g., "Documentary")
languagestringNoLanguage code (ISO-639-1, e.g., "en")
livestreambooleanNoWhether the content is live (true or false)
networkstringNoNetwork name (e.g., "Discovery+", "HBO Max", "ESPN")
channelstringNoChannel name (e.g., "Discovery Channel", "HBO 1", "ESPN2")

DeviceInfo

FieldTypeRequiredDescription
userAgentstringNoUser agent string of the device
deviceTypenumberNoDevice type (3 = Connected TV, 7 = Set-Top-box)
deviceIdstringNoUnique device identifier (e.g., Google Ad ID, Apple IDFA)

UserInfo

FieldTypeRequiredDescription
gdprnumberNoWhether GDPR applies (0 = no, 1 = yes)
gdprConsentstringNoGDPR consent string (Base64-encoded)
ipAddressstringNoIP address of the user/device

Example:

const appContext = {
  dom: {
    refElement: document.getElementById('ad-container'),
    videoElement: document.getElementById('main-video'), // optional
  },
  application: {
    appId: 'G15147002586',
    appStoreUrl: 'https://www.samsung.com/us/appstore/app/G15147002586',
  },
  contentMetaData: {
    genre: 'Documentary',
    language: 'en',
    livestream: false,
    network: 'Discovery+',
    channel: 'Discovery Channel',
  },
  device: {
    userAgent: navigator.userAgent,
    deviceType: 3,
    deviceId: '236A005B-700F-4889-B9CE-999EAB2B605D',
  },
  user: {
    gdpr: 1,
    gdprConsent: 'CQL4_0AQL4_...',
    ipAddress: '181.174.87.53',
  }
};



4.2. PlacementContext

The PlacementContext type is required when initializing a placement.

FieldTypeRequiredDescription
playerHeightnumberYesHeight of the video player in pixels (e.g., 1080)
playerWidthnumberYesWidth of the video player in pixels (e.g., 1920)
placementIdnumberYesUnique identifier for the placement (provided by Teads, e.g., 241975)
minDurationnumberNoMinimum ad duration in seconds (e.g., 0)
maxDurationnumberNoMaximum ad duration in seconds (e.g., 60)

Example:

const placementContext = {
  playerHeight: 1080,
  playerWidth: 1920,
  placementId: 241975,
  minDuration: 0,
  maxDuration: 60
};


5. API Reference

5.1. Placement Methods & Properties

Each placement object (returned by initInPlay or initInPause) exposes the following methods and properties:

Property/MethodDescriptionReturns
loadAd()Fetches an ad for the placement. Emits adLoaded or adFailedToLoad events.void
playAd()Starts ad playback if an ad is ready. Emits adStarted or adFailedToStart events.void
stopAd()Stops the currently playing ad and cleans up resources.void
destroy()Cleans up the SDK objects and event listeners for this placement.void
isAdReadytrue if an ad is loaded and ready to play, otherwise false.boolean

Example:

inplayPlacement.loadAd();
if (inplayPlacement.isAdReady) {
  inplayPlacement.playAd();
}


Or, more typically, using events:

inplayPlacement.addEventListener('adLoaded', function() {
  inplayPlacement.playAd();
});
inplayPlacement.loadAd();



5.2. Event System

The SDK uses an event-driven architecture. You can listen for events on the placement object using addEventListener

Supported Events:


Event NameCallback ParametersDescription
adLoadednone or { assetsUrls }Emitted after a successful loadAd() call.
adFailedToLoad{ error } (string/object)Emitted if loadAd() fails (e.g., network issues (timeout, connectivity issues), no demand, invalid VAST response).
adStartednoneEmitted after a successful playAd() call.
adFailedToStart{ error } (string/object)Emitted if playAd() fails.
adCompletednoneEmitted when the ad finishes playing and is cleaned up.
requestPlayerResize{ contentResize }Emitted if the SDK requests a player resize (see Advanced Usage).
adError{ error } (string/object)Emitted for general errors.


Clarification:

For all error events, the callback parameter will be a string or an object containing a description of the error:
e.g.
{ error: "Network error: timeout" } 
or
{ error: { code: 1001, message: "No demand" } }). 



5.3. Usage Example

// Load and play an ad, handling events
inplayPlacement.addEventListener('adLoaded', function() {
  inplayPlacement.playAd();
});
inplayPlacement.addEventListener('adCompleted', function() {
  console.log('Ad playback completed');
});
inplayPlacement.addEventListener('adFailedToLoad', function(event) {
  console.error('Ad failed to load:', event.detail.error);
});
inplayPlacement.loadAd();


6. Error Handling & Compliance

6.1. Error Handling

The SDK uses an event-driven approach to surface errors. You can opt in to listen for error events on the placement object and handle them in your application if you wish to provide custom error handling or user feedback. The SDK also handles errors internally to ensure stability. 

Common Error Events:

  • adFailedToLoad: Emitted if an ad could not be loaded (e.g., network issues, no demand, invalid VAST).
  • adFailedToStart: Emitted if an ad could not be started (e.g., playback error).
  • adError: Emitted for general or unexpected errors.

    Error Event Payloads: 

  • The event's detail.error property will contain a string or an object describing the error.
  • Example:
    inplayPlacement.addEventListener('adFailedToLoad', function(event) {
      console.error('Ad failed to load:', event.detail.error);
      // Optionally show fallback UI, retry, etc.
    });



6.2. Compliance & Privacy

The SDK is designed to help you comply with privacy regulations such as GDPR. 

What you need to provide:

  • If your app is subject to GDPR, set the gdpr and gdprConsent fields in the user object of your AppContext.
    • gdpr: 1 if GDPR applies, 0 otherwise.
    • gdprConsent: The user's consent string (Base64-encoded).

    Example:

const appContext = {
  // ...
  user: {
    gdpr: 1,
    gdprConsent: 'CQL4_0AQL4_...',
    // ...
  }
};


Security:

  • The SDK communicates with the ad server over HTTPS.

7. Ad Fetching & VAST Parameters

  • How the SDK fetches ads:
    • the SDK builds a VAST tag URL from the objects passed at SDK initialization, it url-encodes all values
    • then it makes an HTTP GET call and expects to get a response with VAST XML markup
  • List of VAST parameters and their meaning: these are not in scope of this documentation but resemble the SDK objects.


8. Advanced Usage


8.1. Handling (content) Player Resize Requests (requestPlayerResize Event)


Some ad experiences require the video player to be resized and/or repositioned (for example, to display picture-in-picture or squeeze-back / L-shape ads). The SDK emits a requestPlayerResize event on the placement object when such a change is needed. 

Important:

  • If you do not provide the video player element (videoElement) in the AppContext, your application is expected to listen for the requestPlayerResize event and handle the resize operation. Else the video player resize is handled by the SDK. 

How to handle:

  • Listen for the requestPlayerResize event on your placement object.
  • The event's detail.contentResize property will contain the resize parameters (see table below).
  • The SDK expects the resize request to be handled immediately and according to the specified parameters. 
  • It is crucial that you call the provided onComplete callback after the resize operation is finished (or immediately if you do not animate). This ensures a smooth user experience and allows the ad to play properly. 

Resize Parameters:

FieldTypeDescription
durationnumberAnimation duration in milliseconds (e.g., 300)
scaleXnumberX-axis scaling factor (e.g., 1.0 for no scale)
scaleYnumberY-axis scaling factor (e.g., 1.0 for no scale)
xnumberX-axis target position in pixels
ynumberY-axis target position in pixels
onCompletefunctionCallback to invoke when the resize operation is complete

Example:

inplayPlacement.addEventListener('requestPlayerResize', function(event) {
  const resize = event.detail.contentResize;
  // Animate or immediately set your video player to the new size/position
  animatePlayer(resize.x, resize.y, resize.scaleX, resize.scaleY, resize.duration, function() {
    resize.onComplete();
  });
});


Summary:

  • If you do not provide a videoElement, you must handle requestPlayerResize.
  • Handle the resize as soon as the event is received, using the provided parameters.
  • Always call the onComplete callback to allow the SDK to continue.



8.2. Obtain the ad experience visual assets

The SDK exposes an object on the adLoaded  event with all the visual asset URLs of the ad experience. This can be used by the app for its own creative approval.

// the ad experience visual asset urls will be passed in adLoaded event:
inplayPlacement.addEventListener('adLoaded', (e) => { console.log(e.details.assets) })





9. Workflow diagram

A visual representation of the SDK API calls and events flow:





10. Test placement ids & Demo page


Test placementId for InPlay

  • Overlay
    • placementId = 241974
  • Squeeze-back
    • placementId = 241975
    • placementId = 241973
  • Picture-in-picture
    • placementId = 241972

Test placementId for InPause

  • Fullscreen in-loop
    • placementId = [to-be-provided on request]


Demo page for InPlay

The code samples from this page are implemented in this demo page:

Demo 1 - Lavazza coffee

See the section with more ad experiences - here



11. FAQ & Troubleshooting


Q: What happens if I don't provide a videoElement in the AppContext?

A: If you do not provide a videoElement, your application is responsible for handling the requestPlayerResize event. This is required for certain ad experiences (such as squeeze-back and picture-in-picture) to function correctly. See Advanced Usage for details.


Q: How do I know when an ad is ready to play?

A: Listen for the adLoaded event on your placement object. When this event is emitted, you can safely call playAd().


Q: What should I do if an ad fails to load or play?

A: You can listen for the adFailedToLoad and adFailedToStart events. The event's detail.error property will provide information about the failure. You may choose to display fallback content, retry, or simply log the error.


Q: Is GDPR/consent required for all integrations?

A: If your app is distributed in regions where GDPR applies, you must provide the gdpr and gdprConsent fields in the user object of your AppContext. If not, you may omit these fields.


Q: Who do I contact for support or to obtain placement IDs?

A: Please contact your Teads account manager or support representative for integration support, placement IDs, or additional documentation.

12. Appendix

Glossary

TermDefinition
SDKSoftware Development Kit; a set of tools and APIs for integrating Teads ad experiences.
PlacementA logical location in your app where an ad can be shown (e.g., InPlay, InPause).
AppContextAn object containing information about your app, device, user, and content.
PlacementContextAn object containing information specific to an ad placement (e.g., player size, ID).
VASTVideo Ad Serving Template; an industry-standard XML format for video ad responses.
GDPRGeneral Data Protection Regulation; EU privacy law requiring user consent for data use.
Consent StringA Base64-encoded string representing the user's privacy consent choices.
EventA notification emitted by the SDK to signal ad lifecycle changes or errors.

References


Did you find it helpful? Yes No

Send feedback
Sorry we couldn't be helpful. Help us improve this article with your feedback.