Protect a Live stream with multi-DRM
Available in: UI · API
Use this how-to when a Live stream must reach web, Windows and Apple clients with DRM enforced on every platform. The integration model is the same regardless of the surface: register a DRM provider once, then attach it to each protected Destination.
When to use this
When a DASH, CMAF or HLS / TS Destination on a Live stream must encrypt segments and have license URLs in the manifest. For the broader concept reference see DRM.
Prerequisites
- The System Administrator role. The DRM provider CRUD is gated to that role; Operators cannot register, validate, edit or delete providers.
- A multi-DRM vendor account. The catalogue publishes
AXINOMandEZDRMtoday. From the vendor you receive a SPEKE endpoint, the credentials envelope expected by the brand and — for brands that need it — a tenant id. - A
DASH,CMAForHLS / TSDestination on the Live stream that will carry the protected output.
Via UI
Navigation: Integrations → DRM → Providers.
Register the DRM provider
Open Integrations → DRM → Providers and click Add provider. The form maps to the DrmProviderCreateRequest schema:
| UI label | API field | Notes |
|---|---|---|
| Name | name | Display name (≤ 100 characters). |
| Provider type | provider_type | One of the values from the server-side catalogue (today AXINOM, EZDRM). |
| SPEKE URL | speke_url | Primary SPEKE endpoint. |
| SPEKE backup URL | speke_url_backup | Optional fallback. |
| Tenant id | tenant_id | Required when the chosen Provider type declares requires_tenant_id = true. |
| Credentials | credentials | Provider-specific envelope. Write-only — GET returns the redacted sentinel value. |
| Enabled | enabled | Whether the provider is selectable by Destinations. |
Submit. The new row appears in the providers list with Validation status: UNKNOWN.
Validate
Run the Validate action on the new provider row. The handler round-trips the credentials against the upstream SPEKE service. The Validation status column flips to VALID (success) or INVALID (failure). A failure surfaces a sanitised error in Validation error; correct the credentials with Edit and re-validate.
Attach the provider to a Destination
Open the Destination under Destinations and fill the DRM block:
| UI label | API field | Notes |
|---|---|---|
| Active | drm.active | Toggle that turns DRM on for this Destination. |
| Provider | drm.provider_id | Picker over the registered providers (only enabled providers appear). |
| Content id | drm.contentid | The content identifier expected by the vendor. |
| Systems | drm.systems[] | Any combination of Widevine, PlayReady, FairPlay. |
| Encryption mode | drm.encryption_mode | One of cenc or cbcs. |
Save. The Destination's row shows a shield indicator when DRM is active.
Start the Live stream
Start the Live stream from On air or the Live stream's detail page. The encoder requests keys from the configured SPEKE endpoint, encrypts the segments and writes the license URLs into the manifest.
Via API
DRM provider CRUD:
| Action | Method + path | operationId |
|---|---|---|
| List providers | GET /c21apiv2/settings/integrations/drmproviders | getAllDrmProviders |
| Create a provider | POST /c21apiv2/settings/integrations/drmproviders | addDrmProvider |
| Validate a provider | POST /c21apiv2/settings/integrations/drmproviders/{providerId}/validate | validateDrmProvider |
| Update a provider | PUT /c21apiv2/settings/integrations/drmproviders/{providerId} | updateDrmProvider |
| Delete a provider | DELETE /c21apiv2/settings/integrations/drmproviders/{providerId} | deleteDrmProvider |
The DRM block on a Destination is set through addPublishing / updatePublishing:
# 1. Register the provider
curl -X POST "https://<your-host>/c21apiv2/settings/integrations/drmproviders" \
-H "Authorization: Bearer <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"name": "MyDRMProvider",
"provider_type": "AXINOM",
"speke_url": "https://drm-axinom.example/speke/v2",
"tenant_id": "<tenant>",
"credentials": { "...": "..." },
"enabled": true
}'
# 2. Validate
curl -X POST "https://<your-host>/c21apiv2/settings/integrations/drmproviders/<providerId>/validate" \
-H "Authorization: Bearer <YOUR_API_TOKEN>"
# 3. Attach to an existing DASH/CMAF/HLS Publishing
curl -X PUT "https://<your-host>/c21apiv2/publishings/<publishingId>" \
-H "Authorization: Bearer <YOUR_API_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"drm": {
"active": true,
"provider_id": <providerId>,
"contentid": "<vendor content id>",
"systems": ["Widevine", "PlayReady"],
"encryption_mode": "cenc"
}
}'
validation_status carries UNKNOWN (just registered), VALID (validation succeeded) or INVALID (validation failed). Common patterns:
| Pattern | drm.systems | drm.encryption_mode |
|---|---|---|
| DASH + CMAF, web + Microsoft | ["Widevine", "PlayReady"] | cenc |
| CMAF / HLS, Apple coverage | ["FairPlay"] (or all three) | cbcs |
Universal cbcs delivery | ["Widevine", "PlayReady", "FairPlay"] | cbcs |
Verify
- The provider row reads Validation status: VALID.
GET /c21apiv2/publishings/{publishingId}returns thedrmblock withactive: trueand the expectedsystems/encryption_mode.- Players from each target ecosystem successfully decrypt and play the protected output:
| Ecosystem | Browser / device | Manifest |
|---|---|---|
| Widevine | Chrome or Edge on desktop | DASH or CMAF |
| PlayReady | Edge on Windows | DASH or CMAF |
| FairPlay | Safari on iOS or macOS | HLS / CMAF |
The upstream vendor's dashboard logs one license issuance per session per ecosystem.
FAQ
validation_error. Common causes are a wrong tenant id, mistyped credentials, or the SPEKE endpoint being unreachable from this C21 Live Control instance. Correct the field with updateDrmProvider (or Edit in the UI) and re-run Validate.updateDrmProvider; the change applies to subsequent key acquisitions. Running Live streams keep working under the keys they already hold until their next rotation.Broadcast radio as video
Run a radio Channel as a Live stream where the visual track is a programmable still or short clip, the audio is always the live feed, and the visual can be swapped without interrupting the audio.
Schedule a weekly recurring broadcast
Drive a Live stream on a fixed cadence — from the Scheduler UI, from the API, or both.