Protected / Non-Protected Variants

Protected and Non-Protected Variants

Protection variants let you create the opposite delivery mode from an existing ready content without uploading the media again:

  • A protected ("drm") content can create a non-protected ("clear") variant.
  • A non-protected ("clear") content can create a protected ("drm") variant.

The operation creates a separate content with its own content ID, retained input, processing job, output files and lifecycle. The source remains unchanged and stays ready; protectionMode is never modified in place.

⚠️

A clear variant has no DRM and can be downloaded by anyone who has a valid signed delivery URL. Only create one when the media is suitable for non-protected distribution.

Requirements

A variant can be created when all of the following are true:

  • The source content is ready and is a supported video or audio content.
  • Fastevo retained the source's original input. This is controlled by the project's original-copy retention setting.
  • The project is deployed, active and not suspended.
  • When the target mode is clear, clear delivery is enabled for new content.
  • No content in the same variant family already uses the requested target mode, including a matching content currently in trash.
  • The source is not already being copied by another variant operation.

Check Available Variants

In the Dashboard, variant actions appear in the content detail and overflow menu. For a protected content with no linked clear variant, the overflow-menu action Create unprotected version is omitted entirely while clear delivery creation is disabled. The detail card may still explain why creation is unavailable. Disabling the gate does not hide useful actions for an existing linked variant: it can still be opened, restored or retried when applicable.

Use the capability endpoint before displaying a Create protected version or Create non-protected version action:

GET https://api.fastevo.net/api/v1/projects/mediaProtection/contents/{contentId}/variants
Authorization: Bearer <token>

Example response:

{
  "protectionVariantGroupId": "6b0000000000000000000001",
  "originalAvailable": true,
  "variants": [
    {
      "contentId": "6b0000000000000000000010",
      "title": "Launch video",
      "protectionMode": "drm",
      "status": "ready",
      "isTrashed": false,
      "lifecycleState": "active"
    },
    {
      "contentId": "6b0000000000000000000011",
      "title": "Launch video - Clear",
      "protectionMode": "clear",
      "status": "processing",
      "isTrashed": false,
      "lifecycleState": "active"
    }
  ],
  "capability": {
    "allowed": false,
    "targetProtectionMode": "clear",
    "blockedReason": "TARGET_VARIANT_EXISTS",
    "existingContentId": "6b0000000000000000000011"
  }
}
FieldDescription
protectionVariantGroupIdStable ID shared by the protected and non-protected contents in the same family. It may be absent until the first variant is created.
originalAvailableWhether the source has a retained original that can be copied.
variants[]Every known content in the family, including trashed contents.
variants[].lifecycleStateOperational state independent from processing status: active, trashing, trashed, restoreQueued or restoring.
capability.allowedWhether a new opposite-mode variant can be requested now.
capability.targetProtectionModeThe only valid target mode for this source: "drm" or "clear".
capability.blockedReasonMachine-readable reason when allowed is false; otherwise null.
capability.existingContentIdExisting target content when the variant already exists or is in trash.

Possible capability blockers are:

blockedReasonMeaning
TARGET_VARIANT_EXISTSThe opposite variant already exists. Open existingContentId; for an error target, this blocker appears only when repeating the same PUT can safely retry that content.
TARGET_VARIANT_IN_TRASHThe opposite variant is in trash. Restore it instead of creating a duplicate.
PROTECTION_VARIANT_RETRY_UNAVAILABLEThe failed opposite variant cannot currently be retried. Permanently delete it to recreate the variant, or contact support if its lifecycle prevents deletion.
CONTENT_NOT_READYVariant creation starts only from a ready source.
UNSUPPORTED_CONTENT_TYPEThe source type cannot be converted to the requested delivery mode.
ORIGINAL_NOT_RETAINEDThere is no retained original to copy. Uploading the original again as new content is required.
SOURCE_BUSYAnother operation temporarily holds the source original. Retry later.
PROJECT_NOT_DEPLOYEDThe project's delivery infrastructure is not available.
CLEAR_DELIVERY_CREATION_DISABLEDNew clear content is disabled for this project.

Create a Variant

The target mode is part of the URL and must be the mode opposite to the source:

PUT https://api.fastevo.net/api/v1/projects/mediaProtection/contents/{sourceContentId}/variants/{protectionMode}
Authorization: Bearer <token>
Content-Type: application/json

protectionMode must be drm or clear. The request body is optional:

{
  "title": "Launch video - Clear",
  "priority": 5
}
FieldTypeRules
titlestringOptional; maximum 100 characters. It uses the standard content-title ASCII character set; Unicode and emoji are rejected.
priorityintegerOptional; 0 to 10, default 1. It has the same relative scheduling behavior as content creation.

