Skip to main content
View as Markdown

Cue Points & Interactive Videos - Kaltura Player

Kaltura Cue Points & Interactive Video API​

Cue points are temporal metadata markers on video entries — chapters, slides, ads,
annotations, quizzes, broadcast events, session boundaries, and custom code triggers.
They drive player experiences (chapter navigation, slide sync, in-video quizzes,
ad insertion) and are searchable via eSearch.

This hub guide covers the shared cue point architecture, base service, protocols,
and cross-type features. Each cue point type has a dedicated guide with
implementation details — see section 5 for links.

Base URL: $KALTURA_SERVICE_URL (e.g., https://www.kaltura.com/api_v3)
Auth: KS via ks parameter (admin KS with disableentitlement for full access)
Format: format=1 for JSON responses
Times: All startTime and endTime values are in milliseconds

1. When to Use​

  • Temporal metadata foundation — Add structured, time-based markers to any video entry, enabling chapters, slides, annotations, ads, quizzes, and custom triggers on the timeline.
  • Interactive video experiences — Build rich in-player interactions such as chapter navigation, slide synchronization, in-video quizzes, hotspot overlays, and ad insertion using cue points as the data layer.
  • Video timeline enrichment — Attach searchable text, thumbnails, and structured data to specific moments in a video, making content discoverable at the timestamp level via eSearch.
  • Cross-application integration — Provide a unified marker system consumed by the Player, KMC, KME, REACH, Content Lab, and external applications through a single API service.
  • Live and VOD workflows — Support both pre-authored cue points (REST API for VOD) and real-time cue points pushed during live broadcasts (socket.io from the media server).

2. Prerequisites​

  • KS (Kaltura Session): Admin KS (type=2) with disableentitlement for full cue point management. A USER KS (type=0) scoped to an entry is sufficient for reading cue points during playback.
  • Cue Points plugin: The base cuePoint server plugin must be enabled on the account. Individual cue point types require their respective plugins (thumbCuePoint, adCuePoint, codeCuePoint, annotation, quiz, etc.).
  • Player plugins: To render cue points during playback, enable kalturaCuepoints (core data loader) plus consumer plugins (navigation, dualscreen, ivq, timeline, hotspots) as needed.
  • Session management: See Session Guide for KS generation and privilege scoping.

3. Architecture Overview​

Cue points are a plugin-based system. Eight server plugins extend a common KalturaCuePoint base:

objectTypecuePointTypePurpose
KalturaThumbCuePointthumbCuePoint.ThumbChapters and slides (with thumbnail images)
KalturaAnnotationannotation.AnnotationText annotations, comments, hotspots
KalturaAdCuePointadCuePoint.AdAd insertion (VAST/VPAID)
KalturaCodeCuePointcodeCuePoint.CodeCustom programmatic triggers
KalturaQuestionCuePointquiz.QUIZ_QUESTIONQuiz questions
KalturaAnswerCuePointquiz.QUIZ_ANSWERQuiz viewer answers
KalturaEventCuePointeventCuePoint.EventLive broadcast start/end markers
KalturaSessionCuePointsessionCuePoint.SessionRecording session boundaries

All types share a common set of base fields and are managed through a single service (cuepoint_cuepoint), with additional services for quiz management (quiz_quiz, userEntry).

4. Base Cue Point Service​

Service: cuepoint_cuepoint

All cue point types are managed through this single service. The deprecated annotation_annotation service exists but has restricted actions — use cuepoint_cuepoint for all operations.

4.1 Actions​

ActionDescription
addCreate a cue point (pass objectType to specify type)
getRetrieve by ID
updateUpdate fields (must include cuePoint[objectType])
deleteSoft-delete (sets status to DELETED)
listList/filter cue points (requires identifying filter)
countCount matching cue points
cloneCopy a cue point to a different entry
updateStatusChange cue point status directly
updateCuePointsTimesUpdate start/end times without full update call
addFromBulkImport multiple cue points via XML file upload

4.2 Base Fields (shared by all types)​

FieldTypeDescription
idstringUnique cue point ID (readonly)
entryIdstringEntry this cue point belongs to (insert-only)
startTimeintPosition on the timeline in milliseconds
tagsstringComma-separated tags
partnerDatastringFree-form partner data (JSON-safe)
systemNamestringUnique name per entry (for stable references)
forceStopint1 = pause player at this cue point
statusint1=READY, 2=DELETED, 3=HANDLED, 4=PENDING
cuePointTypestringPlugin type identifier (readonly)
createdAtintUnix timestamp (readonly)
updatedAtintUnix timestamp (readonly)
copiedFromstringSource cue point ID if cloned (readonly)

4.3 Listing and Filtering​

Every list and count call requires at least one identifying filter:

Filter FieldDescription
entryIdEqual / entryIdInFilter by entry (most common)
idEqual / idInFilter by cue point ID(s)
cuePointTypeEqualFilter by type (e.g., codeCuePoint.Code)
tagsLike / tagsMultiLikeOrFilter by tags
statusEqual / statusInFilter by status
startTimeGreaterThanOrEqual / startTimeLessThanOrEqualTime range filter

Omitting all identifying filters returns PROPERTY_VALIDATION_CANNOT_BE_NULL.

4.4 Create Example​

curl -X POST "$KALTURA_SERVICE_URL/service/cuepoint_cuepoint/action/add" \
-d "ks=$KALTURA_KS" \
-d "format=1" \
-d "cuePoint[objectType]=KalturaCodeCuePoint" \
-d "cuePoint[entryId]=$KALTURA_ENTRY_ID" \
-d "cuePoint[startTime]=5000" \
-d "cuePoint[code]=marker-1" \
-d "cuePoint[tags]=chapter"

4.5 Update (objectType required)​

curl -X POST "$KALTURA_SERVICE_URL/service/cuepoint_cuepoint/action/update" \
-d "ks=$KALTURA_KS" \
-d "format=1" \
-d "id=$CUE_POINT_ID" \
-d "cuePoint[objectType]=KalturaCodeCuePoint" \
-d "cuePoint[code]=updated-marker"

4.6 Clone​

curl -X POST "$KALTURA_SERVICE_URL/service/cuepoint_cuepoint/action/clone" \
-d "ks=$KALTURA_KS" \
-d "format=1" \
-d "id=$SOURCE_CUE_POINT_ID" \
-d "entryId=$TARGET_ENTRY_ID"

Returns a new cue point with copiedFrom set to the source ID.

4.7 Status Enum​

ValueNameMeaning
1READYActive, usable
2DELETEDSoft-deleted
3HANDLEDProcessed/handled
4PENDINGAwaiting asset (thumb cue points without images)

5. Cue Point Types​

Each type has a dedicated guide with fields, curl examples, and player integration details:

TypeobjectTypeDedicated GuideUse Cases
Chapters & SlidesKalturaThumbCuePointChapters & Slides APITimeline navigation, slide sync, timedThumbAsset images
AnnotationsKalturaAnnotationAnnotations APIText annotations, threaded comments, hotspots
Ad Cue PointsKalturaAdCuePointAd Cue Points APIVAST/VPAID ad insertion, pre/mid/post-roll, overlays
Code / Event / SessionKalturaCodeCuePoint, KalturaEventCuePoint, KalturaSessionCuePointCode, Event & Session APIGeneric markers, view-change, broadcast events, recording sessions
Interactive Video QuizKalturaQuestionCuePoint, KalturaAnswerCuePointInteractive Video Quiz APIIn-video quizzes with scoring, 8 question types, reports

6. Protocols: REST API vs Live Push​

Cue points reach the player through two protocols:

REST API (VOD and on-demand): The kalturaCuepoints player plugin calls cuePoint.list to load all cue points for an entry when playback starts. Updates require a page refresh or API re-query.

Socket.io push (live streaming): During live broadcasts, the media server pushes cue point events to connected players in real time via socket.io. This enables:

  • Slide changes during live presentations (KME creates thumb cue points as the presenter advances slides)
  • Broadcast start/end markers (event cue points auto-created by the media server)
  • Real-time annotations and polls pushed during live sessions

The player receives TIMED_METADATA_ADDED events as new cue points arrive via either protocol.

7. Applications​

Cue points are created and consumed across multiple Kaltura applications:

ApplicationCreatesConsumesProtocol
KMC (management console)Manual cue point creation via UI—REST
Player v7—Renders all types (timeline, overlays, navigation, quiz)REST + socket.io
KME (meetings)Slide cue points during live presentations—REST (push to live entry)
Media serverEvent (broadcast start/end) and session cue points automatically—Internal
REACH / Content LabAI-generated chapters, quizzes, summaries—REST (async task → cue points)
Backend integrationsProgrammatic cue point management via API—REST
Bulk importaddFromBulk XML file upload—REST

8. eSearch Integration​

Cue point content is indexed in Elasticsearch and searchable via KalturaESearchCuePointItem.

8.1 Searchable Fields​

Field NameWhat It IndexesSearch Modes
idCue point IDexact
nameTitle (slide/chapter title, code, ad title)exact, partial, starts_with, exists
textText content (annotation text, OCR from slides)exact, partial, starts_with, exists
tagsTagsexact, partial, starts_with, exists
typeCue point typeexact
sub_typeSub-type (1=slide, 2=chapter)exact
questionQuiz question textexact, partial, starts_with, exists
answersQuiz answer option textexact, partial, starts_with, exists
hintQuiz hint textexact, partial, starts_with, exists
explanationQuiz explanation textexact, partial, starts_with, exists
start_timeStart time in millisecondsrange
end_timeEnd time in millisecondsrange

8.2 Search Within Slide OCR Text​

Find entries containing slides with specific text:

curl -X POST "$KALTURA_SERVICE_URL/service/elasticsearch_esearch/action/searchEntry" \
-d "ks=$KALTURA_KS" \
-d "format=1" \
-d "searchParams[objectType]=KalturaESearchEntryParams" \
-d "searchParams[searchOperator][objectType]=KalturaESearchEntryOperator" \
-d "searchParams[searchOperator][operator]=1" \
-d "searchParams[searchOperator][searchItems][0][objectType]=KalturaESearchCuePointItem" \
-d "searchParams[searchOperator][searchItems][0][itemType]=2" \
-d "searchParams[searchOperator][searchItems][0][fieldName]=text" \
-d "searchParams[searchOperator][searchItems][0][searchTerm]=machine learning" \
-d "searchParams[searchOperator][searchItems][0][addHighlight]=1"

itemType: 1=EXACT_MATCH, 2=PARTIAL, 3=STARTS_WITH, 4=EXISTS, 5=RANGE

8.3 Search Quiz Questions​

curl -X POST "$KALTURA_SERVICE_URL/service/elasticsearch_esearch/action/searchEntry" \
-d "ks=$KALTURA_KS" \
-d "format=1" \
-d "searchParams[objectType]=KalturaESearchEntryParams" \
-d "searchParams[searchOperator][objectType]=KalturaESearchEntryOperator" \
-d "searchParams[searchOperator][operator]=1" \
-d "searchParams[searchOperator][searchItems][0][objectType]=KalturaESearchCuePointItem" \
-d "searchParams[searchOperator][searchItems][0][itemType]=2" \
-d "searchParams[searchOperator][searchItems][0][fieldName]=question" \
-d "searchParams[searchOperator][searchItems][0][searchTerm]=design pattern"

KalturaESearchUnifiedItem automatically searches across all entry data including cue point content:

curl -X POST "$KALTURA_SERVICE_URL/service/elasticsearch_esearch/action/searchEntry" \
-d "ks=$KALTURA_KS" \
-d "format=1" \
-d "searchParams[objectType]=KalturaESearchEntryParams" \
-d "searchParams[searchOperator][objectType]=KalturaESearchEntryOperator" \
-d "searchParams[searchOperator][operator]=1" \
-d "searchParams[searchOperator][searchItems][0][objectType]=KalturaESearchUnifiedItem" \
-d "searchParams[searchOperator][searchItems][0][itemType]=2" \
-d "searchParams[searchOperator][searchItems][0][searchTerm]=dependency injection"

9. Player Plugin Ecosystem​

Five Player v7 plugins form the cue point rendering ecosystem:

KalturaPlayer.setup({ plugins: { ... } })
│
├── kalturaCuepoints ← Core: loads data, dispatches TimedMetadata events
│ ├── VOD: API requests (cuePoint.list)
│ └── Live: socket.io push notifications
│
├── timeline ← Seekbar markers, chapter segments
├── navigation ← Side panel (chapters, slides, captions, quiz, search)
├── ivq ← Quiz overlay, seek prevention, scoring
└── dualscreen ← Slide sync, PIP/side-by-side layouts

9.1 Core Plugin: kalturaCuepoints​

The foundation plugin that loads cue point data and feeds it to consumer plugins:

plugins: {
kalturaCuepoints: {}
}

Consumer plugins register the types they need via player.getService('kalturaCuepoints').registerTypes([...]). Only registered types are fetched from the API.

Cue point types in the player:

TypeValueSource
SLIDE'slide'ThumbCuePoint (subType=1)
CHAPTER'chapter'ThumbCuePoint (subType=2)
HOTSPOT'hotspot'Annotation (tag=hotspots)
QUIZ'quiz'QuestionCuePoint
VIEW_CHANGE'viewchange'CodeCuePoint (tag=change-view-mode)
CAPTION'caption'Caption segments

Events dispatched:

  • TIMED_METADATA_ADDED — fired when cue points are loaded
  • TIMED_METADATA_CHANGE — fired on each time update with active/inactive cue points

9.2 Full Setup Example​

var player = KalturaPlayer.setup({
targetId: 'player-container',
plugins: {
kalturaCuepoints: {},
timeline: {},
navigation: {
expandOnFirstPlay: true,
position: 'right',
itemsOrder: { Chapter: 1, Slide: 2, Caption: 3 }
},
ivq: {},
dualscreen: {
layout: 'PIP',
position: 'bottom-right',
childSizePercentage: 30
}
}
});
player.loadMedia({ entryId: '1_abc123' });

For plugin-specific configuration details, see the dedicated type guides:

10. Bulk Operations​

10.1 XML Import​

Upload multiple cue points via cuePoint.addFromBulk with an XML file:

<?xml version="1.0" encoding="UTF-8"?>
<scenes>
<scene-thumb-cue-point entryId="1_abc123">
<sceneStartTime>00:00:05.000</sceneStartTime>
<tags><tag>chapter</tag></tags>
<title>Introduction</title>
<description>Opening section</description>
<subType>2</subType>
</scene-thumb-cue-point>

<scene-annotation entryId="1_abc123">
<sceneStartTime>00:01:30.000</sceneStartTime>
<sceneEndTime>00:02:00.000</sceneEndTime>
<sceneText>Key concept explained here</sceneText>
<tags><tag>important</tag></tags>
</scene-annotation>

<scene-code-cue-point entryId="1_abc123">
<sceneStartTime>00:05:00.000</sceneStartTime>
<code>section-break</code>
<description>Topic transition</description>
</scene-code-cue-point>

<scene-ad-cue-point entryId="1_abc123">
<sceneStartTime>00:03:00.000</sceneStartTime>
<sourceUrl>https://example.com/vast.xml</sourceUrl>
<adType>1</adType>
<protocolType>2</protocolType>
</scene-ad-cue-point>
</scenes>

XML element names: scene-thumb-cue-point, scene-annotation, scene-code-cue-point, scene-ad-cue-point, scene-session-cue-point, scene-question-cue-point, scene-answer-cue-point

10.2 Clone Support​

TypeClonableClone Option Constant
AdYesAD_CUE_POINTS
AnnotationYesANNOTATION_CUE_POINTS
CodeYesCODE_CUE_POINTS
SessionYesSESSION_CUE_POINTS
ThumbYesTHUMB_CUE_POINTS
EventNo—
Quiz (Question/Answer)No—

10.3 Custom Metadata​

Ad, Annotation, Code, Thumb, and Quiz cue points support custom metadata profiles (XSD schemas attached to cue points via the Metadata API). This enables structured data on individual cue points beyond the built-in fields.

11. Error Handling​

ErrorCauseFix
PROPERTY_VALIDATION_CANNOT_BE_NULLList/count without identifying filterInclude entryIdEqual, entryIdIn, idEqual, or idIn
INVALID_CUE_POINT_IDCue point not found or already deletedVerify ID exists and status is not DELETED
CUE_POINT_SYSTEM_NAME_EXISTSDuplicate systemName on the same entrySystem names must be unique per entry
NO_PERMISSION_ON_ENTRYKS limitEntry privilege mismatchEnsure KS has access to the target entry

12. Best Practices​

  • Times are in milliseconds. A cue point at 1 minute 30 seconds = startTime=90000.
  • Use cuepoint_cuepoint service for all operations. The annotation_annotation service is deprecated and has restricted actions.
  • Include objectType on updates. The API needs it to determine which fields to apply.
  • Register cleanup before assertions in tests. Cue points persist on entries — always clean up test cue points.
  • eSearch indexing has a delay. Newly created cue points may take seconds to appear in search results. Use cuePoint.list for immediate retrieval.
  • Filter is mandatory. Every list/count call must include at least one identifying filter field.
  • Use forceStop=1 to pause the player at a cue point (works for all types, not just quizzes).

Dedicated type guides:

Cross-references: