Shift72 Content API (1.0.0)

Download OpenAPI specification:Download

Playback

The main API for playing content is the Streams API. This gives you the URLs of the manifest (DASH .mpd, or HLS .m3u8), as well as granting a playtoken needed for the license check.

The APIs for issuing playtokens are used when you need to use an API key to authorize a playback. The playtoken can be used by players allowing the bearer to watch content without needing an authtoken.

Get playback streams for a slug

Returns the details you need to play some content.

Content is encoded with different formats (HLS/DASH) and DRM, so this will return multiple Streams objects and you need to pick the right one for your player.

This will return a playtoken. This is a JWT authorizing you to watch this specific content. You'll need to provide the playtoken to the license server in order to prove you're allowed to watch.

You can either provide an authtoken for a user, or a valid playtoken for the content.

Note: this API can also be called as a POST with an empty body.

Authorizations:
AuthTokenPlayToken
path Parameters
slug
required
string
Example: /film/123

The slug of content to play, i.e. a film, film bonus, or TV episode.

Responses

Response Schema: application/json
play_token
string

a JWT used to authorize this playback session with the license server

Array of objects
Array
url
string

Stream URL (e.g. the .m3u8 or .mpd manifests, or .mp4 depending on the content type). Usually this is going to point to mrs.shift72.com with the playtoken as a query param.

encoding_type
string
Enum: "hd_dash" "hd_mp4" "hls"

the type of stream. Common values are 'hd_dash' (.mpd manifest used with Widevine and PlayReady DRM), 'hls' (used with Fairplay), and 'hd_mp4' for raw files (no DRM, e.g. trailers).

drm_type
Array of strings or null
Enum: "widevine" "playready" "fairplay"

the DRMs used for this content encoding. DASH manifests contain both PlayReady and Widevine.

object or null

The last known playback position, if available.

play_position
number

Last reported play position, in seconds

length
number

Reported content length

last_played_at
string <date-time>

When was the content last played?

ad_tag
string or null

a VMAP url to use for this content if ads are configured.

will_trigger_watch_window
boolean

If true, the watch window will be triggered when a license request is made

willTriggerRentalWindow
boolean
Deprecated

Use will_trigger_watch_window instead. This field is retained for compatibility.

watch_window_duration
number or null

The duration of the watch window, in minutes. This will be null if there's no watch window or it's not a rental.

default_subtitle_language
string or null

A hint to the player for picking default subtitles. Currently configured globally for a site.

object

Playback and content related configurations and feature toggles

property name*
additional property
any

Response samples

Content type
application/json
{}

Get playlist for a slug

Playable slugs have a playlist associated with them. Currently, this is used for preroll and postroll, but it can theoretically support any arbitrary content on your platform.

A playlist is a series of items to play (e.g. different slugs).

The default playlist for any playable slug (e.g film, bonus or episode) is just a playlist with a single item in it.

Auth is not required, but is recommended so that your playback progress can be taken into account.

Note: this API can also be called as a POST with an empty body.

Authorizations:
AuthTokenPlayToken
path Parameters
slug
required
string
Example: /film/123

The slug to get playlist for, i.e. a film, film bonus, or TV episode.

Responses

Response Schema: application/json
title
string

Title of the content being watched

Array of objects
Array
id
string

a unique id of this item within the playlist

title
string

The title of the content

has_watched
boolean

Whether the user has already watched this content. This isn't very accurate because our playback progress isn't per-playlist yet

skip_policy
string
Enum: "allowed" "must-view-once" "must-view-once-per-session" "never"

How should the user be able to skip this content? This is used by the playlist system in Shift72's player, for example to require a sponsorship ad is shown at least once, but is then skippable in future.

object
type
string
Value: "play"

The action type. "play" is the only supported type

slug
string

The item to play

Response samples

Content type
application/json
{
  • "title": "Citizen Kane",
  • "items": [
    • {
      • "id": "preroll-1",
      • "title": "Shift72 Presents",
      • "skip_policy": "must-view-once",
      • "has_watched": true,
      • "action": {
        }
      },
    • {
      • "id": "feature",
      • "title": "Citizen Kane",
      • "skip_policy": "allowed",
      • "has_watched": false,
      • "action": {
        }
      }
    ]
}

Request playtoken for current user

Request a playtoken for the current user.

This usually isn't necessary, as the Streams API will issue a playtoken for the user if they use an authtoken.

For regular users, no request parameters are accepted: you get what you get and you don't get upset.

