# Create a playback session

Request and consume the DRM-X Universal Playback Session Contract with authentication, trusted Content IDs, and bounded authorization.

Canonical: https://docs.drm-x.com/api-reference/playback-sessions
Updated: 2026-09-05

![Your backend decides access; DRM-X enforces the signed policy. Encrypted media and DRM licenses follow separate delivery paths.](https://docs.drm-x.com/assets/session-flow.svg)Your backend decides access; DRM-X enforces the signed policy. Encrypted media and DRM licenses follow separate delivery paths.

API 

## Create a Universal Playback Session[#](#create-a-universal-playback-session)



```
POST https://api6.drm-x.com/api/v1/playback/environments/{siteId}/sessions
Accept: application/json
Content-Type: application/json
X-DRMX-Client-Id: {siteKey}
X-DRMX-Client-Secret: {accessKey}
```



```
{
"contentId": "course-12-lesson-4",
"contentType": "vod",
"drmSystem": "widevine",
"subject": "customer-user-1001",
"sessionId": "new-unpredictable-id-per-playback",
"playbackMode": "streaming",
"licensePolicyTemplate": "multi-tier-standard",
"useEnvironmentDefaults": true,
"applicationId": "customer-web",
"platformCapabilities": {
"clientPlatform": "web",
"drmSystems": ["widevine"],
"manifestTypes": ["dash"],
"maximumHeight": 2160,
"persistentState": false,
"sdkVersion": "1.1.0-preview.13"
}
}
```



A successful Contract v1 response includes the authoritative manifest, available manifest variants, a DRM-specific license URL, a short-lived DRM License Token or customer proxy authorization, a release route, the licensed maximum height, and allowed tracks. Return it with `Cache-Control: no-store`.



Use one unpredictable session ID for each real playback attempt. Reusing an ID across devices defeats concurrent-stream counting.





## Authentication and trusted request fields[#](#authentication-and-trusted-request-fields)

Call this API from your backend with a project API client that has `license-tokens:create`. Use the environment UUID as `siteId`. Your authenticated viewer calls your endpoint; your endpoint supplies the trusted fields below.

| Field | Meaning | Integration rule | 
| --- | --- | --- |

| `contentId` | The published content reference | Resolve from your trusted catalog after the entitlement check. | 

| `subject` | Your stable viewer identifier | Derive from the authenticated session, not a client-supplied user ID. | 

| `drmSystem` | `widevine`, `playready`, `fairplay`, or `wiseplay` | Match the selected DRM to the player capabilities. | 

| `sessionId` | Identity of this playback attempt | Generate a fresh unpredictable value for each attempt. | 

| `contentType` | `vod` or `live` | Use the type registered for the content. | 

| `playbackMode` | `streaming` in Contract v1 | Offline playback requires a later contract extension. | 

| `licensePolicyTemplate` / `licensePolicy` | A named policy or custom policy | Select on your server; do not supply both. See [policy rules](https://docs.drm-x.com/license-service/policies). | 

| `platformCapabilities` | Platform, DRM systems, manifest types, and device hints | Send explicit capabilities with new integrations. They describe the client; they do not override license policy. | 



## Consume the response descriptors[#](#consume-the-response-descriptors)

Use the nested Contract v1 descriptors. Do not construct license URLs from guesses or replace registered manifest URLs with player inputs.

| Response field | How to use it | 
| --- | --- |

| `contractVersion` | Verify that the returned contract version is supported by your integration. | 

| `manifestUrl` / `manifestUrls` | Load the authoritative selected manifest or a returned compatible variant. | 

| `expiresAt` | The expiry of this bounded authorization. | 

| `drm` | Read `system`, `licenseServerUrl`, `drmLicenseToken`, `tokenType`, and the optional `fairPlayCertificateUrl`. A customer token proxy can replace the browser-facing authorization with its own bounded session. | 

| `release` | Use its `url`, `method`, and `authorizationScheme` to release the session when playback ends. | 

| `policy` | Honor `maximumHeight` and `allowedTrackTypes`. The provider still enforces the signed policy. | 

| `tracks` | Read audio/subtitle language-selection capability and the language-tag standard. | 

Return your player response with `Cache-Control: no-store`. Never forward the project Access Key to the browser. Restrict authorization headers to the returned license and certificate routes.



## Handle errors and release reservations[#](#handle-errors-and-release-reservations)

Inspect the HTTP status and machine-readable `code`. Retain the `requestId` for troubleshooting and respect `retryable`; a denied entitlement or invalid policy needs a corrected decision, not a retry loop. See the [playback session error reference](https://docs.drm-x.com/api-reference/errors).

Release the reservation on Stop, playback replacement, terminal errors, and application shutdown. A fresh playback attempt gets a new session ID.
