Getting started

Integration & migration

Image & video API

Video Player SDK

DAM user guide

API overview

Account

Video analytics

Track viewer engagement, quality of experience, errors, and custom dimensions with ImageKit Video player's built-in analytics.


ImageKit video player ships with a built-in analytics module that reports engagement and quality-of-experience metrics for every playback session. Add an analytics object to your IKPlayer options to start collecting data and view results in the ImageKit dashboard under video analytics.

Enterprise plan only
Video analytics is available only on custom enterprise pricing plans. Contact us to enable it for your account.

The feature is currently in beta and actively evolving. Metric definitions and dashboard layouts may change before general availability.

What gets tracked

Analytics is opt-in. Set analytics.enabled to true to start. Once enabled, the player automatically collects data across four areas:

  • Engagement: Who watches, how long, and how much of each video they complete
  • Performance: Page, player, and video startup times plus seek responsiveness
  • Reliability: Rebuffering, startup failures, and mid-stream errors
  • Quality: Bitrate delivered vs. what the screen actually needed

All data is available in the dashboard with filters by device, browser, OS, country, video, and more. See Metrics for the full list.

Quick setup

Pass an analytics object on ikOptions with enabled: true to start the tracker. All other fields are optional.

Copy
import { videoPlayer } from '@imagekit/video-player';
import '@imagekit/video-player/styles.css';

const player = videoPlayer('my-video', {
  imagekitId: 'YOUR_IMAGEKIT_ID',
  analytics: {
    enabled: true,                // required to start the tracker
    userId: 'anon-user-abc123',  // optional anonymized ID, not email/username
    customDimensions: {
      cd_1: '2.1.0',              // playerVersion
      cd_2: 'experiment-b'        // experimentBucket
    }
  }
});

player.src({ src: 'https://ik.imagekit.io/<your-imagekit-id>/video.mp4' });

Analytics options

Parameter Description
enabled (required)
boolean
Set to true to start the analytics tracker. The tracker is otherwise inactive.
Default: false
userId
string
Opaque, anonymized identifier for the end user. Used to compute Unique Users and to look up sessions per user. Do not pass values that are personally identifiable on their own (such as email or username); use an opaque ID from your system. If omitted, Unique Users counts will not be meaningful.

customDimensions
object

Per-session custom dimensions keyed by dimension key (cd_1, cd_2, …). See custom dimensions.

Copy
{
  cd_1: 'string',
  cd_2: 'string',
  // ...
}

mapError
function

Callback to remap or enrich an error before it is reported. Receives { code, message, context } and returns an object with any subset of those fields (omitted fields keep their original value). Return null or undefined to keep the error unchanged. See error tracking.

Copy
(error) => { code?, message?, context? } | null | undefined

Metrics

All metrics below appear in the dashboard under Video analytics → Metrics, and can be sliced by any of the dimensions listed further down.

Engagement

Metric Definition
Total ViewsNumber of times a video successfully started playing in the selected period. Optionally expanded to include all playback attempts, including sessions where the first frame never appeared.
Unique UsersNumber of distinct userIds with at least one successful view per time bucket. Requires userId to be set for meaningful counts.
Playing TimeTotal time content was actively playing. Excludes seek time, rebuffering, and time while paused.
Playback Completed by UsersDistribution of users by the maximum completion percentage they reached. Replays by the same user do not count separately.
Playback Completed by ViewsDistribution of playback sessions by completion percentage. Every replay counts as a separate session.
Audience RetentionPer-video timeline curve showing where viewers leave, skip, or continue. Requires a Video Source URL filter to scope to a single asset.

Timing & latency

Metric Definition
Page Load TimeTime from the initial page request until the player is first initialized on the page. Typically recorded only for the first video on a page.
Player Startup TimeTime for the player itself to initialize and become ready for playback. Does not include the network fetch of the first frame.
Video Startup TimeTime from playback intent (autoplay or user action) to the first rendered video frame.
Seek LatencyTime between a seek action and playback resumption, summarized as percentiles across views.

Playback health

Metric Definition
Re-buffer PercentageShare of total watch time spent rebuffering after playback started. Aggregate ratio across all views in each time bucket.
Re-buffer DurationPer-view seconds spent in rebuffer stalls, summarized as percentiles.
Re-buffer FrequencyNumber of rebuffer events per minute of total watch time. Aggregate across all views.
Re-buffer CountPer-view number of distinct rebuffer events, summarized as percentiles.
Abandoned Before Start PercentageShare of attempts where the user left before the first frame and no error was recorded: voluntary startup abandonment.
Video Startup Failure PercentageShare of attempts where the first frame never appeared because of a recorded error. Codes you mark as business exceptions are excluded by default (see error tracking).
Playback Failed PercentageShare of views where a fatal error occurred after playback had started. Codes you mark as business exceptions are excluded by default.

Quality

These metrics are most meaningful when serving Adaptive Bitrate Streaming (ABS) content (HLS or DASH), where the player switches renditions based on network conditions.

