Hakari

VOD library

Two ways a VOD lands in your library:

  1. Upload — user uploads an mp4/mov/mkv/webm, Hakari transcodes into an adaptive HLS/DASH ladder and serves it from the global edge.
  2. Live recording — a stream with recording enabled finalizes on stop; the resulting playlist is playable at the stream's vodPlaybackUrl.

This page covers the upload path. For live recording, see Live streams — Recording.

Upload flow

  client ──PUT presigned URL──▶ cloud storage
     │                           ▲
     ├──POST /vod──▶ Hakari ──── dispatches transcode
     │                           │
     └── polls GET /vod/:id for progress
                                 │
            transcode pipeline ──┘
                  │
                  └──▶ webhook → status: complete, playbackUrl ready

Status progression: pending_uploaduploadedqueuedprocessingcomplete (or failed / cancelled).

Creating a VOD via the dashboard

Dashboard → VOD Library → + Upload video:

  • Title
  • Source file — mp4/mov/mkv/webm. Upload is direct-to-storage via a presigned URL, so even multi-GB files don't hit our API.
  • Output formatHLS or MPEG-DASH. HLS for widest compatibility; DASH if you prefer MPD manifests.
  • Video codech264 (widest), h265 (better compression), vp9, av1 (best compression, slow). Plan-gated.
  • Aspect ratiopreserve (no padding), or a fixed 16:9, 9:16, 4:3, 1:1. Fixed ratios pad with black bars.
  • Rendition ladder — pick rungs (1080p, 720p, 480p, 360p). Each is a separate playable quality.
  • Bitrate per rung — override defaults if you want a higher-quality 720p or a cheaper 1080p.

Hit Upload & transcode. The upload manager runs in the browser — you can navigate away, it keeps going. Watch progress on the VOD detail page.

Playback

A completed VOD has playbackUrl set — paste it into any HLS/DASH player. The edge serves these with:

  • Long-lived per-object cache — once a segment is cached at an edge, subsequent viewers in the same region get it without a round-trip to storage.
  • Long Cache-Control: max-age=31536000, immutable on segments, short max-age=60 on .m3u8 manifests.
  • CORS * so browser players work out of the box.
  • HTTP/2 + TLS 1.3.

Thumbnail is auto-extracted from the source and served at …/vod/<id>/thumb.jpg.

Signed playback

Per-VOD toggle on the detail page. When on, the edge enforces ?policy=&signature= on every /vod/<id>/* request. See signed playback for the algorithm and client examples.

Programmatic upload

# 1. Create the VOD record + get a presigned PUT URL.
curl -X POST https://api.hakari.cloud/v1/projects/my-project/vod \
  -H "Authorization: Bearer hkr_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Launch recording",
    "filename": "launch.mp4",
    "outputFormat": "hls",
    "videoCodec": "h264",
    "ladder": [
      {"name":"720p","width":1280,"height":720,"videoBitrate":"3M"},
      {"name":"480p","width":854,"height":480,"videoBitrate":"1500k"}
    ]
  }'
# → { vod: {...}, upload: { url, method: "PUT", ... } }

# 2. PUT the file to the presigned URL.
curl -X PUT --data-binary @launch.mp4 "<upload.url>"

# 3. Mark upload complete → dispatches the transcode job.
curl -X POST https://api.hakari.cloud/v1/projects/my-project/vod/<vodId>/uploaded \
  -H "Authorization: Bearer hkr_xxx"

# 4. Poll until status === "complete"
curl https://api.hakari.cloud/v1/projects/my-project/vod/<vodId> \
  -H "Authorization: Bearer hkr_xxx"

For vod.complete notifications instead of polling, subscribe to the webhook.

Plan limits

Your plan gates:

  • Max source size (hard ceiling on each upload).
  • Concurrent transcode jobs per project (excess jobs queue).
  • Allowed video codecs (h265 / av1 often require higher tiers).
  • Allowed output formats.

Limits return as 403 from the create endpoint when exceeded.