Skip to content

SECTION 8 — ANALYTICS: VOD

44. POST /analytics/video/session/start

Called when a user starts playing VOD content.

Request

http
POST /analytics/video/session/start
Content-Type: application/json
Authorization: Bearer <token>

Request Body

json
{
  "session_id": "sess_vod_abc001",
  "user_id": "user_123",
  "device_id": "device_abc123",
  "platform": "web",
  "app_version": "2.4.1",
  "content": {
    "content_id": "ep_001",
    "content_type": "episode",
    "title": "E1: Pilot Episode",
    "creator_id": "creator_001",
    "creator_name": "Chris Spencer",
    "show_id": "show_001",
    "show_title": "Chris Spencer Presents",
    "season": 1,
    "episode_number": 1,
    "duration_seconds": 1472,
    "is_free": true,
    "is_premium": false,
    "is_ppv": false,
    "rating": "TV-14"
  },
  "playback": {
    "start_position_seconds": 0,
    "quality": "auto",
    "autoplay": false,
    "is_resume": false
  },
  "device": {
    "type": "web",
    "os": "macOS",
    "os_version": "14.0",
    "browser": "Chrome",
    "browser_version": "119.0",
    "screen_resolution": "1920x1080",
    "connection_type": "wifi",
    "isp": "Comcast"
  },
  "geo": { "country": "US", "state": "Georgia", "city": "Atlanta", "timezone": "America/New_York" },
  "referrer": { "source": "creator_zone", "page": "/creators/chris-spencer", "section": "free_episodes" },
  "timestamp": "2024-11-01T18:00:00Z"
}

Request Body Parameters (key fields)

FieldTypeRequiredDescription
session_idstringYesUnique view session ID
user_idstringNoUser ID (null for guests)
device_idstringYesUnique device fingerprint
platformstringYesweb, ios, android, roku, firetv, appletv
content.content_idstringYesContent being played
content.content_typestringYesepisode, premium, ppv
content.duration_secondsintYesTotal content duration
content.is_free / is_premium / is_ppvbooleanYesContent type flags
playback.start_position_secondsintYesPosition playback started
playback.qualitystringYesInitial quality
playback.is_resumebooleanYesWhether this is a resume
device.typestringYesDevice type
device.connection_typestringYeswifi, cellular, ethernet
geo.countrystringYesCountry code
timestampstringYesISO 8601 UTC

Response 200 OK

json
{
  "status": "success",
  "data": {
    "session_id": "sess_vod_abc001",
    "accepted": true,
    "heartbeat_interval_seconds": 30,
    "server_timestamp": "2024-11-01T18:00:00Z"
  }
}

45. POST /analytics/video/session/heartbeat

Called every 30 seconds during playback.

Request Body (key fields)

FieldTypeRequiredDescription
session_idstringYesActive session ID
content_idstringYesContent being watched
playback.position_secondsintYesCurrent position
playback.percent_watchedfloatYesPercentage watched
playback.is_playingbooleanYesIs video playing
playback.is_bufferingbooleanYesIs video buffering
playback.qualitystringYesCurrent quality
playback.playback_ratefloatYesSpeed e.g. 1.0, 1.5
performance.buffer_health_secondsfloatYesBuffer ahead
performance.rebuffer_countintYesRebuffer events
performance.dropped_framesintYesDropped frames
performance.bitrate_kbpsintYesCurrent bitrate
engagement.is_tab_activebooleanYesTab active state
timestampstringYesISO 8601 UTC

Response 200 OK

json
{
  "status": "success",
  "data": {
    "session_id": "sess_vod_abc001",
    "accepted": true,
    "next_heartbeat_seconds": 30,
    "server_timestamp": "2024-11-01T18:07:30Z"
  }
}

46. POST /analytics/video/session/end

Called when playback ends or user exits.

Request Body (key fields)

FieldTypeRequiredDescription
session_idstringYesSession ID
playback.end_position_secondsintYesFinal playback position
playback.total_watch_secondsintYesTotal active watch time
playback.percent_completedfloatYesPercentage completed
playback.completedbooleanYesWhether fully watched
playback.end_reasonstringYescompleted, user_exit, error, timeout, inactivity
performance.total_rebuffer_countintYesTotal rebuffer events
performance.quality_switchesintYesQuality changes count
engagement.total_pause_countintYesNumber of pauses
engagement.total_seek_countintYesNumber of seeks
timestampstringYesISO 8601 UTC

