Overview
Consistent video event tracking across CTV platforms enables unified audience analytics and cross-platform cohort building. This guide covers the standard video event schema and implementation patterns for all supported platforms.Video Event Schema
Permutive uses a consistent video event schema across all CTV platforms:Core Events
| Event | Description | Trigger |
|---|---|---|
| Videoview | User initiated video playback | When video starts or user selects content |
| VideoCompletion | User finished watching | When video ends or user exits |
| VideoAdView | Video ad started playing | When ad playback begins |
| VideoAdCompletion | Video ad finished | When ad playback ends |
| VideoAdClicked | User clicked video ad | When user interacts with ad |
Standard Video Properties
Use these properties consistently across events for unified analytics:Property Naming: The schema uses
snake_case property names. Native SDKs (tvOS, Android TV) use camelCase in their APIs (e.g., seasonNumber), which is automatically mapped to the snake_case schema.| Property | Type | Description |
|---|---|---|
title | string | Video title |
genre | string[] | List of genres (e.g., [“Drama”, “Thriller”]) |
content_type | string[] | Content types (e.g., [“Series”, “Episode”]) |
age_rating | string | Age rating (e.g., “PG-13”, “TV-MA”) |
runtime | number | Runtime in seconds |
country | string | Origin country |
original_language | string | Original language code |
audio_language | string | Audio language being watched |
subtitles.enabled | boolean | Whether subtitles are enabled |
subtitles.language | string | Subtitle language |
season_number | number | Season number (for series) |
episode_number | number | Episode number (for series) |
consecutive_episodes | number | Consecutive episodes watched |
iab_categories | string[] | IAB content taxonomy categories |
Completion Event Properties
Additional properties forVideoCompletion:
| Property | Type | Description |
|---|---|---|
completion | number | Percentage watched (0.0 - 1.0) |
engaged_time | number | Time spent watching in seconds |
Ad Event Properties
Properties for video ad events:| Property | Type | Description |
|---|---|---|
ad_id | string | Advertisement identifier |
ad_position | string | Position: “preroll”, “midroll”, “postroll” |
ad_duration | number | Ad duration in seconds |
campaign_id | string | Campaign identifier |
creative_id | string | Creative identifier |
Platform Implementation
- Web CTV
- tvOS
- Android TV
- Roku
Platforms: Samsung Tizen, LG WebOS, HbbTVUse the CTV addon for automatic event tracking:Automatic Events:
Videoview- tracked when addon is initializedVideoCompletion- tracked when.stop()is called
Engagement Tracking
How Engagement Works
Engagement time measures how long a user actively watches content:- Start - When
play()is called, engagement timer starts - Pause - When
pause()is called, timer pauses - Resume - When
play()is called again, timer resumes - Complete - When
stop()is called, total engagement is recorded
Buffering Considerations
Buffering should pause engagement tracking:- Web CTV
- Native (iOS/Android)
Seeking/Scrubbing
When users seek to a new position:Ad Break Handling
Pre-roll Ads
Track ads before main content:Mid-roll Ads
Pause main content tracking during ads:Post-roll Ads
Track ads after main content completes:Best Practices
- Do
- Don't
- Set duration accurately - Provide video duration in milliseconds when initializing
- Sync with player state - Call
play()/pause()when the player state changes - Always call stop() - Ensure
stop()is called when video ends or user exits - Handle buffering - Pause tracking during buffering states
- Track all ad events - Capture ad views and completions for ad analytics
- Use consistent properties - Follow the standard schema across all platforms
- Include video metadata - Richer metadata enables more precise cohort building
- Generate unique view IDs - Create new view IDs per content session (Roku)
Cross-Platform Consistency
For unified analytics across platforms, ensure:Event Name Consistency
| Platform | Videoview Event | Completion Event | Ad View Event |
|---|---|---|---|
| Web CTV | Videoview | VideoCompletion | VideoAdView |
| tvOS | VideoPlay | VideoComplete | Manual |
| Android TV | Videoview | VideoComplete | Manual |
| Roku | Videoview (manual) | VideoCompletion (manual) | VideoAdView (manual) |
Property Mapping
Ensure property names are consistent:| Web CTV | iOS SDK | Android SDK | Roku |
|---|---|---|---|
title | title | title | title |
genre | genre | genre | genre |
season_number | seasonNumber | seasonNumber | season_number |
episode_number | episodeNumber | episodeNumber | episode_number |
Work with Technical Services to configure a unified event schema across all platforms.
Troubleshooting
Engagement time is incorrect
Engagement time is incorrect
Problem: Engaged time doesn’t match expected values.Solutions:
- Ensure
play()is called only when video is actually playing - Call
pause()during buffering and paused states - Verify
stop()is called when video ends - Check that ad breaks pause the main content tracker
Completion percentage is 0 or missing
Completion percentage is 0 or missing
Problem: VideoCompletion event shows 0% or null completion.Solutions:
- Provide duration when creating the tracker/addon
- Ensure duration is in the correct unit (milliseconds for most SDKs)
- Wait for video metadata to load before creating tracker
Video events not appearing in dashboard
Video events not appearing in dashboard
Problem: Events don’t show in Permutive analytics.Solutions:
- Verify SDK is initialized with correct credentials
- Check browser/device console for errors
- Ensure events match your workspace schema
- Wait 5-10 minutes for events to process
Ad events not linked to video sessions
Ad events not linked to video sessions
Problem: Ad events aren’t associated with video content.Solutions:
- Track ads using the same addon/tracker instance
- On Roku, use the same
view_idfor content and ads - Ensure ad events fire during the video session