SSAI Integration: Server-Side Ad Insertion

Stitch LtvAdx ads into your HLS or DASH stream, VOD or live: open a session, play the URL it returns.

What is stitched

HLS with MPEG-TS segments, or fMP4/CMAF segments — muxed, or with separate AAC audio and WebVTT subtitle renditions — VOD and live. DASH with CMAF segments addressed by SegmentTemplate, VOD and live. Streams the stitcher cannot cut play exactly as your origin serves them, without ads: encrypted or low-latency HLS, separate audio with TS video, IMSC (fMP4) subtitles; DASH with several Periods, DRM, or SegmentBase/SegmentList addressing.

1. Set up the channel

In the publisher portal, open Tools → SSAI Setup, pick the channel and turn SSAI on. List the hosts your stream is served from (cdn.example.com or *.example.com); a session for any other host is refused. The origin must be https on a public address and answer within 1.5 seconds. The channel must be approved, and only creatives uploaded to LtvAdx (status Ready) are stitched. The same page has a test player that plays your stream with LtvAdx's test ad in every break — nothing is recorded or billed.

2. Open a session when a viewer presses play

POST https://ssai.ltvadx.com/ssai/sessions
Content-Type: application/json

{
  "channelId":    "YOUR_CHANNEL_ID",
  "originUrl":    "https://cdn.example.com/show/master.m3u8",   // or …/manifest.mpd for DASH
  "householdId":  "DEVICE_OR_HOUSEHOLD_ID",
  "platform":     "ROKU",
  "reportingMode":"SERVER"                                       // optional: SERVER (default) | CLIENT
}

# 201
{
  "sessionId":   "…",
  "playbackUrl": "https://ssai.ltvadx.com/ssai/hls/{sessionId}/master.m3u8",   // DASH: /ssai/dash/{sessionId}/manifest.mpd
  "trackingUrl": "https://ssai.ltvadx.com/ssai/sessions/{sessionId}/tracking",
  "reportingMode": "SERVER",
  "expiresInSeconds": 14400
}

A server creating sessions for devices can pass deviceIp and deviceUserAgent; otherwise the caller's own are used (for targeting and invalid-traffic checks).

3. Play the playback URL

Give the player playbackUrl instead of your origin URL. Content segments still come from your CDN; ad segments come from cdn.ltvadx.com through a signed redirect on ssai.ltvadx.com. Breaks are placed from the cues in your stream (HLS #EXT-X-CUE-OUT/CUE-IN, #EXT-X-DATERANGE SCTE35, binary SCTE-35; DASH SCTE-35 EventStream), otherwise from the channel's break positions ("start,50%,end"), otherwise by content length. In live streams the break is replaced, ads first and slate after them, so the stream keeps your timeline; a viewer who joins in the middle of a break sees that break as your origin has it.

fMP4 / CMAF HLS

Every playlist of your stream — video variants, audio renditions, subtitles — gets the same breaks, so players keep the tracks in step. Each ad starts with its own #EXT-X-MAP and your content's MAP comes back after the break. Variants with their own audio get a muxed fMP4 ad; video-only variants the ad's video track and your audio rendition its AAC track; WebVTT subtitles get blank segments for the ad's length. In live streams, audio, subtitles and video must be numbered alike (CMAF packagers do).

House promo

In SSAI Setup you can upload a house promo (5–60 seconds). A live break that no campaign fills plays it, then slate, instead of your stream's own break content — and VOD breaks too if you tick that option. It is never billed and never counted as an ad.

Packager commands and player code that we have run end to end — ffmpeg, Shaka Packager, GPAC; hls.js, Shaka, dash.js, Video.js, Safari — are on SSAI Recipes, with an origin checklist.

4. Tracking

SERVER (default): LtvAdx fires impression and quartile beacons as the player requests each ad segment — nothing to build. CLIENT: your player reads trackingUrl (avails → ads → tracking events, with signed beacon URLs) and fires them as the ad plays. A tested snippet that does this for any web player is on SSAI Recipes. Either way each event counts once. Integration Health in the publisher portal shows whether players start your ads and whether their impressions and completes arrive — a CLIENT-mode player that never fires its beacons shows up there.

5. End the session

DELETE https://ssai.ltvadx.com/ssai/sessions/{sessionId}     # 204

Sessions also end after 4 hours without a request, and 24 hours after creation in any case.

Limits

  • 120 new sessions per minute from one IP address (429 above it).
  • 40 playlist requests per session per 10 seconds — poll live playlists once per target duration.
  • Your origin's playlists are cached by the ad server and shared by every session on the same URL (live about 2 s, VOD and master playlists 5 minutes), so viewers do not multiply origin load.

Test streams

https://cdn.ltvadx.com/demo/ssai-test-vod-v1/master.m3u8         # HLS VOD
https://cdn.ltvadx.com/demo/ssai-test-vod-dash-v1/manifest.mpd   # DASH VOD with a SCTE-35 cue at 30 s
https://cdn.ltvadx.com/demo/ssai-test-vod-cmaf-v1/master.m3u8    # CMAF HLS: video + AAC audio + WebVTT, cue at 30 s
https://cdn.ltvadx.com/demo/ssai-test-vod-fmp4-v1/master.m3u8    # muxed fMP4 HLS, cue at 30 s