To play a Videas asset in your own page you don’t stream from a fixed URL. Instead you go through a short two-step flow that keeps your API key secret and hands the browser only short-lived, signed URLs. This page explains the model; the next two show the actual code (JavaScript SDK and REST API).
You may not need any of this. If all you want is the video on a page, every Videas media gives you an embed code — a script tag or an iframe — to paste as-is, player, chapters and subtitles included. This guide is for the case where you drive playback yourself: your own player, a mobile app, a server-rendered page.
The two steps
- Mint a player token — call
GET /videos/{uid}/player/(or/assets/{uid}/player/). This returns the player metadata (config, theme, overlays, items) and aplayback_tokenvalid for 4 hours. - Resolve the stream URLs — call
POST /playback/info/with theplayback_tokenand theasset_id. This returns the signed, time-limited media URLs (hls_url, …) you feed into a video player.
The split exists so the token — safe to expose to a browser — is separated from your secret key, and so the actual media URLs are signed and expire quickly.
The security model (read this first)
The two endpoints authenticate differently, and this is the single most important thing to get right:
| Step | Endpoint | Auth | Where to call it |
|---|---|---|---|
| 1. Mint token | GET …/player/ |
API key (Authorization: Bearer sk_…) |
Server only |
| 2. Resolve URLs | POST …/playback/info/ |
playback_token (no API key) |
Browser is fine |
Golden rule. Your
sk_key is a secret — never ship it to a browser or a mobile app. Step 1 must run on your server. Theplayback_tokenit returns is designed to be handed to the browser, which does step 2 by itself.
Recommended architecture
┌─────────────┐ 1. getPlayer(uid) [sk_ key] ┌──────────────┐
│ Your server │ ──────────────────────────────────▶│ Videas API │
│ (sk_ key) │◀────────────────────────────────── │ │
└─────────────┘ playback_token (valid 4h) └──────────────┘
│
│ 2. hand playback_token + asset_id to the page
▼
┌─────────────┐ 3. POST /playback/info/ [token] ┌──────────────┐
│ Browser │ ──────────────────────────────────▶│ Videas API │
│ (player) │◀────────────────────────────────── │ │
└─────────────┘ signed hls_url (short-lived) └──────────────┘
│
│ 4. feed hls_url into hls.js / native HLS
▼
▶ playback
Your server mints one token and can reuse it for 4 hours; the browser re-resolves the signed URLs whenever they expire (they live much less than the token). When the token itself expires, mint a new one server-side.
What playback/info/ returns
The response is typed by the asset — the type field tells you which shape you
got. Every media URL is a { url, expires_at } object.
Video (type: "video")
| Field | Meaning |
|---|---|
hls_url |
HLS manifest (.m3u8) — the primary stream (adaptive bitrate, subtitles & audio tracks baked in) |
source_url |
Progressive MP4 — a legacy fallback when HLS is unavailable |
preview_sprites_url |
Sprite sheet for seek-bar thumbnails |
chapters |
[{ title, start_time, thumbnail_url }] |
Audio (type: "audio"): source, waveform_url, chapters,
subtitle_tracks ([{ label, language, is_default, src }]).
Image (type: "image"): variants ([{ name, dimensions, url }]).
Document (type: "document"): url, thumbnails (per-page).
Third-party (type: "third_party", e.g. YouTube/Vimeo): embed_url,
provider, provider_id — embed the provider’s iframe rather than an HLS
player.
Fields present on every type
expires_at— when this playback info (and its signed URLs) expire; re-resolve after this.resume_position_seconds— the viewer’s saved position, if any. Seek here to resume where they left off (nullwhen there’s nothing to resume).blocked— see below.
Handle the blocked state
When the asset owner’s credit wallet is empty, playback is withheld: the
response comes back with blocked: true and no media URL. Always check it
before wiring the player, and show a neutral “temporarily unavailable” message
rather than a broken player:
{ "type": "video", "blocked": true, "hls_url": null, "expires_at": "…" }
Token & URL lifetimes — a quick recap
playback_token→ valid 4 hours. Mint it server-side; reuse it.- Signed media URLs (
hls_url, …) → short-lived (see eachexpires_at). Re-callPOST /playback/info/to refresh them — no new token needed until the 4-hour token itself expires.