This guide explains how to embed Fermion live sessions into external websites using the Fermion SDK or manual iframe embedding.
Prerequisites
- A Fermion live session ID
- Fermion API key
- Access to your website’s codebase
Step 1: Obtain the Live Session ID
Each live session has a unique identifier. For example 6779080e80ec97e953a17971
. You will be able to create a Live session from your dashboard.
First, create a new live event.
If you cannot see Live events
tab in your dashboard, go to Manage features
tab at the top and enable live events.

After that, go to Manage sessions
to create a new session inside a live event:

A single live event can contain multiple live sessions.
Step 2: Install the SDK
npm install @fermion-app/sdk
# or
yarn add @fermion-app/sdk
# or
pnpm add @fermion-app/sdk
Step 3: Generate an Embed Token
You’ll need to generate a JWT (JSON Web Token) to authenticate the embed. Here’s how to create one using the jsonwebtoken
package:
import jwt from 'jsonwebtoken'
const payloadObject = {
liveEventSessionId: 'your-live-session-id',
userId: 'unique-user-id',
playbackOptions: {
// If you pass this as true, system would enforce only 1080p and 720p modes of playback. Note: Passing this as true might result in buffering on user side if their internet is not fast (as this disables low quality playback versions)
shouldPreferOnlyHighDefinitionPlayback: false,
// If you pass this as true, it will hide the seek controls (seekbar and jump forward/backward buttons) from the UI
shouldHideSeekControls: false,
// If you pass this as true, once the livestream ends, the same JWT that is used to embed the stream would not be able to playback the recorded version of the video
shouldDisallowRecordedPlaybackIfNotLive: false,
},
}
const jwtToken = jwt.sign(payloadObject, 'FERMION_API_KEY', {
expiresIn: '1h',
})
The payloadObject
must conform to the following zod schema:
z.object({
liveEventSessionId: z.string(),
userId: z.string(),
playbackOptions: z
.object({
shouldPreferOnlyHighDefinitionPlayback: z.boolean().default(false),
shouldHideSeekControls: z.boolean().default(false),
shouldDisallowRecordedPlaybackIfNotLive: z.boolean().default(false),
})
.default({
shouldDisallowRecordedPlaybackIfNotLive: false,
shouldPreferOnlyHighDefinitionPlayback: false,
shouldHideSeekControls: false,
}),
})
Important notes: - Replace FERMION_API_KEY
with your actual API key -
Provide a unique user ID for each viewer - playbackOptions
is optional. If
you do not pass this object we will use the defaults as mentioned above.
Fermion uses the same zod schema as above internally to validate your JWT
payload.
Step 4: Embed the Live Session
For Instructors (WebRTC Meeting Mode)
If you are an instructor who needs to use WebRTC (meeting mode), you
must use the iframe embedding method. The M3U8 playback option is only
available for student viewers and does not support WebRTC functionality.
import { FermionLivestreamVideo } from '@fermion-app/sdk/livestream-video'
// Create a livestream instance
const livestream = new FermionLivestreamVideo({
liveEventSessionId: 'your-live-session-id',
websiteHostname: 'your-domain.fermion.app',
})
// Embed the live session (requires JWT token)
const embed = livestream.getPrivateEmbedPlaybackIframeCode({
jwtToken: 'your-jwt-token',
})
console.log(embed.iframeHtml)
For Students (View-Only Mode)
Students can use either the iframe embedding method or the custom M3U8 playback option:
import { FermionLivestreamVideo } from '@fermion-app/sdk/livestream-video'
// Create a livestream instance
const livestream = new FermionLivestreamVideo({
liveEventSessionId: 'your-live-session-id',
websiteHostname: 'your-domain.fermion.app',
})
// Option 1: Iframe embedding (recommended for most cases)
const embed = livestream.getPrivateEmbedPlaybackIframeCode({
jwtToken: 'your-jwt-token',
})
console.log(embed.iframeHtml)
// Option 2: Custom M3U8 playback (advanced use case)
const hlsConfig = livestream.getHlsPlaybackConfig({
origin: 'https://cdn-storage.fermion.app',
masterM3u8Pathname: '/path/to/your/playlist.m3u8',
clearkeyDecryptionKeyInHex: '6815d8748df5297181862d32',
urlSearchParamString: '?verify=signature_here',
})
// Use this configuration with your custom HLS player (e.g., hls.js)
import Hls from 'hls.js'
if (Hls.isSupported()) {
const hls = new Hls({
pLoader: hlsConfig.PlaylistLoader,
})
hls.loadSource(hlsConfig.sourceUrl)
hls.attachMedia(videoElement)
}
To get the playback options (origin, masterM3u8Pathname,
clearkeyDecryptionKeyInHex, urlSearchParamString), you need to call the
get-signed-url-data-for-live-event-session
API endpoint from your backend
server with your Fermion API key. Refer to the API
documentation
for more information.
Chat Integration
To embed the live session chat, use this iframe manually (SDK support for chat coming soon):
<iframe
width="1280"
height="720"
src="https://acme.fermion.app/embed/live-session-chat?token=your_token_here"
title="Live event session chat"
frameborder="0"
allow="allow-same-origin; camera *;microphone *;display-capture *;encrypted-media;"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
>
</iframe>
Iframe Embed vs M3U8 Embed
Understanding the differences between iframe embedding and custom M3U8 playback can help you choose the right approach for your use case:
Feature | Iframe Embed (Recommended) | Custom M3U8 Playback (Advanced) |
---|
DRM Protection | ✅ Full DRM support | ❌ No DRM support |
Player Experience | ✅ Fully-built player with buffering, quality switching, error handling | ⚠️ Requires custom implementation |
Setup Complexity | ✅ Zero configuration, works out of the box | ⚠️ Additional complexity and dependencies |
UI/UX Consistency | ✅ Consistent, tested experience | ⚠️ Custom UI development required |
Maintenance | ✅ Automatic updates and improvements | ⚠️ Manual maintenance and bug fixes |
Customization | ⚠️ Limited to Fermion player interface | ✅ Full control over player and behavior |
WebRTC Support | ✅ Full WebRTC support for instructors | ❌ No WebRTC support (viewers only) |
Best For | Most production use cases, content protection, instructors | Advanced customization, existing player integration, viewers only |
We recommend using the iframe embed approach for most use cases as it
provides the best balance of security, functionality, and ease of
implementation. For instructors who need WebRTC functionality, iframe
embedding is the only option.
Manual Iframe Embedding (Alternative)
If you prefer not to use the SDK, you can embed live sessions manually using iframes:
Main Session View
<iframe
width="1280"
height="720"
src="https://acme.fermion.app/embed/live-session?token=your_token_here"
title="Live event session"
frameborder="0"
allow="allow-same-origin; camera *;microphone *;display-capture *;encrypted-media;"
referrerpolicy="strict-origin-when-cross-origin"
allowfullscreen
>
</iframe>
Lifecycle
You must also begin and end the streaming session via API calls. Inactive sessions with no instructor participants going on for more than 2 hours will be automatically terminated.
Please refer to fermion API here to learn more about these endpoints: https://api.fermion.app

Important Notes
-
Viewing Modes:
- By default, the live event starts in HLS mode (view-only)
- For instructors who need WebRTC (meeting mode), call the
modify-user-state-in-live-event-session
private API endpoint. Check the documentation for it.
- The same embed code and token work for both viewers and instructors
-
Security:
- Always generate unique tokens for each user
- Set appropriate token expiration times
- Keep your Fermion API key secure
Additional Resources
For more information about modifying user states and other API endpoints, please refer to our API documentation.