Embedding video in your B2B SaaS product comes down to three engineering decisions: which embed pattern fits your stack, how you keep one customer's videos invisible to another customer, and where the player lives in your product UI.
Get the first decision wrong and your page bundle carries a player you do not need. Get the second wrong and you ship a multi-tenant data leak. Get the third wrong and your customers see video that looks bolted onto your product instead of part of it.
TL;DR
- Three embed patterns to choose from: iframe (no JS on your side), Web Player custom HTML element (one script tag, deeper page integration), or direct HLS stream URL (bring your own player). Pick by how much page integration you need.
- Tenant isolation pattern: signed JWT playback URLs scoped to specific media assets. Your backend issues a token only when the requesting user is allowed access; a leaked URL is useless outside that scope.
- Implementation flow: upload to your video host, get the Playback ID, embed via the pattern you picked. Wire signed URLs when you ship multi-tenant.
- Where this fits in your product: customer portals (Rocketlane-style), internal team dashboards, sales enablement libraries, native mobile apps. The same playback pattern works across all of them.
Three ways to embed video in your B2B SaaS product
Pick based on how much page integration you need. The first two use the FastPix-hosted player and inherit its themable UI, captions, analytics, accessibility, and frame-accurate seeking out of the box. The third gives you the stream URL and gets out of the way.
Option 1: iframe embed (copy from the dashboard, paste into your page)
The fastest path. In the FastPix dashboard, go to Video > Media, click the uploaded video you want to embed to open its Media Details page, then click Integrate in the left navigation to open the Embed video panel. Copy the iframe code from there and paste it into your page.

