Skip to content

Remote Device JSON Format

Ingan121 edited this page Sep 7, 2025 · 7 revisions

Normal Remote Devices

{
    "type": "WIDEVINE",
    "device_name": "public",
    "device_type": "ANDROID",
    "host": "https://cdrm-project.com/remotecdm/widevine",
    "name_override": "CDRM-Project Public Widevine API",
    "secret": "CDRM",
    "security_level": 3,
    "system_id": 22590
}
  • type: WIDEVINE or PLAYREADY, assumes WIDEVINE if omitted.
  • device_name* (or name): Device name.
  • device_type (Widevine only): ANDROID or CHROME
  • host*: The base URL of the remote server. Required unless this is a SuperGeneric device.
  • name_override: Device name to show in the remote devices list in the Vineless panel, will use ${host}/${device_name} if omitted.
  • secret: The secret key to use for your remote device.
  • security_level*: WV: 1 (L1), 2 (L2), or 3 (L3), PR: "150" (SL150), "2000" (SL2000), or "3000" (SL3000)
  • system_id* (Widevine only): The Widevine system ID of your remote device.
  • * denotes a required field

Vineless SuperGeneric Remote Devices

  • In addition to the above items, you can provide an additional sg_api_conf field with an object containing the following data.
  • Designed for remote devices that are not compatible with the pywidevine or pyplayready's remote API spec.
{
    "type": "WIDEVINE",
    "device_name": "public",
    "device_type": "ANDROID",
    "host": "https://cdrm-project.com/remotecdm/widevine",
    "name_override": "SuperGeneric Sample for CDRM-Project Widevine",
    "security_level": 3,
    "system_id": 22590,
    "sg_api_conf": {
        "headers": {
            "Content-Type": "application/json",
            "X-Secret-Key" : "{secret}"
        },
        "generateChallenge": [
            {
                "method": "GET",
                "url": "/{device_name}/open",
                "sessionIdResKeyName": "data.session_id"
            },
            {
                "method": "POST",
                "url": "/{device_name}/set_service_certificate",
                "sessionIdKeyName": "session_id",
                "serverCertKeyName": "certificate",
                "serverCertOnly": true
            },
            {
                "method": "POST",
                "url": "/{device_name}/get_license_challenge/AUTOMATIC",
                "bodyObj": {
                    "privacy_mode": true
                },
                "sessionIdKeyName": "session_id",
                "psshKeyName": "init_data",
                "challengeKeyName": "data.challenge_b64"
            }
        ],
        "parseLicense": [
            {
                "method": "POST",
                "url": "/{device_name}/parse_license",
                "sessionIdKeyName": "session_id",
                "licenseKeyName": "license_message"
            },
            {
                "method": "POST",
                "url": "/{device_name}/get_keys/CONTENT",
                "sessionIdKeyName": "session_id",
                "contentKeysKeyName": "data.keys"
            },
            {
                "method": "GET",
                "url": "/{device_name}/close/%s"
            }
        ],
        "keyParseRules": {
            "keyKeyName": "key",
            "kidKeyName": "key_id"
        },
        "messageKey": "message"
    }
}
  • KeyName (string or string[]): A dot-separated string or an array of strings denoting nested property names. E.g., 'data.session_id' or ['data', 'session_id'].
  • URL (string): A string that may contain {device_name} and %s. {device_name} will be replaced with the actual device name. %s will be replaced with the session ID. The base URL (host in the JSON root) will be prepended to this URL.
  • HeaderObject (Object): An object representing the headers to include in the request. A header having a value of {secret} will be replaced with the actual secret key defined as the secret property in the JSON root. If the secret property is missing, the header will be omitted.