For admin users, the request body can tailor the playtoken a little bit, such as requesting a different expiry, changing the delivery policy (e.g. to reduce DRM strictness to allow all quality levels to be viewed on browsers that would otherwise be limited to SD-ish), and changing whether telemetry should be sent.

Authorizations:
AuthTokenAdminAuthToken
path Parameters
slug
required
string
Example: /film/123

The slug to get token for, i.e. a film, film bonus, or TV episode.

Request Body schema: application/json
One of
exp
string <date-time>

Expiry timestamp for this playtoken. NOTE this is an ISO8601 timestamp, NOT UNIX TIME. At most 24 hours in future

uid
string or null

Optional: text to show as a watermark over the video. This is applied by players to help discourage or track down screen recording

olv
string or null
Default: "og"
Enum: "og" "apple"

Optional: the style of overlay to use. og (default) shows the watermark on the left edge of the video. apple displays text in a different corner for 20 seconds at a time

delpol
string or null
Enum: "urn:shift72" "urn:shift72.studio.1" "urn:shift72.studio.2"

The delivery policy to use. If not specified, the content or site default will be used.

  • urn:shift72: "Standard". Allows HD playback on all devices.
  • urn:shift72.studio.1: "Studio 1". Default for most clients. HDCP is required, and HD content is limited on less secure devices (e.g. Widevine browsers)
  • urn:shift72.studio.2: "Studio 2". Really restrictive. Will restrict playback on a lot of devices.

Responses

Response Schema: text/plain
string

Request samples

Content type
application/json
{ }

Response samples

Content type
text/plain
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwic2x1ZyI6Ii9maWxtLzI4MSIsInVzciI6Ilt1c2VyaWRdIiwiZXhwIjoxNTE2MjM5MDIyLCJpYXQiOjE1MTYyMzkwMjJ9.l9J2jy0LROLrDTcpqsjUDnOMRhGRs0jVLORxlBWjJbk

Issue playtoken for a Shift72 user

Request a playtoken on a user's behalf.

This is used for scenarios where you want to generate a playtoken using an API key for a particular user.

Authorizations:
ApiKey
path Parameters
userId
required
number
Example: 123456

The Shift72 user ID to issue this play token for

slug
required
string
Example: /film/123

The slug to get token for, i.e. a film, film bonus, or TV episode.

Request Body schema: application/json
exp
string <date-time>

Expiry timestamp for this playtoken. Defaults to 24 hours from now. NOTE this is an ISO8601 timestamp, NOT UNIX TIME. At most 24 hours in future.

uid
string or null

Text to show as a watermark over the video. This is applied by players to help discourage or track down screen recording"

olv
string or null
Default: "og"
Enum: "og" "apple"

The style of overlay to use. og (default) shows the watermark on the left edge of the video. apple displays text in a different corner for 20 seconds at a time

delpol
string or null
Enum: "urn:shift72" "urn:shift72.studio.1" "urn:shift72.studio.2"

The delivery policy to use. If not specified, the content or site default will be used.

  • urn:shift72: "Standard". Allows HD playback on all devices.
  • urn:shift72.studio.1: "Studio 1". Default for most clients. HDCP is required, and HD content is limited on less secure devices (e.g. Widevine browsers)
  • urn:shift72.studio.2: "Studio 2". Really restrictive. Will restrict playback on a lot of devices.

Responses

Response Schema: text/plain
string

Request samples

Content type
application/json
{
  • "exp": "2019-08-24T14:15:22Z",
  • "uid": "string",
  • "olv": "og",
  • "delpol": "urn:shift72"
}

Response samples

Content type
text/plain
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwic2x1ZyI6Ii9maWxtLzI4MSIsInVzciI6Ilt1c2VyaWRdIiwiZXhwIjoxNTE2MjM5MDIyLCJpYXQiOjE1MTYyMzkwMjJ9.l9J2jy0LROLrDTcpqsjUDnOMRhGRs0jVLORxlBWjJbk

Issue playtoken for an external user

Get a playtoken to allow an external user to watch content.

As these tokens are for external users, no ownership, device limits, or region checks will be done. You need to ensure that the recipient is allowed to play this content before giving them a token.

You must provide an expiry time for the token, no more than 24 hours in the future. After a token has expired, attempts to start playback or perform license checks will fail and a new token will be required.

Authorizations:
ApiKey
path Parameters
slug
required
string
Example: /film/123

The slug to get token for, i.e. a film, film bonus, or TV episode.

Request Body schema: application/json
usr
required
string

The user ID to associate with this playtoken. This can be a user ID in an external system.