Response 200 OK

json
{
  "status": "success",
  "data": {
    "session_id": "sess_vod_abc001",
    "accepted": true,
    "watch_summary": {
      "total_watch_seconds": 1350,
      "percent_completed": 91,
      "completed": false,
      "end_reason": "user_exit"
    },
    "server_timestamp": "2024-11-01T18:22:30Z"
  }
}

47. POST /analytics/video/events

Post single or batch player interaction events.

Request Body

Send session_id, user_id, device_id, content_id, creator_id, and an events array. Each event has event_id, event_type, position_seconds, timestamp, and optional metadata.

Supported VOD Event Types

Event TypeDescription
playPlayback started or resumed
pausePlayback paused
seekUser seeked to position
seek_start / seek_endSeek began/ended
buffer_start / buffer_endBuffering started/ended
quality_changeStream quality changed
volume_changeVolume level changed
mute / unmuteAudio muted/unmuted
fullscreen_enter / fullscreen_exitFullscreen
playback_rate_changeSpeed changed
content_startFirst frame rendered
content_completeEnd of content reached
subtitle_on / subtitle_offSubtitles
pip_enter / pip_exitPicture-in-picture
shareUser shared content
clipUser created a clip
likeUser liked content
tipUser tipped creator

Response 200 OK

json
{
  "status": "success",
  "data": {
    "session_id": "sess_vod_abc001",
    "accepted_count": 7,
    "rejected_count": 0,
    "rejected_events": [],
    "server_timestamp": "2024-11-01T18:24:32Z"
  }
}

48. POST /analytics/video/quality

Report a stream quality change event.

Request Body (key fields)

FieldTypeRequiredDescription
quality_change.from_qualitystringYesPrevious quality
quality_change.to_qualitystringYesNew quality
quality_change.from_bitrate_kbpsintYesPrevious bitrate
quality_change.to_bitrate_kbpsintYesNew bitrate
quality_change.triggerstringYesuser, auto, network, error
quality_change.position_secondsintYesPosition at change

Response 200 OK

json
{
  "status": "success",
  "data": {
    "session_id": "sess_vod_abc001",
    "accepted": true,
    "server_timestamp": "2024-11-01T18:04:10Z"
  }
}

49. POST /analytics/video/error

Report a player or stream error.

Request Body (key fields)

FieldTypeRequiredDescription
error.error_codestringYesInternal error code
error.error_typestringYesnetwork, decode, drm, timeout, auth, cdn, player
error.error_messagestringYesHuman-readable message
error.error_severitystringYesinfo, warning, critical
error.is_fatalbooleanYesWhether playback terminated
error.recovery_attemptedbooleanYesWhether auto-recovery tried
error.recovery_successbooleanYesWhether recovery succeeded

Response 200 OK

json
{
  "status": "success",
  "data": {
    "session_id": "sess_vod_abc001",
    "accepted": true,
    "error_id": "err_log_xyz001",
    "server_timestamp": "2024-11-01T18:12:30Z"
  }
}

50. POST /analytics/video/ads

Report ad impression, view, skip, or click.

Request Body

Include session_id, user_id, device_id, content_id, creator_id, ad (ad_id, ad_type, ad_title, ad_duration_seconds, ad_position, etc.), event (event_type, position_seconds, watch_duration_seconds, was_skipped, was_clicked), and timestamp.

Supported Ad Event Types

Event TypeDescription
ad_impressionAd was shown
ad_startAd started playing
ad_quartile_25 / 50 / 7525%/50%/75% of ad watched
ad_completeAd fully watched
ad_skipAd was skipped
ad_clickAd was clicked
ad_errorAd failed to load

Response 200 OK

json
{
  "status": "success",
  "data": {
    "session_id": "sess_vod_abc001",
    "ad_id": "ad_xyz001",
    "accepted": true,
    "server_timestamp": "2024-11-01T18:00:15Z"
  }
}