Server-Side Ad Insertion (SSAI)
Complete guide to integrating ApexMediation's SSAI system for seamless ad stitching across Live and VOD content.
HLS Protocol
RFC 8216 compliance, DATERANGE, CDN caching
DASH Protocol
MPD structure, EventStream, multi-period
Live Mode
Latency, resilience, operational controls
VOD Mode
Seeking, manifest stability, measurement
Containers
TS and CMAF/fMP4 segment formats
DRM Support
Widevine, FairPlay, PlayReady policies
Prerequisites
Origin, cue types, codec ladder requirements
Operations
Failure modes, fallback ladder, SLAs
CDN Guidance
Cache policies, headers, misconfigurations
Measurement
Tracking events, exactly-once, reconciliation
Playback Matrix
Certified player/platform compatibility
What is Server-Side Ad Insertion?
Server-Side Ad Insertion (SSAI), also known as Dynamic Ad Insertion (DAI), stitches advertisements directly into the video stream at the server level before delivery to the viewer. This approach eliminates ad blocker effectiveness, ensures seamless playback, and provides broadcast-quality ad experiences across all devices.
Key Benefits
- Ad blocker resistant: Ads are part of the content stream, indistinguishable from program content
- Seamless experience: No buffering or player reinitialization between content and ads
- Broad compatibility: Designed to work across modern HLS and DASH players. Exact compatibility depends on protocol, container, DRM policy, and player capabilities—see the Certified Playback Matrix and protocol pages.
- Accurate measurement: Server-side tracking with exactly-once delivery guarantees
Architecture Overview
┌─────────────────────────────────────────────────────────────────────┐
│ Video Player (SDK) │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ HLS.js │ │ Shaka │ │ ExoPlayer │ │
│ │ AVPlayer │ │ dash.js │ │ Native │ │
│ └─────┬───────┘ └──────┬──────┘ └──────┬──────┘ │
└────────┼─────────────────┼────────────────┼─────────────────────────┘
│ │ │
└─────────────────┼────────────────┘
│
┌──────▼──────┐
│ CDN Edge │ ← Segments cached at edge
└──────┬──────┘
│
┌────────────▼────────────┐
│ SSAI Manifest Service │
│ ┌───────────────────┐ │
│ │ Session Manager │ │
│ │ Pod Decisioning │ │
│ │ Manifest Stitcher │ │
│ │ Tracking Engine │ │
│ └───────────────────┘ │
└────────────┬────────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
┌─────▼─────┐ ┌──────▼──────┐ ┌──────▼──────┐
│ Origin │ │ Ad Server │ │ Demand │
│ (CMS) │ │ (VAST/VMAP)│ │ Partners │
└───────────┘ └─────────────┘ └─────────────┘Request Flow
- Session Init: Player SDK requests a session manifest URL, providing device capabilities, consent signals, and targeting context.
- Manifest Fetch: Player fetches the personalized HLS/DASH manifest from the SSAI service (CDN may cache segments but not the manifest).
- Ad Break Detection: SSAI service detects ad break opportunities from SCTE-35, EXT-X-DATERANGE, or DASH EventStream signals.
- Pod Decisioning: Real-time auction selects ads matching format requirements, competitive separation rules, and frequency caps.
- Manifest Stitching: Ad segments are stitched into the manifest with proper discontinuity markers and timing information.
- Segment Delivery: Player fetches stitched segments from CDN edge (content and ads appear as unified stream).
- Tracking: Impressions, quartiles, and completion events fire server-side with deduplication for exactly-once delivery.
Integration
Session Initialization
POST /v1/session/init{
"tenant_id": "your-tenant-id",
"asset": {
"id": "content-12345",
"type": "vod", // "live" | "vod"
"duration": 3600 // seconds (VOD only)
},
"device": {
"type": "ctv", // "web" | "mobile" | "ctv"
"os": "tvos",
"model": "Apple TV 4K",
"player": "avplayer"
},
"format": {
"protocol": "hls", // "hls" | "dash"
"container": "cmaf", // "ts" | "cmaf"
"drm": null // "widevine" | "fairplay" | null
},
"consent": {
"gdpr": true,
"ccpa": false,
"us_privacy": "1YNN"
}
}Response
{
"session_id": "sess_abc123xyz",
"manifest_url": "https://ssai.apexmediation.ee/v1/session/sess_abc123xyz/master.m3u8",
"expires_at": "2025-01-15T12:00:00Z",
"tracking_url": "https://track.apexmediation.ee/v1/session/sess_abc123xyz"
}Ad Decisioning & Timing
Pod Structure
Each ad break is organized as a "pod" containing one or more slots. The decisioning engine fills each slot based on format compatibility, competitive separation, and frequency caps.
Slot Types
Pre-roll
Before content playback begins
Mid-roll
During content at signaled break points
Post-roll
After content completion
SLA Guarantees
- Decision Deadline: Pod decisions complete before break start (p99 < 200ms)
- Fallback Behavior: If deadline approaches, slate (fallback content) is served rather than black screen
- Safe Mode: During incidents, system reduces fanout and enforces strict deadlines
Content Correctness
The SSAI system enforces strict content correctness rules to ensure seamless playback:
Format Compatibility
Ads must match content codec, resolution tier, and container format. HLS/TS content receives HLS/TS ads; DASH/CMAF content receives DASH/CMAF ads.
Audio Continuity
Audio layout (stereo/5.1/Atmos) and loudness (EBU R128/ATSC A/85) are validated and normalized to prevent jarring transitions.
Timing Alignment
Segment durations are aligned to GOP boundaries. Discontinuity sequences are maintained consistently across renditions.
Caption Handling
CEA-608/708 captions are preserved through ad breaks. WebVTT timing is adjusted to account for ad insertion.
Observability & Forensics
Every ad decision is fully explainable for debugging and support:
Explain API
GET /v1/session/{session_id}/pod/{pod_id}/explain{
"pod_id": "pod_123",
"break_type": "midroll",
"slots_requested": 3,
"slots_filled": 2,
"decision_trace": [
{"step": "partner_request", "partner": "partner_a", "duration_ms": 45},
{"step": "format_filter", "rejected": 2, "reason": "codec_mismatch"},
{"step": "competitive_separation", "rejected": 1, "reason": "same_category"},
{"step": "frequency_cap", "rejected": 0},
{"step": "final_selection", "selected": 2}
],
"unfilled_reason": "no_compatible_inventory"
}Metrics Exposed
- Session counts by tenant/channel
- Pod decision latency (p50/p95/p99)
- Fill rate by break type
- Format rejection reasons
- Partner response times
- Tracking event success rate
Security & Privacy
Signed Session Tokens
All session manifests are protected by cryptographically signed tokens with TTL expiration. Tokens are validated on every manifest request.
Anti-Tampering
Session parameters (targeting, consent) cannot be modified after session creation. Any tampering attempt results in session invalidation.
Rate Limiting
Per-tenant, per-session, and per-IP rate limits prevent abuse and protect against session storms during player retry loops.
Cache Isolation
Session manifests use private/no-store cache headers to prevent cross-user manifest poisoning at CDN edges.
Platform Coverage Matrix
| Platform | HLS/TS | HLS/CMAF | DASH/TS | DASH/CMAF | Live | VOD |
|---|---|---|---|---|---|---|
| Web (hls.js) | ✓ | ✓ | — | — | ✓ | ✓ |
| Web (Shaka) | ✓ | ✓ | △ | ✓ | ✓ | ✓ |
| tvOS (AVPlayer) | ✓ | ✓ | — | — | ✓ | ✓ |
| Android TV (ExoPlayer) | ✓ | ✓ | △ | ✓ | ✓ | ✓ |
| Roku | ✓ | ✓ | △ | ✓ | ✓ | ✓ |
| Fire TV | ✓ | ✓ | △ | ✓ | ✓ | ✓ |
DASH + TS containers: While technically supported by some players (Shaka, ExoPlayer), DASH with TS segments requires player-specific configuration and is not recommended for new deployments. Use DASH + CMAF for full compatibility. See Container Formats for details.