No SDK required: the playback flow is two plain HTTP calls. This guide uses
curl and a Python server example, but the shape is the same in any language.
Read How playback works first for
the security model — the summary is step 1 needs your secret key (server
only); step 2 uses the token and is browser-safe.
Step 1 — mint a player token (server, needs the API key)
curl -H "Authorization: Bearer $VIDEAS_API_KEY" \
https://api.videas.com/api/external/v1/videos/vid_123/player/
The response includes the player metadata and, crucially, a playback_token
(valid 4h):
{
"uid": "…",
"playback_token": "eyJhbGciOi…",
"player_config": { "auto_play": false, "theme": "dark" },
"items": [{ "asset": { "uid": "vid_123", "thumbnail_url": "https://api.videas.com/assets/vid_123/thumbnail-ab12cd34.jpg" } }]
}
URL fields like
thumbnail_urlcome back as absolute URLs — ready to use, no host to prefix.
Step 2 — resolve signed stream URLs (token only, no API key)
curl -X POST https://api.videas.com/api/external/v1/playback/info/ \
-H "Content-Type: application/json" \
-d '{"asset_id":"vid_123","playback_token":"eyJhbGciOi…"}'
{
"type": "video",
"blocked": false,
"hls_url": { "url": "https://…/stream.m3u8?token=…", "expires_at": "2026-07-15T12:00:00Z" },
"source_url": { "url": "https://…/video.mp4?token=…", "expires_at": "…" },
"preview_sprites_url": { "url": "https://…", "expires_at": "…" },
"chapters": [{ "title": "Intro", "start_time": 0 }],
"resume_position_seconds": null
}
Notice there’s no Authorization header on step 2 — it’s authenticated by
the token, which is why you can safely run it from the browser.
Putting it together (Python server)
A common pattern: your backend mints the token, your page resolves + plays it. With the Python SDK the server side is one call:
import os
from videas_sdk import VideasClient
client = VideasClient(api_key=os.environ["VIDEAS_API_KEY"])
def player_context(uid: str) -> dict:
player = client.videos.get_player(uid)
# Pass ONLY browser-safe data to your template / JSON endpoint.
return {
"asset_id": uid,
"playback_token": player["playback_token"], # safe to expose; valid 4h
"poster": player["items"][0]["asset"].get("thumbnail_url"),
}
Prefer plain stdlib? The same two calls with urllib:
import json, urllib.request
def mint_token(uid, api_key):
req = urllib.request.Request(
f"https://api.videas.com/api/external/v1/videos/{uid}/player/",
headers={"Authorization": f"Bearer {api_key}"},
)
with urllib.request.urlopen(req) as r:
return json.load(r)["playback_token"]
Then hand playback_token + asset_id to the browser and resolve there.
Playing it in the browser
Once the browser has asset_id and playback_token, the resolve-and-play code
is identical to the SDK guide — the only difference is where the token came
from. See
Web player with the JavaScript SDK → Step 2
for the full hls.js + native-HLS snippet. In short:
const info = await (await fetch('https://api.videas.com/api/external/v1/playback/info/', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ asset_id, playback_token }),
})).json()
// if (!info.blocked) → feed info.hls_url.url into hls.js / a native <video>
Other asset types
playback/info/ is polymorphic — branch on type:
video→ playhls_url(fallbacksource_url).audio→ playsource; rendersubtitle_tracksandwaveform_url.image→ pick avariants[]entry by size.document→ link/previewurland per-pagethumbnails.third_party→ embed the provider iframe viaembed_url(don’t use an HLS player).
Next steps
- How playback works
- Web player with the JavaScript SDK
- Using the REST API
GET /videos/{uid}/player/andPOST /playback/info/in the API reference