Example:

curl -X PUT \
  "https://api.fastevo.net/api/v1/projects/mediaProtection/contents/6b0000000000000000000010/variants/clear" \
  -H "Authorization: Bearer $FASTEVO_TOKEN" \
  -H "Content-Type: application/json" \
  --data '{"title":"Launch video - Clear","priority":5}'

A newly created target returns 201 Created:

HTTP/1.1 201 Created
Location: /api/v1/projects/mediaProtection/contents/6b0000000000000000000011
{
  "contentId": "6b0000000000000000000011",
  "sourceContentId": "6b0000000000000000000010",
  "protectionVariantGroupId": "6b0000000000000000000001",
  "protectionMode": "clear",
  "status": "queued",
  "created": true
}

Track the returned target contentId through content queries or callbacks. It follows the normal queued → processing → ready lifecycle.

Idempotency and Retry

The PUT operation is safe to repeat:

  • The first request that creates the target returns 201 and created: true.
  • Concurrent requests and later requests for an existing target return 200 and created: false, with the same target contentId.
  • A repeated request never creates a third content for the same family and protection mode.
  • If the target is in error, the same request retries that same target content. Fastevo creates a new processing job while preserving the failed job's history. The response is 200, status: "queued" and created: false.
  • If the target already has an independent retained input whose size and provenance match its storage object, retry does not need the sibling source's original or source lease. Otherwise, Fastevo falls back to the sibling source, reacquires it briefly and creates a fresh independent copy.

Check capability again before retrying. If the independent target input fails verification and the source fallback is unavailable, the response reports ORIGINAL_NOT_RETAINED or SOURCE_BUSY. Do not send a regular reprocess request to change protectionMode; that field remains immutable.

Storage, Processing and Deletion

Fastevo copies the retained original into the target content's own storage namespace before processing. The copy is verified before the source is released, so deleting one variant later does not delete the other's original or outputs.

This also means that variants consume additional resources:

  • One retained original is stored for each content.
  • Each variant has its own transcoded and packaged outputs.
  • Creating or retrying a variant runs a normal processing job and contributes storage and processing usage according to your plan.

During the brief original-copy phase, trash, deletion and reprocessing of the source are blocked with SOURCE_BUSY. Once the independent target input is durable, both contents have separate lifecycle controls. Sending a target to trash does not remove the source, and vice versa.

For large originals, an interrupted server-side multipart copy is safe to retry: a new attempt uses the same target namespace, and incomplete copy parts left by a hard stop become eligible for automatic lifecycle cleanup after one day. They are not published as a content input and do not block the retry.

If the target variant is already in trash, creation returns TARGET_VARIANT_IN_TRASH with its existingContentId. Use the trash restore endpoint rather than creating a duplicate. Restore can be requested immediately after deletion: while the target is still trashing, the API stores the request and reports restoreQueued. The Dashboard polls through restoring until the same target returns to active; it never creates a replacement content or a third family member.

Errors

Errors use the standard API error envelope:

{
  "statusCode": 409,
  "error": "Conflict",
  "message": "The requested protection variant is in trash and must be restored.",
  "code": "TARGET_VARIANT_IN_TRASH",
  "details": {
    "existingContentId": "6b0000000000000000000011"
  }
}
StatusCodeAction
409CONTENT_NOT_READYWait until the source is ready.
409ORIGINAL_NOT_RETAINEDUpload the original as new content; an output rendition is not used as a substitute.
409SOURCE_BUSYRetry after the current source operation finishes.
409TARGET_PROTECTION_MODE_EQUALS_SOURCERequest the opposite protection mode.
409TARGET_VARIANT_IN_TRASHRestore details.existingContentId.
409PROTECTION_VARIANT_RETRY_UNAVAILABLEPermanently delete the failed target to recreate the variant, or contact support if its lifecycle prevents deletion.
409PROJECT_NOT_DEPLOYEDWait until the project's delivery infrastructure is deployed.
403CLEAR_DELIVERY_CREATION_DISABLEDEnable clear delivery or request a DRM target.
422UNSUPPORTED_CONTENT_TYPEUse a supported video or audio source.
401, 403, 404Standard authorization/not-found errorsVerify the token, content-upload permission, project and source content ID.

Playback

Use each variant as a normal, independent content:

  • For a DRM target, generate a playback token with the target content ID and use the Fastevo Player.
  • For a clear target, create signed URLs as described in Non-Protected Content.