Metric Definition
Upscale PercentageMaximum upscale percentage during a view. Non-zero values mean the player enlarged the decoded video to fit the display.
Downscale PercentageMaximum downscale percentage during a view. Large values mean the delivered rendition was higher resolution than the display needed.
Weighted Average BitratePer-view time-weighted average of the bitrates actually played, summarized as percentiles across views.

Breakdowns

In addition to the time-series metrics above, the dashboard surfaces top-N breakdowns: Top Devices, Top Operating Systems, Top Browsers, Top Countries, and Top Videos.

Events

The metrics above are derived from a stream of playback events the player emits automatically once analytics is enabled. You don't subscribe to or handle these events yourself; they are sent to ImageKit in the background and listed here for transparency about what the player tracks. You can see the full event timeline for any individual playback on the playback detail page.

Events are grouped into sessions and views:

  • A session is a viewer's continuous engagement within one browser, shared across all players, tabs, and page loads on the same site. It can span multiple videos and resets after 60 minutes of inactivity or 24 hours, whichever comes first. A different browser, profile, or incognito window gets its own session.
  • A view is a single video playback within a session, identified by a playbackId. Most metrics are computed per view.
Event When it fires
sessioninitA new session begins: the first playback on a page, or after a session reset due to inactivity or the 24-hour limit.
playerreadyThe player has initialized and is ready for playback.
viewinitA view opens for a video source, either on initial load or when the source changes.
viewstartedThe first video frame has rendered for the view.
playPlayback intent was registered, from autoplay or a user action.
playingActive playback began or resumed (including after a pause, seek, or rebuffer).
pausePlayback was paused.
timeupdatePeriodic progress heartbeat carrying the current playhead position, cumulative playing time, and current bitrate.
seeking / seekedA seek started and then completed. Together they capture seek latency.
rebufferstart / rebufferendA mid-playback stall began and then ended. Together they capture rebuffer duration.
videochangeThe player switched to a new video source within the same session.
errorA playback error was recorded, or an error was reported manually. Feeds the failure metrics described under error tracking.
endedPlayback reached the end of the video. This does not close the view; a replay or seek continues on the same view.
viewendThe view closed. The reason is one of videochange (source switched), error (fatal error), dispose (player was destroyed), navigation (user left the page), or sessionrotate (session idle timeout).

Dimensions and breakdowns

Every metric can be filtered or grouped by the dimensions below. All dimensions are derived server-side from the request and User-Agent. The only ones you control from the player are User ID (userId) and Custom dimensions (customDimensions).

Viewer

Dimension Description & examples
User IDThe opaque identifier you pass on analytics.userId. Example: anon-user-abc123

Client

Dimension Description & examples
BrowserBrowser name. Examples: Chrome, Safari, Edge, Firefox
Browser VersionBrowser major version. Examples: 124, 17.4
Operating SystemOS name. Examples: iOS, Android, macOS, Windows
OS VersionOS version string. Examples: 17.4, 14, 10
Page URLFull URL of the page hosting the player. Example: https://example.com/videos/launch

Device

Dimension Description & examples
Device CategoryDevice class. Examples: mobile, tablet, desktop, tv, console
Device ArchitectureCPU architecture. Examples: arm64, x86_64
Display WidthScreen width in CSS pixels. Example: 1920
Display HeightScreen height in CSS pixels. Example: 1080
Display DPRDevice pixel ratio. Examples: 1, 2, 3

Geo

Dimension Description & examples
CountryCountry via GeoIP. Examples: India, United States, Germany
StateState or region. Examples: Karnataka, California
CityCity name. Examples: Bengaluru, San Francisco

Player

Dimension Description & examples
Player SoftwarePlayer name. Example: imagekit-video-player
Player Software VersionPlayer version. Example: 1.4.0
ImageKit PluginImageKit plugin identifier. Example: analytics-js
ImageKit Plugin VersionPlugin version. Example: 1.4.0

Video metadata

Dimension Description & examples
Video Source TypeMIME type of the source. Examples: application/x-mpegURL, video/mp4, application/dash+xml. See Adaptive Bitrate Streaming for HLS and DASH delivery.
Video Source URLFull source URL. Example: https://ik.imagekit.io/<id>/launch.m3u8
Video Source HostnameHostname of the source URL. Example: ik.imagekit.io
Audio CodecDetected audio codec. Example: mp4a.40.2
Video CodecDetected video codec. Examples: avc1.640028, hvc1

Error

Dimension Description & examples
Error CodePlayer error code (or remapped via mapError). Examples: 2, network-or-geo
Exited Before Video StartWhether the view ended before the first frame. Values: true, false

Playback

Dimension Description & examples
AutoplayedWhether autoplay was active. Values: true, false
PreloadPreload attribute. Values: auto, metadata, none

Custom dimensions (user-defined)

Dimension Description & examples
cd_1, cd_2, …Values you pass in analytics.customDimensions. Keyed by the dimension key assigned in the dashboard. See custom dimensions.

Custom dimensions