1<iframe
2 src="https://play.fastpix.com/?playbackId=YOUR_PLAYBACK_ID&autoplay=true&muted=true"
3 width="640"
4 height="360"
5 frameborder="0"
6 allow="autoplay; fullscreen"
7 allowfullscreen>
8</iframe>The dashboard's Integrate panel also exposes the direct .m3u8 streaming URL and the raw Playback ID. URL parameters let you control behavior without writing JS: autoplay=true, muted=true, loop=true, hide-controls=true, aspect-ratio=16/9, and enableVideoClick=true.
To make the iframe responsive across screen sizes, wrap it in a padding-top container:
1<div style="position: relative; padding-top: 56.25%;">
2 <iframe
3 src="https://play.fastpix.com/?playbackId=YOUR_PLAYBACK_ID"
4 style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
5 frameborder="0"
6 allow="autoplay; fullscreen"
7 allowfullscreen>
8 </iframe>
9</div>When to use it: marketing pages, knowledge bases, support docs, customer-facing portals that need a video without any JavaScript wiring, prototypes, and anywhere a copy-paste embed beats writing player code.
Trade-offs: the iframe runs in its own sandbox, so cross-frame events (programmatic play/pause from your page, custom UI controls outside the player chrome, fine-grained analytics events) need messaging across the frame boundary. If you need that integration depth, Option 2 is the better fit.
Option 2: FastPix Web Player (custom HTML element)
The same FastPix-hosted player, but rendered as a custom HTML element on your page instead of inside an iframe. One script tag, one custom element. The player still handles HLS playback, ABR rendition switching, themable UI, captions, fullscreen, analytics integration via Video Data, accessibility, and frame-accurate seeking.
1<script src="https://cdn.jsdelivr.net/npm/@fastpix/fp-player@latest/dist/player.js"></script>
2
3<fastpix-player
4 playback-id="YOUR_PLAYBACK_ID"
5 stream-type="on-demand">
6</fastpix-player>When to use it: B2B SaaS web apps where you need full customization and developer control over the player (your code listens to play/pause events, tracks custom analytics, swaps the playback ID dynamically as the user navigates between videos in your portal, or restyles the player chrome to match your product). Works in React, Vue, Svelte, Next.js, plain HTML: anywhere a custom element renders.
Trade-offs: the script tag adds one dependency to your page bundle. For the simplest possible embed, Option 1 has zero JS on your side.
Option 3: Direct HLS stream URL (bring your own player)
Skip the FastPix-hosted player and feed the HLS stream URL into your own player library. The stream comes from https://stream.fastpix.com/{playbackId}.m3u8 and works with any HLS-compatible player.
1<video controls></video>
2
3<script>
4 import Hls from 'hls.js';
5
6 const video = document.querySelector('video');
7 const playbackId = 'YOUR_PLAYBACK_ID';
8 const hlsUrl = `https://stream.fastpix.com/${playbackId}.m3u8`;
9
10 if (Hls.isSupported()) {
11 const hls = new Hls();
12 hls.loadSource(hlsUrl);
13 hls.attachMedia(video);
14 } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
15 video.src = hlsUrl;
16 }
17</script>When to use it: your stack already has HLS.js, Video.js, Shaka Player, AVPlayer, or ExoPlayer in production and you want consistency with that player across your app. Also fits if you want vendor-neutral abstraction so the playback URL is the only thing tied to FastPix.
Trade-offs: you own the player. Browser compatibility, ABR tuning, captions wiring, accessibility settings, and analytics instrumentation become your code. Pick this only when the consistency argument is worth that ownership.
Signed playback URLs: keeping Customer A's videos away from Customer B
Public Playback IDs and HLS URLs are accessible to anyone who has the URL. For a multi-tenant B2B SaaS where Customer A's videos must stay invisible to Customer B, you need signed JWT playback URLs.
Step 1: Make the video private and create a signing key
- In the FastPix dashboard, set the video's access policy to private when you upload (or convert an existing public asset). The API field is
accessPolicy: "private". - Go to the Signing Keys section of the FastPix dashboard and create a new signing key, or call the signing keys API.
- FastPix returns a key pair: a private key (base64-encoded) and a signing key ID. Store the private key in your backend's secrets manager. Never expose it to the client.
Step 2: Generate the JWT from your backend on each playback request
Your backend generates a signed JWT scoped to the specific media the requesting user is allowed to view. The token carries kid (signing key ID), aud (the audience, formatted as media:{MEDIA_ID}), and exp (expiration time). Issued at (iat) and issuer (iss) are optional but recommended.
1// Node.js: Express route handler
2const jwt = require('jsonwebtoken');
3
4app.get('/api/video-token/:mediaId', (req, res) => {
5 const { mediaId } = req.params;
6 const user = req.user;
7
8 // Your backend's authorization check: is this user
9 // allowed to play this media?
10 if (!userCanAccessMedia(user, mediaId)) {
11 return res.status(403).send('Forbidden');
12 }
13
14 const token = jwt.sign(
15 {
16 kid: process.env.FASTPIX_SIGNING_KEY_ID,
17 aud: `media:${mediaId}`,
18 iss: 'yourcompany.com',
19 iat: Math.floor(Date.now() / 1000),
20 exp: Math.floor(Date.now() / 1000) + 3600 // 1 hour
21 },
22 process.env.FASTPIX_SIGNING_KEY_PRIVATE,
23 { algorithm: 'HS256' }
24 );
25
26 res.json({ token });
27});The authorization check (userCanAccessMedia) is where your tenant isolation lives. Your database knows which media belongs to which customer, and your backend only issues a token for media the requesting user owns.
Step 3: Pass the signed URL to the player on the client
The client requests a token from your backend, then constructs the playback URL with the token query parameter.
1// React example with the FastPix Web Player
2function VideoEmbed({ mediaId }) {
3 const [token, setToken] = useState(null);
4
5 useEffect(() => {
6 fetch(`/api/video-token/${mediaId}`)
7 .then(r => r.json())
8 .then(({ token }) => setToken(token));
9 }, [mediaId]);
10
11 if (!token) return <div>Loading…</div>;
12
13 const playbackUrl = `https://stream.fastpix.com/${mediaId}.m3u8?token=${token}`;
14
15 return (
16 <fastpix-player
17 stream-type="on-demand"
18 playback-url={playbackUrl}>
19 </fastpix-player>
20 );
21}For testing JWTs during development without writing the backend code yet, FastPix provides a hosted JWT signer at jwt.fastpix.co. Use it to generate test tokens, validate the structure, and confirm playback works before wiring up your server-side flow. Do not use the hosted signer for production: sign tokens on your own backend.
Why this pattern matters
A B2B SaaS database knows which user belongs to which tenant. Your backend translates that knowledge into JWT claims at playback request time. FastPix validates the JWT against the media's signing key and only serves the stream if the token is valid and matches the requested media. A leaked playback URL is useless to anyone outside the token's scope, and tokens expire on the schedule you set (one hour is typical for in-app playback; shorter for high-stakes content).
This is how Rocketlane keeps onboarding kickoff recordings visible to the specific customer they belong to and invisible to every other customer on their platform. See the full Rocketlane case study for the workflow.
Surfacing the embedded video in your product UI
The embed pattern is the same; what changes is where the player lives. Three common placements for B2B SaaS:
Customer-facing portal (Rocketlane-style)
The customer logs into your product and sees their projects, tasks, and onboarding materials. Recorded kickoff calls, training videos, and demo recordings live inside their portal view. Render the FastPix Web Player inside a card on the project page, scoped by the project's customer ID via signed playback URLs.
Rocketlane built this exact pattern with FastPix: see the case study.
Internal team dashboards
CS managers reviewing customer health, sales reps watching demo call recordings, professional services teams running implementation status reviews. Same embed pattern, but the authorization check is "is this user on the internal team?" rather than "does this user belong to this tenant?"
Mobile apps
For React Native, use a WebView with the FastPix Web Player embed, or pull the HLS stream URL into a native player. For native iOS and Android, the FastPix iOS Player SDK wraps AVPlayer and the Android Player SDK wraps ExoPlayer, with the same Playback ID model. Signed playback URLs work identically across web and native.
Get started: from FastPix signup to embedded video in 30 minutes
The end-to-end flow:
- Sign up at fastpix.io. Free tier covers the first 100,000 streaming views per month. No credit card required to start.
- Upload your first video from the dashboard at Media > Create first media. Pick Pull Video to import from a URL, or Push Video to upload from your device. FastPix processes the video automatically.
- Copy the Playback ID from the Media Details page when the status reads Ready.

