How to embed a private video on your website
An unlisted YouTube or Vimeo link is not private: anyone who gets the link can watch it, share it, or embed it elsewhere. If a video is meant only for paying students, customers or employees, it should play only on your site and only for viewers you have let in. This guide shows the pattern, using vewo's API as the example.
Why "unlisted" is not enough
Unlisted means "not in search results". The link itself is the key, and it never expires.
The pattern
- Store the video as private, so it has no public link.
- Lock embeds to your domains, so the player refuses to load elsewhere.
- When an entitled viewer opens the page, your backend asks for a short-lived view token.
- The page embeds the player with that token. When it expires, a copied link stops working.
With vewo, step by step
1. Create the video as private. You get its id and a URL to send the file to:
curl -X POST https://api.vewo.io/v1/videos \
-H "Authorization: Bearer $VEWO_KEY" \
-H "Content-Type: application/json" \
-d '{"title": "Lesson 4", "size_bytes": 734003200, "visibility": "private"}'
{
"video": { "id": "a41f09c2be17", "status": "UPLOADING", ... },
"upload": { "method": "PUT", "url": "https://...", "headers": { ... } },
"note": "PUT the file to upload.url, then ..."
}2. In the workspace, open Settings and list your site under allowed embed domains. The player then refuses to load on any other site.
3. When the video can play, your webhook endpoint receives video.ready:
POST https://your-app.example/hooks/vewo
webhook-id: msg_...
webhook-timestamp: 1791393004
webhook-signature: v1,...
{
"type": "video.ready",
"workspace_id": "ws_...",
"created_at": 1791393004,
"data": { "id": "a41f09c2be17", "status": "READY", "width": 1080, "height": 1920, ... }
}4. When an entitled viewer opens your page, your backend mints a view token:
curl -X POST https://api.vewo.io/v1/videos/a41f09c2be17/view-token \
-H "Authorization: Bearer $VEWO_KEY" \
-H "Content-Type: application/json" \
-d '{"expires_in": 3600}'
{
"video_id": "a41f09c2be17",
"token": "...",
"expires_at": 1791396604,
"embed_url": "https://vewo.io/embed/a41f09c2be17?vt=...",
"visibility": "private"
}5. Put embed_url in an iframe on the page:
<iframe src="{embed_url}" width="640" height="360"
allow="autoplay; fullscreen" allowfullscreen></iframe>The full reference is in the vewo API docs.
What this protects, and what it does not
It stops link sharing and embedding on other sites. It does not stop someone recording their screen; nothing on the web can, short of DRM, which vewo does not offer.
Captions and accessibility
Add AI captions to each private video in one click; every viewer can turn them on inside the embed.
Questions
How long should a view token last?
Long enough to watch the video. The API allows one minute to one day; one hour is a good default.
Does the viewer need a vewo account?
No.
Can I do this without writing code?
Partly: private videos and domain lock work from the dashboard; per-viewer tokens need a backend.
Start your free month of Business. No card needed.