Custom dimensions let you slice analytics by metadata that's specific to your application. for example, app version, A/B test bucket, content category, or subscription tier.

ImageKit uses a two-step model:

  1. Register the dimension in the dashboard under Settings → Video analytics → Custom dimensions. You provide a human-readable label (and optional description); the dashboard assigns a stable dimension key such as cd_1, cd_2, …
  2. Send values from the player keyed by the dimension key (not the label).

Why dimension keys?
Dimension keys (cd_1, cd_2, …) are immutable identifiers. You can rename or disable a dimension's label at any time without breaking historical data, and the wire payload stays small.

Setting custom dimensions

Pass customDimensions in analytics at player initialization, or update them at any time during a session with setCustomDimensions.

Copy
const player = videoPlayer('my-video', {
  imagekitId: 'YOUR_IMAGEKIT_ID',
  analytics: {
    enabled: true,
    customDimensions: {
      cd_1: '2.1.0',          // playerVersion
      cd_2: 'experiment-b',   // experimentBucket
      cd_3: 'premium'         // subscriptionTier
    }
  }
});

// Replace the entire map at runtime (e.g. after the viewer signs in)
player.imagekitVideoPlayer().setCustomDimensions({
  cd_1: '2.1.0',
  cd_2: 'experiment-b',
  cd_3: 'enterprise'
});

// Inspect the currently effective values
player.imagekitVideoPlayer().getCustomDimensions();

Limits and rules

  1. The number of active custom dimensions per account depends on your plan. See pricing.
  2. Values are strings only. Values longer than 256 characters are dropped client-side.
  3. Disabling a dimension from the dashboard reserves its key permanently; the same key (cd_N) is never reassigned to a new label. This keeps historical data consistent.
  4. Keys you send that are not registered for your account are ignored.

Use cases

  • Release impact: Set a key to your player or app version and compare error rates across releases.
  • A/B testing: Bucket viewers into experiments and compare quality of experience between groups.
  • Content classification: Tag views with content category, genre, or producer to surface which categories perform best.
  • Plan-based analysis: Track which tier (free, premium, enterprise) is experiencing issues.

Error tracking

The player automatically reports playback errors with the following fields:

  • Error code: the player error code (e.g. Video.js MediaError code)
  • Error message: human-readable description from the player
  • Error context: JSON-serialized raw error object for debugging

Errors appear in the dashboard under Video analytics → Errors with their full context and contribute to Video Startup Failure Percentage and Playback Failed Percentage.

Remapping errors with mapError

Use mapError to rewrite the error code, message, or context before it reaches analytics. Common uses:

  • Group errors more usefully in dashboards (e.g. extract the specific HLS failure type instead of the generic HTML5 MediaError code). See example below.
  • Add your own context like a build version or request ID so you can correlate spikes with releases.
  • Redact sensitive data from context if needed.

mapError receives { code, message, context } and may return any subset of those keys. Returning nothing keeps the original values.

Copy
const player = videoPlayer('my-video', {
  imagekitId: 'YOUR_IMAGEKIT_ID',
  analytics: {
    enabled: true,
    mapError: (err) => {
      try {
        const ctx = JSON.parse(err.context || '{}');
        // For HLS/DASH errors, ctx.metadata.errorType is something like
        // 'networkrequestfailed' or 'networkrequesttimeout', much more
        // actionable than the generic HTML5 MediaError code.
        if (ctx.metadata?.errorType) {
          return {
            code: ctx.metadata.errorType,
            // You can also enrich `context` to correlate spikes with releases:
            // context: JSON.stringify({ ...ctx, build: window.__BUILD_SHA__ })
          };
        }
      } catch { /* ignore */ }
    }
  }
});

Business exceptions

Some errors aren't real playback failures. Certain conditions are expected outcomes you don't want polluting your failure metrics.

Classify these in the dashboard under "Error Configuration" in video analytics settings: add the error code (the one reported by the player, or the one you produce via mapError), give it a label, and mark it as a business exception.

  • Business-exception codes are excluded by default from Video Startup Failure Percentage and Playback Failed Percentage.
  • Toggle "Show excluded errors" on either metric to display business exceptions as a separate line for visibility.

  • The standard HTML5 MediaError codes (14) are seeded automatically and treated as real errors unless you mark them as exceptions.

The player itself does not classify error severity. Every error reaches the dashboard with the same shape, and classification is applied at query time based on your configuration.

Best practices

  1. Keep userId anonymous. Always pass an opaque, anonymized value (e.g. a hashed internal ID). Never use an email, username, or anything personally identifiable on its own.
  2. Use custom dimensions sparingly. High-cardinality values (e.g. unique session tokens) reduce query performance. Prefer low-to-medium cardinality fields like app version, experiment bucket, or content category.
  3. Set mapError early so error codes are normalized before they reach the dashboard, keeping your error configuration consistent across releases.
  4. Disable in development. Omit the analytics object or set analytics.enabled to false to avoid polluting production metrics with test traffic.
  5. No cookies. The analytics module sets no cookies and collects no PII by default.