exp
required
string <date-time>

Expiry timestamp for this playtoken. NOTE this is an ISO8601 timestamp, NOT UNIX TIME

uid
string or null

Optional: text to show as a watermark over the video. This is applied by players to help discourage or track down screen recording

olv
string or null
Default: "og"
Enum: "og" "apple"

Optional: the style of overlay to use. og (default) shows the watermark on the left edge of the video. apple displays text in a different corner for 20 seconds at a time

delpol
string or null
Enum: "urn:shift72" "urn:shift72.studio.1" "urn:shift72.studio.2"

Optional: The delivery policy to use. If not specified, the content or site default will be used.

  • urn:shift72: "Standard". Allows HD playback on all devices.
  • urn:shift72.studio.1: "Studio 1". Default for most clients. HDCP is required, and HD content is limited on less secure devices (e.g. Widevine browsers)
  • urn:shift72.studio.2: "Studio 2". Really restrictive. Will restrict playback on a lot of devices.
additional property
string or boolean or number

Additional claims to include in the playtoken. These can be JSON strings, booleans or numbers. It's strongly recommended that you add a vendor prefix to any custom claims so that they don't conflict with any Shift72 issued claims.

Any of
string

Additional claims to include in the playtoken. These can be JSON strings, booleans or numbers. It's strongly recommended that you add a vendor prefix to any custom claims so that they don't conflict with any Shift72 issued claims.

Responses

Response Schema: text/plain
string

Request samples

Content type
application/json
{
  • "usr": "string",
  • "exp": "2019-08-24T14:15:22Z",
  • "uid": "string",
  • "olv": "og",
  • "delpol": "urn:shift72",
  • "property1": "string",
  • "property2": "string"
}

Response samples

Content type
text/plain
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwic2x1ZyI6Ii9maWxtLzI4MSIsInVzciI6Ilt1c2VyaWRdIiwiZXhwIjoxNTE2MjM5MDIyLCJpYXQiOjE1MTYyMzkwMjJ9.l9J2jy0LROLrDTcpqsjUDnOMRhGRs0jVLORxlBWjJbk

User Library

A user's library is the TVOD content they've bought (e.g. rentals or EST purchases).

The library can also contain plan content if the plan has been flagged as a "library plan". This is useful for hybrid models, such as festival passes where there may be a small number of films that should appear similar to other rentals.

For SVOD sites with large content libraries it's more appropriate for users to discover plan content other ways -- including the full catalogue in their library view would be overwhelming!

Get my user library

Gets the library content and plans for the current user

Authorizations:
AuthToken
query Parameters
location
string

override the users location, used for plan-as-library content

Responses

Response Schema: application/json
Array of objects (LibraryItem)

The media items a user owns. This is usually stuff they've rented or bought. Plan content can appear here too, if the plan has been set up as a Library Plan.

Recent expired rentals appear in the library too. These can be identified by is_expired: true or checking the expiry date is in the past.

The same item can appear multiple times -- e.g. if the user rents an item, and it later is added via a Library Plan. If the same content is in multiple Library Plans, then there will be one library item for each of the plans.

Sorting: the library items are sorted so that watchable items will always appear before expired content. There are some heuristics applied so that the most relevant items are near the top of the list (e.g. expiring soon)

Array
ownership
string
Enum: "rent" "buy" "plan"

How you own the content. Plan content only appears here if the plan has been flagged as a library plan

type
string
Enum: "film" "film-bonus" "tv-season" "tv-episode" "tv-season-bonus"
slug
string
title
string
available_from
string

ISO8601 timestamp The start of the content's availability window. The content cannot be watched before this time.

available_to
string

ISO8601 timestamp The end of the content's availability window. The content cannot be watched after this time. This is a hard cutoff enforced by the license server.

expiry
string

ISO8601 timestamp. The rental expiry. Once a watch window is triggered the expiry will be set to watch_window_end, shortening or lengthening the original rental period.

is_expired
boolean

Is it past the expiry date? This is calculated from the expiry field based on server time.

watch_window_duration
number

Duration of the watch window for a rental, in minutes. Once you start playing the content, you will have this long to finish.

watch_window_start
string

If rental watch window has been triggered, this is when it started. ISO8601 UTC timestamp, or null

watch_window_end
string

If rental watch window has been triggered, this is when it will end. ISO8601 UTC timestamp or null. You must finish watching the content by this time.

plan_id
number

Plan content only. This is the plan ID that granted it

object

Where were you up to? This is based off playback telemetry and only accurate to about 30 seconds.

