JWT token generation and signing utilities for secure playback access, DRM licensing, and viewer count authorization with configurable expiration and permissions.
import { Mux } from "@mux/mux-node";
// Initialize client with JWT keys
const mux = new Mux({
jwtSigningKey: process.env.MUX_SIGNING_KEY,
jwtPrivateKey: process.env.MUX_PRIVATE_KEY
});
// Access JWT utilities
const jwt = mux.jwt;Sign JWT tokens for secure playback access to protected video content.
/**
* Sign a playback token for single token type
* @param playbackId - The playback ID to sign
* @param config - JWT signing configuration
* @returns Promise resolving to signed JWT token
*/
signPlaybackId(playbackId: string, config?: MuxJWTSignOptions): Promise<string>;
/**
* Sign multiple playback tokens for different content types
* @param playbackId - The playback ID to sign
* @param config - JWT signing configuration for multiple tokens
* @returns Promise resolving to object containing multiple signed tokens
*/
signPlaybackId(playbackId: string, config?: MuxJWTSignOptionsMultiple): Promise<Tokens>;
interface MuxJWTSignOptions {
/** Token type to generate ('video' | 'thumbnail' | 'gif' | 'storyboard' | 'stats' | 'drm_license') */
type?: 'video' | 'thumbnail' | 'gif' | 'storyboard' | 'stats' | 'drm_license';
/** Token expiration time (e.g. "7d", "2 days", "10h") */
expiration?: string;
/** Additional claims to include */
params?: Record<string, string>;
/** Optional key ID override */
keyId?: string;
/** Optional key secret override */
keySecret?: string;
/** Optional key file path override */
keyFilePath?: string;
}
interface MuxJWTSignOptionsMultiple {
/** Array of token types to generate, optionally with per-type params */
type: Array<'video' | 'thumbnail' | 'gif' | 'storyboard' | 'stats' | 'drm_license' | ['video' | 'thumbnail' | 'gif' | 'storyboard' | 'stats' | 'drm_license', Record<string, string>]>;
/** Token expiration time (e.g. "7d", "2 days", "10h") */
expiration?: string;
/** Additional claims to include */
params?: Record<string, string>;
/** Optional key ID override */
keyId?: string;
/** Optional key secret override */
keySecret?: string;
/** Optional key file path override */
keyFilePath?: string;
}
interface Tokens {
/** Playback token for video streams */
'playback-token'?: string;
/** Thumbnail token for thumbnail images */
'thumbnail-token'?: string;
/** GIF token for animated GIFs */
'gif-token'?: string;
/** Storyboard token for storyboard images */
'storyboard-token'?: string;
/** Stats token for analytics data */
'stats-token'?: string;
/** DRM license token */
'drm-token'?: string;
}Usage Examples:
// Sign single playback token (default)
const token = await mux.jwt.signPlaybackId('your-playback-id', {
expiration: '7d', // Expires in 7 days
});
// Sign token with specific type and expiration
const thumbnailToken = await mux.jwt.signPlaybackId('your-playback-id', {
type: 'thumbnail',
expiration: 3600, // Expires in 1 hour
});
// Sign multiple token types
const tokens = await mux.jwt.signPlaybackId('your-playback-id', {
type: ['video', 'thumbnail', 'storyboard'],
expiration: '24h',
});
console.log(tokens['playback-token']); // Video playback token
console.log(tokens['thumbnail-token']); // Thumbnail access tokenSign JWT tokens for DRM license acquisition and protected content access.
/**
* Sign a DRM license token
* @param playbackId - The playback ID for DRM content
* @param config - DRM license signing configuration
* @returns Promise resolving to signed DRM license token
*/
signDrmLicense(playbackId: string, config?: MuxJWTSignOptions): Promise<string>;Usage Examples:
// Sign DRM license token
const drmToken = await mux.jwt.signDrmLicense('your-drm-playback-id', {
expiration: '2h', // Token expires in 2 hours
params: {
aud: 'drm', // Audience claim for DRM
},
});Sign JWT tokens for accessing viewer count and engagement statistics.
/**
* Sign a viewer count authorization token
* @param id - The resource identifier (asset ID, live stream ID, etc.)
* @param config - Viewer count signing configuration
* @returns Promise resolving to signed viewer count token
*/
signViewerCounts(id: string, config?: MuxJWTSignOptions): Promise<string>;Usage Examples:
// Sign viewer count token for asset
const viewerToken = await mux.jwt.signViewerCounts('your-asset-id', {
expiration: '1h',
params: {
type: 'asset',
},
});
// Sign viewer count token for live stream
const liveViewerToken = await mux.jwt.signViewerCounts('your-live-stream-id', {
expiration: '30m',
params: {
type: 'live_stream',
},
});Legacy space ID signing functionality. Deprecated: Mux Real-Time Video (spaces) has been shut down. This function will be removed in the next major version.
/**
* Sign a space ID token
* @param spaceId - The space identifier
* @param config - Space ID signing configuration
* @returns Promise resolving to signed space token
* @deprecated Mux Real-Time Video (spaces) has been shut down. This function will be removed in the next major version.
*/
signSpaceId(spaceId: string, config?: MuxJWTSignOptions): Promise<string>;enum TypeToken {
video = 'playback-token',
thumbnail = 'thumbnail-token',
storyboard = 'storyboard-token',
drm_license = 'drm-token',
gif = 'gif-token',
stats = 'stats-token'
}
enum TypeClaim {
video = 'v',
thumbnail = 't',
gif = 'g',
storyboard = 's',
stats = 'playback_id',
drm_license = 'd'
}enum DataTypeClaim {
video = 'video_id',
asset = 'asset_id',
playback = 'playback_id',
live_stream = 'live_stream_id'
}// Note: The params field accepts a Record<string, string> for custom JWT claimsJWT tokens support flexible expiration configuration using duration strings:
// Human-readable duration strings (using zeit/ms format)
const token1 = await mux.jwt.signPlaybackId('playback-id', {
expiration: '7d', // 7 days
});
const token2 = await mux.jwt.signPlaybackId('playback-id', {
expiration: '2 days', // 2 days
});
const token3 = await mux.jwt.signPlaybackId('playback-id', {
expiration: '10h', // 10 hours
});
const token4 = await mux.jwt.signPlaybackId('playback-id', {
expiration: '60', // 60 milliseconds
});const token = await mux.jwt.signPlaybackId('your-playback-id', {
expiration: '1d',
params: {
aud: 'my-app',
sub: 'user-123',
custom_claim: 'custom-value',
user_metadata: {
plan: 'premium',
region: 'us-east',
},
},
});const tokens = await mux.jwt.signPlaybackId('your-playback-id', {
type: ['video', 'thumbnail', 'storyboard', 'stats'],
expiration: '6h',
params: {
aud: 'my-video-app',
sub: 'viewer-456',
},
});
// Use tokens for different content types
const videoUrl = `https://stream.mux.com/${playbackId}?token=${tokens['playback-token']}`;
const thumbnailUrl = `https://image.mux.com/${playbackId}/thumbnail.jpg?token=${tokens['thumbnail-token']}`;import { AuthenticationError } from '@mux/mux-node';
try {
const token = await mux.jwt.signPlaybackId('invalid-playback-id');
} catch (error) {
if (error instanceof AuthenticationError) {
console.error('JWT signing failed: Invalid credentials');
} else {
console.error('JWT signing error:', error.message);
}
}type TokenExpiration = number | string | Date;
interface JWTPayload {
/** Playback ID */
sub: string;
/** Token type */
aud: string | Array<string>;
/** Expiration time */
exp: number;
/** Issued at time */
iat: number;
/** Additional claims */
[key: string]: any;
}