Docs

Send events

Send playback events to your analytics service.

The tracker includes adapters for Chunkify Analytics, PostHog, Datadog RUM, and OpenTelemetry via OTLP/HTTP. You can also send events to your own HTTP endpoint or write a custom handler.

Use the PostHog adapter to capture playback events with your PostHog browser client, or the Datadog RUM adapter to record them as custom actions. Both work without a Chunkify Analytics Server.

If you followed player setup, replace the console destination with one of these examples. You can add several destinations to send the same events to more than one service.

Choose a destination

Each example creates a destination that you can pass to your player's analytics options. Add the imports at the top of your browser module.

Set up an Analytics Server, hosted by Chunkify or by you. Copy its server URL and public Player key. Append /v1/events to the server URL:

import { createChunkifyAdapter } from '@chunkify/player-analytics/chunkify';

const destination = createChunkifyAdapter(
    'https://analytics.example.com/v1/events',
    {
        ingestKey: 'YOUR_PUBLIC_PLAYER_KEY',
    },
);

The adapter sends one complete JSON event with X-Chunkify-Ingest-Key. It adds browser, device, language, screen, and current page context in browser_context.

Set collectBrowserContext: false to omit that context. The core playback measurements are still sent.

Temporary delivery failures are retried by default. This adapter preserves the Analytics Server's expected schema and has no custom mapping option.

Add your website origin in server configuration, then open the Chunkify dashboard to inspect the results.

Use the resulting destination in your selected player example. For instance, with a native <video> already on the page:

import { monitor } from '@chunkify/player-analytics';

const video = document.querySelector('video');
if (!video) throw new Error('Missing video element');

const session = monitor(video, {
    videoId: 'ast_3Ljtoej7c3Y1plabZoElbQwdwLh',
    destinations: [destination],
});

Keep the matching connector for hls.js, Video.js 10, or Shaka Player. Each accepts the same destinations option. Call session.destroy() when monitoring stops.

Map event fields

Use createEventMapper() to select fields, rename them, or calculate values. Only the listed fields are included in the mapped object. The original event is preserved for other destinations.

This example keeps the event identifiers and converts playing time to seconds for an HTTP endpoint:

import { createEventMapper } from '@chunkify/player-analytics';
import { createHttpAdapter } from '@chunkify/player-analytics/http';

const mapEvent = createEventMapper({
    eventId: 'event_id',
    eventName: 'event_name',
    viewId: 'view_id',
    videoId: 'video_id',
    sequence: 'sequence',
    occurredAt: 'occurred_at',
    playingSeconds: (event) => (
        typeof event.playing_time_ms === 'number'
            ? event.playing_time_ms / 1000
            : undefined
    ),
});

const destination = createHttpAdapter('/api/video-analytics', { mapEvent });

A string copies the named source field. A function calculates its value. Missing fields and values returned as undefined are omitted; null is preserved by the mapper.

For example, playingSeconds is omitted from a rendition-change record because that event has no cumulative playing time. See Events and metrics for each payload.

Destination Apply your mapper
HTTP createHttpAdapter(endpoint, { mapEvent })
PostHog createPostHogAdapter(client, mapEvent)
Datadog RUM createDatadogAdapter(client, mapEvent)
OTLP createOtlpAdapter(endpoint, { mapAttributes: mapEvent })
Custom send() Call mapEvent(event) inside your handler.
Chunkify Analytics Sends the complete Chunkify Analytics schema. No mapper option.

Mapping changes a destination's payload. To choose which event types are delivered, use includeEvents.

Use multiple destinations

Add each destination to the array. For example, send complete events to your endpoint while also inspecting them in the console:

import { monitor } from '@chunkify/player-analytics';
import { createHttpAdapter } from '@chunkify/player-analytics/http';

const video = document.querySelector('video');
if (!video) throw new Error('Missing video element');

const session = monitor(video, {
    videoId: 'ast_3Ljtoej7c3Y1plabZoElbQwdwLh',
    destinations: [
        createHttpAdapter('/api/video-analytics'),
        { send: (event) => console.log(event) },
    ],
});

Delivery runs independently for each destination. A thrown error or rejected Promise is isolated so it does not interrupt playback or another destination. Handle errors in your custom code when you need delivery diagnostics.

Browser delivery

HTTP-based adapters accept HTTPS URLs or root-relative paths. Endpoints cannot contain credentials, query parameters, or fragments. Loopback HTTP is also accepted for local development.

The HTTP, OTLP, and Chunkify adapters send JSON without cookies or a page referrer. A cross-origin endpoint must allow your page origin, POST, Content-Type, and any configured public ingest header through CORS.

Keep private provider credentials and analytics secret keys on your server. Browser examples use public client or ingest keys.

Retries and limits

Destination Retry behavior
Chunkify Analytics Enabled by default. Set retry: false to disable.
HTTP and OTLP Disabled by default. Set retry: true to enable.
PostHog and Datadog RUM Managed by their browser clients.
Custom send() Managed by your code.

When enabled, HTTP retries cover network failures, request timeouts, and HTTP 429, 502, 503, and 504. There are at most two retries after the initial request.

The HTTP transport times out each request after five seconds and allows 32 pending sends per adapter. Further sends fail immediately while it is full. It has no offline storage or waiting queue.

A readable Retry-After header can extend the backoff. A delay over ten seconds ends delivery instead. Cross-origin endpoints must expose Retry-After for the browser to read it.

Retries reuse the same serialized event and browser context. Your receiver must tolerate duplicates; preserve event_id when mapping fields. Use sequence to order records within a view.

The Analytics Server keeps the first delivery of an event ID received within its deduplication window, seven days by default. Use view-level report totals, and deduplicate raw events by event_id in your own consumers.

Final HTTP events use a keepalive request, but delivery when a page exits is best effort. A successful HTTP send means the endpoint returned a 2xx status.