DRM & Encryption
Transcodely supports industry-standard DRM (Digital Rights Management) for protecting premium video content. DRM encryption is configured at the output level and is available for streaming formats only: hls, dash, and adaptive.
HLS DRM is not yet fully wired. Jobs with DRM on
hls(or the HLS side ofadaptive) complete successfully, but the generated HLS playlists do not emit encryption signaling (#EXT-X-KEY/#EXT-X-SESSION-KEY), so the HLS rendition is effectively undecryptable. DASH DRM (ContentProtectionin the MPD) is the verified, working path. Becauseadaptiveproduces both an HLS and a DASH manifest from shared CMAF segments, only its DASH rendition is currently protected. Usedashfor production DRM until HLS DRM signaling lands.
DRM is configured via the drm object on an Output Specification. You provide the DRM systems to use, the encryption scheme, and either your own encryption keys (BYOK) or a key server URL.
DRM adds a 1.25x feature multiplier to the output cost. See Pricing for details.
The DRMConfig object
| Attribute | Type | Required | Description |
|---|---|---|---|
systems | array of enums | Yes | DRM systems to enable. One or more of: widevine, fairplay, playready. Maximum 3. See DRM systems. |
scheme | enum | Yes | Encryption scheme. One of: cenc, cbcs. See Encryption schemes. |
byok | object | One of | Bring Your Own Key configuration. Mutually exclusive with key_server. See Bring Your Own Key. |
key_server | object | One of | Key server configuration. Mutually exclusive with byok. See Key server. |
clear_lead_seconds | number | No | Duration of unencrypted content at the start of the stream, in seconds (0—30). Useful for ad insertion before encrypted content. Default: 0. |
{
"drm": {
"systems": ["widevine", "fairplay"],
"scheme": "cbcs",
"key_server": {
"license_server_url": "https://drm.example.com/v1/keys"
}
}
}DRM systems
Transcodely supports the three major DRM systems. Specify one or more in the systems array.
| System | API Value | Platforms | Description |
|---|---|---|---|
| Widevine | widevine | Chrome, Firefox, Android, Chromecast, smart TVs | Google’s DRM. Most widely used for web and Android. Free to use. |
| FairPlay | fairplay | Safari, iOS, iPadOS, tvOS, macOS | Apple’s DRM. Required for content protection on Apple devices. Requires Apple developer account. |
| PlayReady | playready | Edge, Windows, Xbox, smart TVs | Microsoft’s DRM. Used for Windows apps and gaming consoles. |
For maximum device coverage, use all three systems:
{
"systems": ["widevine", "fairplay", "playready"]
}Encryption schemes
The encryption scheme determines how media samples are encrypted. Your choice of scheme must be compatible with the DRM systems you select.
| Scheme | API Value | Algorithm | Description |
|---|---|---|---|
| CENC | cenc | AES-128 CTR | Common Encryption. Full sample encryption. Supported by Widevine and PlayReady. Not recommended for FairPlay. |
| CBCS | cbcs | AES-128 CBC | Common Encryption with subsample pattern encryption. Supported by all three DRM systems. Recommended for multi-DRM. |
Compatibility matrix
| DRM System | CENC | CBCS |
|---|---|---|
| Widevine | Yes | Yes |
| FairPlay | No | Yes |
| PlayReady | Yes | Yes |
Use
cbcswhen targeting multiple DRM systems including FairPlay. Usecenconly when targeting Widevine and/or PlayReady without FairPlay.
Bring Your Own Key
Use BYOK when you manage your own encryption keys. This gives you full control over key rotation and distribution.
| Attribute | Type | Required | Description |
|---|---|---|---|
key_id | string | Yes | Key identifier as 32-character hex string (16 bytes). Identifies the key in the DRM license server. |
key | string | Yes | Content encryption key as 32-character hex string (16 bytes). This is the actual encryption key — keep it secret. |
pssh_widevine | string | No | Base64-encoded Widevine PSSH box data. Provide when systems includes widevine so players can acquire a Widevine license. Not server-validated. |
pssh_playready | string | No | Base64-encoded PlayReady PSSH header. Provide when systems includes playready so players can acquire a PlayReady license. Not server-validated. |
fairplay_iv | string | No | Initialization vector for FairPlay as 32-character hex string. Provide when systems includes fairplay. Not server-validated. |
fairplay_uri | string | No | FairPlay key delivery URI, conventionally using the skd:// scheme. Provide when systems includes fairplay. Max 2048 characters. |
Widevine BYOK
A Widevine-only configuration using the CENC scheme. Supply your key_id and key as 32-character hex strings, plus a Base64 pssh_widevine box so players can acquire a license.
{
"drm": {
"systems": ["widevine"],
"scheme": "cenc",
"byok": {
"key_id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"key": "f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1",
"pssh_widevine": "AAAAQ3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADMIARIQobLD1OX2p7jJ0OHyprTF1hoLdHJhbnNjb2RlbHkiEKGyw9Tl9qe4ydDh8qa0xdY="
}
}
}Multi-DRM BYOK with CBCS
One CBCS key shared across Widevine, PlayReady, and FairPlay. Provide each system’s signaling — pssh_widevine, pssh_playready, and the FairPlay fairplay_iv/fairplay_uri — alongside the shared key_id and key.
{
"drm": {
"systems": ["widevine", "fairplay", "playready"],
"scheme": "cbcs",
"byok": {
"key_id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"key": "f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1",
"pssh_widevine": "AAAAQ3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7QAAADMIARIQobLD1OX2p7jJ0OHyprTF1hoLdHJhbnNjb2RlbHkiEKGyw9Tl9qe4ydDh8qa0xdY=",
"pssh_playready": "AAACJnBzc2gAAAAAmgTweZhAQoarkuZb4IhflQAAAgYGAgAAAQABAPwBPABXAFIATQBIAEUAQQBEAEUAUgAgAHgAbQBsAG4AcwA9ACIAaAB0AHQAcAA6AC8ALwBzAGMAaABlAG0AYQBzAC4AbQBpAGMAcgBvAHMAbwBmAHQALgBjAG8AbQAvAEQAUgBNAC8AMgAwADAANwAvADAAMwAvAFAAbABhAHkAUgBlAGEAZAB5AEgAZQBhAGQAZQByACIAIAB2AGUAcgBzAGkAbwBuAD0AIgA0AC4AMAAuADAALgAwACIAPgA8AEQAQQBUAEEAPgA8AFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBFAFkATABFAE4APgAxADYAPAAvAEsARQBZAEwARQBOAD4APABBAEwARwBJAEQAPgBBAEUAUwBDAFQAUgA8AC8AQQBMAEcASQBEAD4APAAvAFAAUgBPAFQARQBDAFQASQBOAEYATwA+ADwASwBJAEQAPgAxAE0ATwB5AG8AZABUADIAcABmAGoASgAwAE8ASAB5AHAAcgBUAEYAMQBnAD0APQA8AC8ASwBJAEQAPgA8AC8ARABBAFQAQQA+ADwALwBXAFIATQBIAEUAQQBEAEUAUgA+AA==",
"fairplay_iv": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"fairplay_uri": "skd://license.example.com/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
}
}
}Key server
Use a key server when you want your DRM provider to manage key generation and delivery. Transcodely fetches encryption keys from your key server during packaging.
| Attribute | Type | Required | Description |
|---|---|---|---|
license_server_url | string | Yes | URL of the key server endpoint. Must be a valid HTTPS URI. Max 2048 characters. |
auth_token | string | No | Authentication token passed to the key server. Max 2048 characters. |
content_id | string | No | Content identifier passed to the key server. Max 256 characters. |
{
"drm": {
"systems": ["widevine", "fairplay"],
"scheme": "cbcs",
"key_server": {
"license_server_url": "https://drm.example.com/v1/keys",
"auth_token": "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"content_id": "movie_2025_summer_release"
}
}
}Clear lead
The clear_lead_seconds field specifies how many seconds at the beginning of the stream remain unencrypted. This is useful for:
- Ad insertion — pre-roll ads can be served from an unencrypted segment without requiring a DRM license
- Preview clips — allow viewers to sample content before DRM authentication
The value must be between 0 and 30 seconds. When omitted, it defaults to 0 (the entire stream is encrypted).
{
"drm": {
"systems": ["widevine", "fairplay"],
"scheme": "cbcs",
"key_server": {
"license_server_url": "https://drm.example.com/v1/keys"
},
"clear_lead_seconds": 10
}
}Complete example
A full dash output specification that layers several DRM building blocks onto an adaptive package. This uses dash, the verified DRM path (see the HLS DRM note above):
- An H.264 ABR ladder at 1080p, 720p, and 480p, mixing
standardandeconomyquality tiers. - Two audio tracks — English (default) and Spanish — packaged alongside the video.
- Multi-DRM across all three systems under one CBCS BYOK key, with a 5-second
clear_lead_secondsso a pre-roll can play before encryption begins.
{
"type": "dash",
"video": [
{"codec": "h264", "resolution": "1080p", "quality": "standard"},
{"codec": "h264", "resolution": "720p", "quality": "standard"},
{"codec": "h264", "resolution": "480p", "quality": "economy"}
],
"audio": [
{"language": "eng", "label": "English", "is_default": true},
{"language": "spa", "label": "Spanish"}
],
"drm": {
"systems": ["widevine", "fairplay", "playready"],
"scheme": "cbcs",
"byok": {
"key_id": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"key": "f6e5d4c3b2a1f0e9d8c7b6a5f4e3d2c1",
"pssh_widevine": "AAAAQ3Bzc2gAAAAA7e+LqXnWSs6jyCfc1R0h7Q...",
"fairplay_iv": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6",
"fairplay_uri": "skd://license.example.com/a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"
},
"clear_lead_seconds": 5
}
}Validation rules
Transcodely validates DRM configuration at job creation time. The following constraints are enforced:
| Rule | Description |
|---|---|
| Streaming formats only | DRM is only available for hls, dash, and adaptive output types. Progressive formats (mp4, webm, mkv, mov) do not support DRM. |
| At least one system | The systems array must contain 1—3 DRM system values. |
| Scheme required | The scheme field is required and must be cenc or cbcs. |
| FairPlay requires CBCS | If systems includes fairplay, the scheme must be cbcs. |
| Mutually exclusive key source | Exactly one of byok or key_server must be provided. |
| BYOK key format | key_id and key must be exactly 32 hex characters (16 bytes). |
| FairPlay URI length | When provided, fairplay_uri must be at most 2048 characters. The skd:// scheme is a convention for players, not a server-enforced rule. |
| Key server URL | license_server_url must be a valid URI. Max 2048 characters. |
| Clear lead range | clear_lead_seconds must be between 0 and 30 (inclusive). |