Skip to content

Quickstart

This guide registers a work, stores its encrypted segments, and plays it back. It uses Laravel or Python as the backend and the PHP upload helper as storage. The browser SDK performs encryption and playback, so the flow is identical for other backends.

Prerequisites

  • A Rightra account and an API key in the form rk_live_....
  • An MP4 file to protect.
  • A host that can run rightra-upload.php, or another storage target that accepts the encrypted segments.
  • A backend that can mint upload tokens.

1. Install the browser SDK

npm install @oliviuus/rightra-sdk

Without a bundler, load the UMD build with a version-pinned script tag:

<script src="https://unpkg.com/@oliviuus/rightra-sdk@0.1.3/dist/rightra.umd.js"></script>

2. Deploy the upload helper

Copy rightra-upload.php to your host and set RIGHTRA_UPLOAD_SECRET to a long random value. See Upload helper for setup.

3. Configure your backend

composer require oliviuus/rightra-laravel
php artisan vendor:publish --tag=rightra-config
# .env
RIGHTRA_API_KEY=rk_live_your_key
RIGHTRA_SDK_URL=https://unpkg.com/@oliviuus/rightra-sdk@0.1.3/dist/rightra.umd.js
RIGHTRA_UPLOAD_SECRET=<same value as in rightra-upload.php>
RIGHTRA_UPLOAD_TOKEN_TTL=900
pip install rightra
RIGHTRA_API_KEY=rk_live_your_key
RIGHTRA_UPLOAD_SECRET=<same value as in rightra-upload.php>
RIGHTRA_UPLOAD_TOKEN_TTL=900

Variable reference: Laravel, Python.

4. Add a token endpoint

The browser never receives RIGHTRA_UPLOAD_SECRET. Your backend mints a short-lived token for each upload. See Upload tokens for the format.

use Illuminate\Http\Request;
use Oliviuus\Rightra\Support\UploadToken;

Route::post('/rightra/token', function (Request $request) {
    $request->validate(['content_id' => 'required|string']);

    return ['token' => UploadToken::mint($request->input('content_id'))];
})->middleware('auth');
import os
import rightra

def rightra_token(content_id):
    return rightra.mint_upload_token(
        content_id,
        secret=os.environ["RIGHTRA_UPLOAD_SECRET"],
    )

5. Register the work

registerWork encrypts the file in the browser and calls uploadSegments once per segment. Return the public URL of each stored segment.

import { Rightra } from "@oliviuus/rightra-sdk";

const rightra = Rightra.init({ apiKey: "rk_live_your_key" });

await rightra.registerWork({
  file,
  title: "My Film",
  type: "film",
  uploadSegments: async ({ contentId, index, segment, iv }) => {
    const { token } = await fetch("/rightra/token", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ content_id: contentId }),
    }).then((r) => r.json());

    const form = new FormData();
    form.append("segment", new Blob([segment]));
    form.append("index", index);
    form.append("iv", iv);

    const res = await fetch(
      `https://your-site.example/rightra/rightra-upload.php?content=${contentId}&file=seg-${index}.enc`,
      { method: "POST", headers: { "X-Rightra-Token": token }, body: form }
    ).then((r) => r.json());

    return { url: res.url };
  },
});

When the upload completes, the SDK registers the manifest URL with Rightra and returns the content ID. Persist it. You need it for playback.

6. Play the work

<div id="player" style="width:100%;aspect-ratio:16/9;background:#000"></div>

<script src="https://unpkg.com/@oliviuus/rightra-sdk@0.1.3/dist/rightra.umd.js"></script>
<script>
  const rightra = Rightra.init({ apiKey: "rk_live_your_key" });

  rightra
    .createPlayer(document.getElementById("player"), {
      contentId: "RTR-853D-52D0",
      manifestUrl: "https://your-site.example/rightra/rightra-storage/RTR-853D-52D0/manifest.json",
      viewer: { id: "user-123", label: "Jane" },
      territory: "RW",
    })
    .then((player) => player.play());
</script>

viewer.id is required. Use any stable identifier from your own user system.

7. Verify

Open the content item in the Rightra console. The Playback tab lists each session with its viewer, timestamp, and watermark code. To confirm detection end to end, follow Testing watermarks.

Troubleshooting

Symptom Cause Resolution
VIEWER_REQUIRED on playback viewer.id was not provided. Pass viewer.id to createPlayer.
CONTENT_NOT_FOUND on playback The content ID does not belong to the API key, or a test key is being used with live content. Use the key that registered the content.
Player stays black with a network error The manifest URL is incorrect or unreachable from the browser. Open the manifest URL directly in the browser.
Upload fails with 401 The upload token expired. The default lifetime is 900 seconds. Mint a new token.
Upload fails with 403 The secret in the upload helper does not match the backend secret. Set both to the same value.

Full error list: API reference.