Skip to content

Kaltura Annotations API

Annotations are text-based cue points that support hierarchical threading
(parent-child relationships) and interactive hotspot overlays.
Use annotations for timestamped comments, notes, and clickable regions on video.

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
Service: cuepoint_cuepoint (shared with all cue point types)
objectType: KalturaAnnotation
Prerequisite: Cue Points Hub for base cue point concepts and shared CRUD

1. When to Use Annotations

  • Timestamped notes — Mark moments in a video with text commentary
  • Threaded discussions — Build comment threads anchored to specific video times
  • Interactive hotspots — Clickable regions on the video frame (via the hotspots tag)
  • Content tagging — Mark segments for review, approval, or searchability

2. Fields (in addition to base)

Field Type Description
text string Annotation text content
parentId string Parent annotation ID (insert-only; 0 = no parent)
endTime int End time in milliseconds
duration int Computed from startTime to endTime (readonly)
depth int Nesting depth in annotation tree (readonly)
childrenCount int Total descendants (readonly)
directChildrenCount int First-level children (readonly)
isPublic int Public visibility (-1=null, 0=false, 1=true)
searchableOnEntry int Index on entry search (-1=null, 0=false, 1=true)

3. Create an Annotation

curl -X POST "$KALTURA_SERVICE_URL/service/cuepoint_cuepoint/action/add" \
  -d "ks=$KALTURA_KS" \
  -d "format=1" \
  -d "cuePoint[objectType]=KalturaAnnotation" \
  -d "cuePoint[entryId]=1_abc123" \
  -d "cuePoint[startTime]=45000" \
  -d "cuePoint[endTime]=60000" \
  -d "cuePoint[text]=Key concept: dependency injection" \
  -d "cuePoint[isPublic]=1" \
  -d "cuePoint[searchableOnEntry]=1"

4. Threaded Annotations

Create child annotations by setting parentId:

curl -X POST "$KALTURA_SERVICE_URL/service/cuepoint_cuepoint/action/add" \
  -d "ks=$KALTURA_KS" \
  -d "format=1" \
  -d "cuePoint[objectType]=KalturaAnnotation" \
  -d "cuePoint[entryId]=1_abc123" \
  -d "cuePoint[parentId]=1_parent_cp" \
  -d "cuePoint[startTime]=45000" \
  -d "cuePoint[text]=Reply: great explanation of DI patterns"

The parent must exist on the same entry. The depth, childrenCount, and directChildrenCount fields update automatically on both the parent and the new child.

5. Hotspot Pattern

Interactive video hotspots are annotation cue points with the hotspots tag. Creating hotspot-tagged annotations requires edit entitlement on the entry:

curl -X POST "$KALTURA_SERVICE_URL/service/cuepoint_cuepoint/action/add" \
  -d "ks=$KALTURA_KS" \
  -d "format=1" \
  -d "cuePoint[objectType]=KalturaAnnotation" \
  -d "cuePoint[entryId]=1_abc123" \
  -d "cuePoint[startTime]=10000" \
  -d "cuePoint[endTime]=20000" \
  -d "cuePoint[text]=Click here for details" \
  -d "cuePoint[tags]=hotspots"

Hotspot behavior (jump, pause, URL) and position data are stored in partnerData as structured JSON:

  -d "cuePoint[partnerData]={\"x\":10,\"y\":20,\"width\":30,\"height\":25}"

The Player v7 navigation plugin renders hotspots as timeline markers and displays them in the side panel.

6. searchableOnEntry Flag

Set searchableOnEntry=1 to make the annotation text searchable at the entry level in eSearch. Without this flag, the annotation text is only findable via cue-point-specific search queries.

7. Annotation Service Note

The legacy annotation_annotation service exists but several actions are restricted (count, updateStatus, updateCuePointsTimes, clone return SERVICE_FORBIDDEN). Use the cuepoint_cuepoint service for all annotation operations.

Index delay: Newly created annotations may take a few seconds to appear in entryIdEqual list queries due to search indexing. Retrieval by idEqual or idIn is immediate.

8. Player Integration

The navigation plugin displays annotations in the side panel and renders hotspots as timeline markers:

plugins: {
  kalturaCuepoints: {},
  navigation: {
    expandOnFirstPlay: true,
    itemsOrder: { Hotspot: 1, Chapter: 2, Caption: 3 }
  }
}

Only annotation types listed in itemsOrder are shown. Hotspot annotations appear when Hotspot is included.

9. Searching Annotations

Annotation text is indexed in eSearch via KalturaESearchCuePointItem with fieldName=text. See Cue Points Hub — eSearch Integration for query examples.

10. Error Handling

Error Cause Fix
PROPERTY_VALIDATION_CANNOT_BE_NULL List without identifying filter Include entryIdEqual, entryIdIn, idEqual, or idIn
INVALID_CUE_POINT_ID Cue point not found or already deleted Verify ID exists and status is not DELETED
PARENT_CUE_POINT_NOT_FOUND Invalid parentId Parent must exist on the same entry

11. 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.
  • Set searchableOnEntry=1 for annotations that should be discoverable at the entry level in search.
  • Use isPublic=1 for viewer-visible annotations. Set to 0 for internal/editorial annotations.
  • eSearch indexing has a delay. Newly created annotations may take seconds to appear in search results. Use cuePoint.list with idEqual for immediate retrieval.
  • Hotspot position data goes in partnerData. Use structured JSON for x, y, width, height coordinates.

12. Related Guides