Root object of sg_api_conf

  • headers (HeaderObject): The base headers to include in the request; will be merged with the request-specific headers.
  • overrideHeaders (Object): Use this to override some restricted headers. Only works on Firefox-based browsers due to Chromium's Manifest V3 limitation.
    • urls (string[]): An array of URL patterns to match for this override. URL patterns follow the match patterns syntax.
    • headers (Object): The headers to override for the matched URLs.
  • generateChallenge (GenerateChallengeRequest or GenerateChallengeRequest[]): An array of requests or a single request to perform in order to generate a license challenge.
  • parseLicense (ParseLicenseRequest or ParseLicenseRequest[]): An array of requests or a single request to perform in order to parse a license.
  • keyParseRules (KeyParseRules): Rules to apply when parsing keys from the response.
  • messageKey (KeyName): The key name of the server message returned in the response. The last found message will be shown in the error notification message if something goes wrong.
  • prPsshAsIs (boolean, PlayReady-only): If true, the PSSH data will be sent as-is without any decoding. If false, the decoded XML WRM header string will be used.
  • Missing elements in the root object will be substituted with the default values. (which are the same as the example above)

GenerateChallengeRequest

  • method (string): HTTP method to use for the request (e.g., "GET", "POST")
  • url (URL): The URL to send the request to.
  • headers (HeaderObject): Headers to include in the request, will be merged with the base headers (sg_api_conf.headers)
  • Request body keys
    • bodyObj (Object): The static part of the JSON request body
    • sessionIdKeyName (KeyName): The key name to put the session ID in the request body
    • psshKeyName (KeyName): The key name to put the PSSH data in the request body
    • serverCertKeyName (KeyName): The key name to put the server certificate data in the request body
  • Result parsing keys
    • sessionIdResKeyName (KeyName): The key name of the session ID returned in the response
    • challengeKeyName (KeyName): The key name of the challenge data returned in the response
    • encodeB64 (boolean): If true, the returned challenge data will be base64-encoded before the next processing step
    • bundleInKeyMessage (boolean, PlayReady-only): If true, the challenge will be bundled in the PlayReady XML-enclosed key message format, before being passed to the web page JavaScript
  • serverCertOnly (boolean): If true, this request will be performed only if there is a server certificate to send
  • messageKey (KeyName): The key name of the server message returned in the response. The last found message will be shown in the error notification message if something goes wrong. Preferred over sg_api_conf.messageKey if this exists

ParseLicenseRequest

  • method (string): HTTP method to use for the request (e.g., "GET", "POST")
  • url (URL): The URL to send the request to.
  • headers (HeaderObject): Headers to include in the request, will be merged with the base headers (sg_api_conf.headers)
  • Request body keys
    • bodyObj (Object): The static part of the JSON request body
    • sessionIdKeyName (KeyName): The key name to put the session ID in the request body
    • psshKeyName (KeyName): The key name to put the PSSH data in the request body
    • serverCertKeyName (KeyName): The key name to put the server certificate data in the request body
    • challengeKeyName (KeyName): The key name to put the challenge data in the request body
    • licenseKeyName (KeyName): The key name to put the license data in the request body
  • Result parsing keys
    • sessionIdResKeyName (KeyName): The key name of the session ID returned in the response
    • contentKeysKeyName (KeyName): The key name of the content keys returned in the response
  • messageKey (KeyName): The key name of the server message returned in the response. The last found message will be shown in the error notification message if something goes wrong. Preferred over sg_api_conf.messageKey if this exists

KeyParseRules

  • regex (Object): Provide this to enable the regex mode. keyKeyName and kidKeyName will be ignored if this is set.
    • data (string): The regex pattern to match the content key in the content keys array. Use parentheses to define capturing groups for the key ID and key value. Example: "--key ([0-9a-fA-F]+):([0-9a-fA-F]+)"
    • keyFirst (boolean): If true, the first capturing group is treated as the key, and the second as the key ID.
  • keyKeyName (KeyName): The key name to parse the content key in the content keys array
  • kidKeyName (KeyName): The key name to parse the key ID in the content keys array
  • base64 (boolean): Set to true if the content keys are base64-encoded. Set to false if they are hex-encoded.
  • needsFlipping (boolean): Set to true if the content keys need to be UUID-flipped. Some PlayReady implementations may require this.

Clone this wiki locally