Use Cases


Inserting Custom Headers

September 8, 2020 - Doug

api.video offers a number of simple APIs to create and share video. To protect videos from being shared, we offer the concept of private videos - where the public token for the video is set to false.

These private videos have a URL token that can be used just once, and cannot be shared. To authenticate the token, we insert a custom header that must also be validated with the URL token.

If you use the api.video player - there is no development required - we do all the lifting of adding the authentication header for you.

If you are using a different player, you need to recieve this header from cdn.api.video and insert this header on each subsequent request. To learn how, read on!

Retrieving the header

For each unique view of a private video, you must generate a unique URL token. It will look something like this:

Using Chrome devTools, we can see what happens when we request this url:

The 4th request is to cdn.api.video for the player.json. The first request to this domain for a private video (either for the .mp4, the player.json, or the manifest.m3u8) will have a custom header in the response (X-Token-Session).

This header and value must be sent on every subsequent request to cdn.api.video to ensure playback.

If you use the api.video player, each subsequent request has this header added automatically. For example, here is the request for the video thumbnail.jpg (in Safari, with a different session token):

At the bottom of the header list is the X-Token-Session.

Using a different player

With a different video player, the code to insert this custom header must be added. So lets walk through the steps to add a new request header in your code.

Getting the session header

To retrieve the session header, simply request the first file from api.video (typically this is the m3u8 manifest file). It will look something like:


If you request this file from your player (or you can test just by loading this url in Safari), you'll receive the response with a lot of headers:

Timing-Allow-Origin: *
Cache-Control: no-store, no-store
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Content-Length: 590
Via: 1.1 PSfgblPAR2xf192:2 (W), 1.1 PSygldLON4zd14:8 (W), 1.1 PSygldLON2ew56:2 (W)
X-XSS-Protection: 1; mode=block, 1; mode=block
Date: Fri, 23 Oct 2020 10:02:57 GMT
Access-Control-Expose-Headers: Content-Type, Content-Length, Content-Range, X-Token-Session, Vary, Origin
Access-Control-Allow-Credentials: true
Content-Type: application/vnd.apple.mpegurl
ETag: "5e8f75e8-24e"
X-Content-Type-Options: nosniff, nosniff
Last-Modified: Thu, 09 Apr 2020 19:22:16 GMT
x-proxy-cache: HIT
Server: PWS/
x-ws-request-id: 5f92aa50_PSygldLON2ew56_14724-24181
x-token-session: 284a505f-d556-4de5-9498-c68260927551
x-px: ms PSygldLON2ew56LHR,ms PSygldLON4zd14LHR,ms PSfgblPAR2xf192CDG(origin)

Now we have the x-token-session for the playback of the video, and we must include this in each subsequent request.

Minimal working example

The following piece of code shows how to retrieve the source file of a private video from a token value (error handling has been omitted for readability reasons).

const token = "..."; // token value retrieved by your backend
const configUrl = "https://cdn-staging.api.video/vod/.../token/" + token + "/player.json";

fetch(configUrl, { credentials: "include" })
    .then(response => 
    .then(([xTokenSession, videoConfig]) => {
        const srcUrl = videoConfig.video.src.replace(":token", token);

        fetch(srcUrl, {
            headers: {
                "X-Token-Session": xTokenSession
        .then(response => response.text())
        .then(videoSrcContent => console.log(videoSrcContent));

Adding the token to your header

Depending on the type of resource to retrieve, adding the X-Token-Session header may not be as straightforward as in the example above.

Below are some tips that you might find useful.

Using MediaSource capabilities

If you manage the video tag yourself, you can use the MediaSource interface to add headers to video files related requests.

Using URL.createObjectURL() method

URL.createObjectURL might be useful for some kinds of assets. For instance, you could display a video poster using an img tag with the following code:

fetch(posterUrl, { headers: { "X-Token-Session": xTokenSession }})
  .then(response => response.blob())
  .then(blob => { myImgElement.src = URL.createObjectURL(blob) });

Using a service worker

Service workers can be used to intercept and modify any request made by your application and thus it gives you the ability to add headers.

Using video.js based players

If your player is based on video.js player framework, you can redefine the beforeRequest method on the xhr object of videojs.Hls . This will give you the ability to add the header on any video request.

videojs.Hls.xhr.beforeRequest = (options) => {
    options.headers = {
        "X-Token-Session": xTokenSession
    return options;


Developer Evangelist

Get started now

Connect your users with videos