play_position
number

The play position, in seconds

last_played_at
string

When was telemetry last received?

length
number

How long is the content in seconds. Note: this is based on player-reported duration and can be inaccurate in some situations!

completed
boolean

Have you watched most of it? (currently, >80%). This is used to determine if a player should just start over

Array of objects

The plans this user has access to. These could be subscriptions, one-off plans (e.g. passes) or plans that were automatically assigned on sign-up or via an integration.

Array
plan_id
number
expiry
string

When does the user's access to this plan expire? Note: if this plan is a subscription, this date will be extended when the next invoice is paid.

Response samples

Content type
application/json
{
  • "items": [
    • {
      • "ownership": "rent",
      • "type": "film",
      • "slug": "string",
      • "title": "string",
      • "available_from": "string",
      • "available_to": "string",
      • "expiry": "string",
      • "is_expired": true,
      • "watch_window_duration": 0,
      • "watch_window_start": "string",
      • "watch_window_end": "string",
      • "plan_id": 0,
      • "playback_progress": {
        }
      }
    ],
  • "plans": [
    • {
      • "plan_id": 0,
      • "expiry": "string"
      }
    ]
}

Get a user library by User ID

A user can request to see their own library, or a privileged user can view others libraries.

Authorizations:
AuthTokenAdminAuthTokenApiKey
path Parameters
user_id
required
integer <int32>

User ID

query Parameters
location
string

override the users location for plan-as-library content

Responses

Response Schema: application/json
Array of objects (LibraryItem)

The media items a user owns. This is usually stuff they've rented or bought. Plan content can appear here too, if the plan has been set up as a Library Plan.

Recent expired rentals appear in the library too. These can be identified by is_expired: true or checking the expiry date is in the past.

The same item can appear multiple times -- e.g. if the user rents an item, and it later is added via a Library Plan. If the same content is in multiple Library Plans, then there will be one library item for each of the plans.

Sorting: the library items are sorted so that watchable items will always appear before expired content. There are some heuristics applied so that the most relevant items are near the top of the list (e.g. expiring soon)

Array
ownership
string
Enum: "rent" "buy" "plan"

How you own the content. Plan content only appears here if the plan has been flagged as a library plan

type
string
Enum: "film" "film-bonus" "tv-season" "tv-episode" "tv-season-bonus"
slug
string
title
string
available_from
string

ISO8601 timestamp The start of the content's availability window. The content cannot be watched before this time.

available_to
string

ISO8601 timestamp The end of the content's availability window. The content cannot be watched after this time. This is a hard cutoff enforced by the license server.

expiry
string

ISO8601 timestamp. The rental expiry. Once a watch window is triggered the expiry will be set to watch_window_end, shortening or lengthening the original rental period.

is_expired
boolean

Is it past the expiry date? This is calculated from the expiry field based on server time.

watch_window_duration
number

Duration of the watch window for a rental, in minutes. Once you start playing the content, you will have this long to finish.

watch_window_start
string

If rental watch window has been triggered, this is when it started. ISO8601 UTC timestamp, or null

watch_window_end
string

If rental watch window has been triggered, this is when it will end. ISO8601 UTC timestamp or null. You must finish watching the content by this time.

plan_id
number

Plan content only. This is the plan ID that granted it

object

Where were you up to? This is based off playback telemetry and only accurate to about 30 seconds.

play_position
number

The play position, in seconds

last_played_at
string

When was telemetry last received?

length
number

How long is the content in seconds. Note: this is based on player-reported duration and can be inaccurate in some situations!

completed
boolean

Have you watched most of it? (currently, >80%). This is used to determine if a player should just start over

Array of objects

The plans this user has access to. These could be subscriptions, one-off plans (e.g. passes) or plans that were automatically assigned on sign-up or via an integration.

Array
plan_id
number
expiry
string

When does the user's access to this plan expire? Note: if this plan is a subscription, this date will be extended when the next invoice is paid.

Response samples

Content type
application/json
{
  • "items": [
    • {
      • "ownership": "rent",
      • "type": "film",
      • "slug": "string",
      • "title": "string",
      • "available_from": "string",
      • "available_to": "string",
      • "expiry": "string",
      • "is_expired": true,
      • "watch_window_duration": 0,
      • "watch_window_start": "string",
      • "watch_window_end": "string",
      • "plan_id": 0,
      • "playback_progress": {
        }
      }
    ],
  • "plans": [
    • {
      • "plan_id": 0,
      • "expiry": "string"
      }
    ]
}