- Embed in your product using the Web Player snippet from Option 1 above, with the Playback ID dropped in. Validate that playback works.
- For private content, create a signing key from the dashboard's Signing Keys section, then generate JWTs from your backend on each playback request (Step 2 above). Switch the embed to use the signed URL pattern.
- Once live, add the FastPix Video Data SDK to track playback analytics across your customers. Free for the first 100,000 streaming views per month.
Total time for the public-video happy path: roughly 30 minutes. Add a couple of hours for the signed URL backend integration when you are ready to ship tenant isolation.
FAQ
What is the difference between the FastPix Web Player and using the direct HLS URL?
The FastPix Web Player is a drop-in custom HTML element that handles the player UI, HLS parsing, ABR, captions, and controls for you. The direct HLS URL pattern gives you the stream URL and lets you bring your own HLS-compatible player (HLS.js, Video.js, Shaka, AVPlayer, ExoPlayer). Use the Web Player when you want the fastest path and the default UI works for you. Use the direct HLS URL when you already have a player in your stack or need deep UI control.
How do I keep Customer A's videos hidden from Customer B?
Use signed JWT playback URLs. Set the video's access policy to private at upload. Create a signing key in the FastPix dashboard. From your backend, generate a JWT scoped to the specific media ID (aud: media:{MEDIA_ID}) only when your application's authorization layer confirms the requesting user owns or has access to that media. FastPix validates the JWT before streaming. A leaked URL cannot be used outside its scope.
Can I embed FastPix video in a React, Vue, Next.js, or WordPress app?
Yes. The FastPix Web Player is a custom HTML element that renders in any framework that handles standard DOM elements. For React and Vue, you may want a thin wrapper component to manage the element's attributes via state. For WordPress, FastPix has an official integration plugin. The direct HLS URL pattern works in any environment where you can attach a video element and use HLS.js.
What about mobile apps?
For native iOS, the FastPix iOS Player SDK wraps AVPlayer and accepts the same Playback ID. For Android, the FastPix Android Player SDK wraps ExoPlayer. For React Native or Flutter, you can either embed a WebView with the FastPix Web Player or use the HLS stream URL with a native player. Signed playback URLs work identically across web and native.
How long should JWT playback tokens live?
One hour is a common default for in-app playback. Shorter for high-stakes or short-form content (15 minutes works for a 10-minute video). Longer when the user explicitly downloads a video for offline-style playback inside your app. The expiration time is set in your backend via the exp claim; the same media can have different expiration windows for different request contexts.
Can I see analytics for who watched which video?
Yes. The FastPix Video Data SDK drops into the player and emits playback events with custom dimensions you can use to tag sessions by customer ID, user ID, or any other attribute that matters to your product. Per-customer analytics is the topic of the next article in this series.
How is this different from using Vimeo, Loom, or YouTube for video in our SaaS product?
Vimeo, Loom, and YouTube are end-user-facing video hosts. They are not built around the API-first, JWT-secured, multi-tenant playback patterns a B2B SaaS product needs. FastPix is the video infrastructure layer: your product owns the customer relationship, the player UI, and the data; FastPix owns ingest, transcode, delivery, and the playback security primitives. See the full FastPix video infrastructure for SaaS products.



