Guide: Embed on any site (plain HTML, WordPress, any CMS)
Play a Videohati video on a plain HTML page, in WordPress, or in any CMS by pasting one script tag and a mount element.
You do not need a framework to show a Videohati video. There are two ways to embed, and which one you use depends on the video's visibility:
- Public or unlisted videos — paste an
<iframe>(or just share a link). No server code at all. Start with the next section. - Private videos — your server mints a short-lived session token per viewer, and the player mounts from a script tag. Your API key stays on the server the whole time. Start at Create a playback session.
Zero-code embed: public and unlisted videos
Every video starts private. Switch it to unlisted (anyone with the link
can watch, not indexed by search engines) or public from the video's
Share & embed card in the dashboard, or over the API:
curl -X PATCH https://api.videohati.com/v1/videos/01JZ9WV3N8GQ5T2M7K4C6XBARH \
-H "Authorization: Bearer $VIDEOHATI_API_KEY" \
-H "content-type: application/json" \
-d '{ "visibility": "unlisted" }'Once the video is unlisted or public, three zero-code options open up:
Share link. Send anyone the hosted watch page — a branded, right-to-left page with the player ready to play:
https://cdn.videohati.com/watch/01JZ9WV3N8GQ5T2M7K4C6XBARHIframe. Paste this where the video should appear (the wrapper keeps a 16:9 shape at any width):
<div style="position:relative;padding-top:56.25%;">
<iframe
src="https://cdn.videohati.com/embed/01JZ9WV3N8GQ5T2M7K4C6XBARH"
style="position:absolute;inset:0;width:100%;height:100%;border:0;"
allow="autoplay; fullscreen; encrypted-media; picture-in-picture"
allowfullscreen loading="lazy" title="Videohati"></iframe>
</div>Append ?lang=en to the /watch or /embed URL for an English player;
Arabic is the default. Append autoplay=1 to the /embed URL to start muted
on load.
oEmbed. Platforms that support oEmbed discovery (WordPress, Notion, and
most LMSes) unfurl the watch link into a player on paste — no markup needed.
The endpoint is https://cdn.videohati.com/oembed?url=<watch-url>.
Playback through all three still runs the full protection pipeline — signed media URLs, session heartbeats, and your project's geographic policy. The only thing that changed is who may open a session: anyone, for this one video.
For videos that must stay private — paid course content, internal material — keep reading: the token flow below leaves your server in control of every viewer.
1. Create a playback session on your server
A playback session is a short-lived permission to watch one video. You mint it with your API key, so this step must run on your server — never in the browser.
Your API key grants write access to the project. Never put a vh_live_ or
vh_test_ key in a web page, a theme file, or client-side JavaScript.
curl -X POST https://api.videohati.com/v1/playback/sessions \
-H "Authorization: Bearer $VIDEOHATI_API_KEY" \
-H "content-type: application/json" \
-d '{ "videoId": "01JZ9WV3N8GQ5T2M7K4C6XBARH", "viewerDisplayText": "Ahmed K." }'The response carries the sessionToken you pass to the page:
{
"sessionId": "01JZ9WV3N8GQ5T2M7K4C6XBARK",
"sessionToken": "01JZ9WV3N8GQ5T2M7K4C6XBARK.1781485200.bXktbWFj",
"manifestUrl": "https://cdn.videohati.com/…/master.m3u8",
"expiresAt": "2026-07-05T12:00:00Z"
}import { Videohati } from "@videohati/node";
const client = new Videohati({ apiKey: process.env.VIDEOHATI_API_KEY });
const session = await client.playback.createSession({
videoId: "01JZ9WV3N8GQ5T2M7K4C6XBARH",
viewerDisplayText: "Ahmed K.", // shown in the watermark
});
// Send session.sessionToken to the page. Keep the API key on the server.
console.log(session.sessionToken);2. Paste the embed on your page
Add the mount element and the script tag where the video should appear. The
script scans the page for data-videohati-video-id and mounts a player on each
match.
<div
data-videohati-video-id="01JZ9WV3N8GQ5T2M7K4C6XBARH"
data-videohati-project-id="01JZ9WV3N8GQ5T2M7K4C6XBARP"
data-videohati-session-token="{{ session token from your server }}"
data-videohati-lang="ar"
></div>
<script src="https://cdn.videohati.com/player.js" async></script>Replace the placeholder in data-videohati-session-token with the token your
server just created. The player refuses to start without one and shows a
"Missing session token" message instead.
The data attributes
Set these on the mount element. Only the first three are required.
| Attribute | Required | Values | What it does |
|---|---|---|---|
data-videohati-video-id | Yes | 01JZ9WV3N8GQ5T2M7K4C6XBARH | The video to play. |
data-videohati-project-id | Yes | 01JZ9WV3N8GQ5T2M7K4C6XBARP | The project the video belongs to. |
data-videohati-session-token | Yes | token string | The short-lived token from your server. |
data-videohati-autoplay | No | "true" | "muted" | Start on load. Most browsers only allow autoplay when muted. |
data-videohati-width | No | number | Player width in pixels. |
data-videohati-height | No | number | Player height in pixels. |
data-videohati-lang | No | "ar" | "en" | Player interface language. Defaults to ar. |
data-videohati-viewer-text | No | any text | Text shown in the on-video watermark. |
data-videohati-api-origin | No | URL | Point the player at a non-production API, such as staging. |
WordPress and other CMSs
In WordPress, add a Custom HTML block to your post or page, then paste the mount element and the script tag from step 2. Any CMS that accepts raw HTML works the same way.
The one part a CMS cannot do for you is mint the session token — that needs your
API key, which must stay on a server. Add a small endpoint on your site that
calls playback.createSession and returns the token, then have your page fetch
it before mounting the player. To create sessions automatically as videos
become ready, see the webhooks guide.
Content Security Policy
If your site sends a Content Security Policy header, allow the two Videohati origins so the script can load and reach the API:
script-src https://cdn.videohati.com;
connect-src https://api.videohati.com https://cdn.videohati.com;
media-src blob:;Guide: Integrate Videohati into a Laravel 11 project
Install the videohati/laravel package, configure your key, upload a video, create a playback session, and embed the player in a Blade view.
Guide: Receive events with webhooks
Register a webhook endpoint, verify the signature, and react to Videohati events like a video becoming ready.