Docs

Setup

Set up your Analytics Server.

Choose hosted analytics or run your own server, then connect your player.

Before you begin

You need a Chunkify Project, owner access to its settings, and an application with a playable video and the playback tracker.

Your production website must use the server's public HTTPS address. Keep private analytics keys on your backend; the tracker uses only a public player key.

Use analytics hosted by Chunkify

1

Add an Analytics Server

Open your Project's Analytics > Settings, select Add server, and choose Hosted by Chunkify. Give it a name and create it.

2

Allow your website

Open the server's configuration and add your application's origin under Allowed origins. Include its scheme and port when present, such as https://app.example.com or http://localhost:3000.

3

Copy the player settings

Copy the server URL and the public Player key from its settings. Use them in the tracker example below.

4

Send events and open Analytics

Play a video in your application, then open Analytics in Chunkify and select that server. Use a date range that includes the playback attempt.

Connect your player

Replace the URL and public key with the settings from your server, and the sample Asset ID with your video's ID. The endpoint includes /v1/events. This example uses an existing native <video> element:

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

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

const session = monitor(video, {
    videoId: 'ast_3Ljtoej7c3Y1plabZoElbQwdwLh',
    destinations: [
        createChunkifyAdapter('https://analytics.chunkify.dev/v1/events', {
            ingestKey: 'YOUR_PUBLIC_PLAYER_KEY',
        }),
    ],
});

Use the appropriate player connector for Chunkify Player, hls.js, Video.js 10, or Shaka. Keep session and call session.destroy() when removing the player or disabling tracking.

Use any stable ID to identify your video. If you use the ID of an Asset in the same Chunkify Project, the Chunkify dashboard also links to that Asset and displays its title, poster, and timeline thumbnails when available.

Replace any existing tracking session rather than attaching a second one to the same player.

The tracker sends snapshots during playback and a final event when the attempt ends. Watch time may still be zero immediately after playback starts. See Send events for context and delivery options.

Default for dashboard players selects the server used by Chunkify previews, the playground, and newly generated player snippets. Existing players on your website keep their own configuration.

Run a self-hosted server

You need Docker with Compose. The stack runs ClickHouse, the Analytics Server, and a gateway that spreads requests across your servers, using the 0.18.0 release. For native installation, see the server installation guide.

Download the stack

mkdir -p chunkify-analytics
cd chunkify-analytics
base=https://raw.githubusercontent.com/chunkifydev/chunkify-analytics/v0.18.0/examples/clickhouse
for file in compose.yaml Caddyfile clickhouse.xml config.toml .env.example; do
  curl --fail --location "$base/$file" --output "$file"
done
cp .env.example .env
echo 'CHUNKIFY_IMAGE=ghcr.io/chunkifydev/chunkify-analytics:0.18.0' >> .env

Set CLICKHOUSE_PASSWORD in .env to a long random value.

Edit the existing [server] section in config.toml. Allow your website and https://chunkify.dev if you will use Chunkify previews or the playground:

[server]
allowed_origins = ["http://localhost:3000", "https://chunkify.dev"]

[retention]
seconds = 2592000

Use your production application's exact origin when deploying. Retention in this example is 30 days. Keep the rest of the downloaded configuration.

Initialize once

docker compose run --rm analytics init

init creates the database and returns the initial public_key and full-access secret_key once. Save them privately. ClickHouse stores only their hashes, so the keys cannot be recovered later.

Run init only for a new installation. It refuses to initialize the same database twice.

Start the server

docker compose up -d

Check health:

curl --fail http://127.0.0.1:4174/healthz
docker compose logs analytics

A healthy server returns {"status":"ok"}. The image includes its geolocation database; no local build is needed.

The clickhouse-data volume holds all events, analytics projects, and key hashes. Keep it when replacing containers. Analytics servers keep no data, so you can run more of them to handle more traffic:

docker compose up -d --scale analytics=3

The gateway accepts requests on your computer only. Before connecting from Chunkify or a deployed website, expose it through an HTTPS reverse proxy at a public address you control.

Set server.public_url to that external base URL so exported download links use an address reachable by your users.

Forward /v1/ requests and ingestion OPTIONS requests. If you expose MCP, forward /mcp and add your public hostname to [mcp].allowed_hosts. See Configuration.

Connect it to Chunkify

Create a read-only project key from the stack directory:

docker compose exec analytics \
  chunkify-analytics key create default secret "Chunkify dashboard" --read-only

Save the returned key. In your Project's Analytics > Settings, add a Self-hosted server with its public base URL and this read-only key. The base URL excludes /v1/events and /mcp.

Add the project's public key if you want Chunkify previews and generated player examples to send events. This is the public_key returned at initialization for the default analytics project.

Connect your application using the tracker example above, with your own server's /v1/events URL and public key. The analytics project selected by the public key must match the one selected by the dashboard's read-only key.

The Chunkify dashboard must be able to reach your server over public HTTPS. A loopback URL is useful for testing the tracker locally, but is not reachable from the hosted Chunkify app.

Check your first playback

Open Sessions for the selected server. You should see a playback attempt after playing the video. Watch time updates as snapshots or a final event arrive.

For missing events, inspect the browser request to /v1/events. Check the public key, full endpoint URL, allowed website origin, and selected dashboard server. Ingestion responses explains common errors.

You can also check recent events from your terminal. Save a read-only key as ANALYTICS_SECRET_KEY in your private environment, then query your server's URL:

curl --fail \
  -H "Authorization: Bearer $ANALYTICS_SECRET_KEY" \
  'https://analytics.example.com/v1/events?order=desc&limit=10'

The response contains an events array with the original events, their server receipt times, and their analytics project ID.