Roku SDK Documentation : Deep Linking

Table of content


Deep linking enables users to get to your content faster from the Roku UI via Roku's content discovery features (for example, Roku Search and Roku home screen banners). With deep linking, your channel is launched into playback or content springboards directly from the Roku UI. For example, when a movie is selected from Roku Search, playback starts immediately without any channel navigation. This functionality enables you to leverage Roku's content discovery features in order to drive users to your channel and increase engagement. 

Public channels with video content must implement deep linking to pass certification. Roku Search integration is required for deep linking into content and screens in your channel.

Overview

The following diagram demonstrates how deep linking from Roku Search works. When content is selected, the contentId and mediaType are passed as query string parameters to the channel. The channel accepts and validates the deep linking parameters and identifies the appropriate launch behavior, which is determined by the mediaType. In this example, contentId "loganLucky123" corresponds to the film "Logan Lucky", and the mediaType is "movie". The "movie" mediaType requires the channel to launch directly into playback (see MediaType behavior for more information on the launch behavior required for different mediaTypes).

To implement deep linking in a channel, follow these steps:

  1. Classify video content. Assign contentIds to the content in your channel and categorize their Roku-supported mediaTypes. 

  2. Scope required deep linking behavior.  Identify the logic required for handling deep link requests based on the content in your channel and corresponding Roku-supported mediaTypes (per Roku requirements).

  3. Implement required deep linking behavior.  Program the channel so it accepts and validates the deep linking parameters and launches the appropriate user experience.

  4. Test deep linking in the channel.  Verify that the channel handles deep links correctly using the Roku Deep Linking Tester or External Control Protocol (ECP) commands sent via cURL.

  5. Submit deep link samples for certification. Submit sample deep link details (title, contentid, and mediaType) in the Developer Dashboard for each mediaType in your channel.

Classifying video content

To classify your video content, you create content IDs in your channel feed that enable you to uniquely and consistently identify the content. If your channel is participating in Roku Search, you specify the Roku-supported mediaType of the content in the search feed. Once you define the contentId and mediaType, you cannot change them or the Roku platform may not be able to find the content.  

ContentId

A contentId is a URL-encoded ASCII string (maximum of 255 characters) that uniquely identifies content. You define the contentId in your channel feed and in your Roku Search feed (if your channel is participating in Roku Search). You can format the contentId using whatever naming convention best suits your business needs. For example, the contentId may be name, number, or URL, or it may contain multiple pipe-separated key-value pairs that self-describe the content (for example, series=myAwesomeShow|Season=1|Episode=1). For content that is part of a series, the contentId should identify both the season and the episode as demonstrated in the previous example. The naming convention that you do use for the contentId must be applied consistently. ContentIds are immutable, which means that they must stay the same once they have been defined.

If a channel is participating in Roku Search, the contentid in the Roku Search feed (PlayID) must map to the contentid in your channel for the same content. It is therefore important to keep the Roku Search feed synchronized with the channel's content feed.

For episodic content, Roku Search only recognizes the episode contentid. An episode's contentid therefore must remain consistent, regardless if a deep link launches the episode or an episodic picker screen. These different deep link behaviors are determined solely by the mediaType. Separate contentIDs used to identify the season and series of the same content item are therefore ignored.

MediaType

A mediaType is a string that categorizes content. You must accurately classify the mediaType for your content in your Roku Search feed. This is particularly important because channels that include content with the “movie,” “series,” “season,” and “episode” mediaTypes are eligible to participate in Roku Search. Each mediaType is described as follows: 

mediaTypeDescription
movieMovie or long-form film (over 15 minutes).
episodeSingle content item (an episode of a TV show, for example).
seasonAs part of a series, single set of related TV episodes consisting of episodes.
series

Set of related serialized episodes, consisting of episodes and possibly seasons. Includes TV shows and daily/weekly ongoing shows.

The behavior of the series mediaType relates to the use of smart bookmarks, which launch episodic content based on the user's viewership.
specialOne-time TV programs that are not part of a series, or content that does not fit into any other mediaType category (for example, music, artists, sporting events, non-episodic news specials).
short-form

Standalone content that is 15 minutes or less that is not a movie or TV show (for example, movie trailers, news clips, comedy clips, food reviews, or other clips).

Channels containing only short-form items are exempt from deep linking certification requirements.

live

Live linear stream

Live linear streams and replays of live broadcast streams are exempt from deep linking certification requirements.

Scoping deep linking requirements

Before programming your channel to handle deep links, you need to understand the required behavior for launching content based on the different mediaTypes. In addition, there are general requirements that your channel should follow when responding to deep link requests. Understanding and adhering to these deep linking requirements provides a standard user experience across the Roku platform and helps ensure that your channel passes certification.

MediaType behavior

When a deep link is sent to your channel, it will include contentId and a mediaType. The contentId specifies which content to play, and the mediaType tells your channel how it must handle the launching of the content item. The following table summarizes the required launch behavior for each mediaType:

mediaType in Deep Link

Required Launch Behavior
moviePlay the movie identified by the contentId. Use bookmarks to determine the playback position.
episodePlay the episode identified by the contentId. Use bookmarks to determine the playback position.
seasonLaunch an episodic picker screen that displays episodes organized by season; highlight the first episode of the selected season.

series

Launch an episode into direct playback using smart bookmarks. A smart bookmark determines the episode to be launched and the playback position based on the type of series, whether the user has previously watched the series, and whether they completed the last watched episode. The different types of series and their recommended smart bookmark behavior are as follows:

  • Followed TV (a series that the user has already started watching in the past): Use bookmarks to determine whether the user completed the previously watched episode. If they completed the last episode, launch the next episode in the series. If they did not, launch the episode where the user stopped watching.

  • Unwatched TV (a cataloged series that the user has not yet watched on your service): launch playback at the beginning of S1E1.

  • Daily/weekly shows (a regularly-occurring show that does not necessarily need to be watched in chronological order; for example, news broadcasts, talk shows, sports podcasts, and religious sermons): Launch the most recent episode in the series.
short-formPlay the short-form item identified by the contentId.
specialPlay the TV special identified by the contentId.  
livePlay the live linear stream identified by the contentId.

A deep link for a single content item will always have the same contentId; however, the mediaType may vary based on the Roku content discovery feature sending the deep link. Your channel therefore must be designed to execute the specified behavior required by each mediaType that could be sent to your channel.

For example, if your channel only includes short video clips, the channel only needs to handle the "short-form" mediaType. Similarly, if your channel contains a single live stream, the channel only needs to handle the "live" mediaType. But if your channel includes the last three seasons of a television episode, your channel needs to handle the "episode", "season", and "series" mediaTypes to be able to respond to deep links sent from Roku Search, Roku voice search, and on-device ads.

General channel behavior

Your channel should exhibit the following behaviors when responding to a deep link requests:

  • Handle invalid deep links: If a deep link has an invalid contentid or mediaType, launch the channel's home screen. 

  • Handle unauthenticated users: If an unauthenticated user is launching or deep linking into your channel for the first time, route the user to the appropriate authentication flow and then process the deep link request after the user has been authenticated. This can happen when a user deep links into your channel via Roku Search or an on-device ad but the channel is not installed. In this case, the firmware will prompt the user to install the channel before continuing with the deep link. 

  • Display a paywall (if needed): If your channel requires a purchase prior to launching, the channel may display a purchase screen before the letting the user view deep linked content.

  • Support a default profile If your channel supports different profiles, set the last one used as the default for a movie, episode or series. A channel may not display a profile selection screen, or any other screen other than one for purchases or authentication, between the selection and playback of a movie or episode. Do not use any profiles linked to children as the default. 

  • Avoid deep linking into other channels: A channel may not deep link into third-party channels.

Updating the channel

To integrate deep linking in your channel, follow these steps:

  1. Accept the deep linking parameters (contentId and mediaType) being passed to it. To do this, add an associativeArray argument to your channel's main entry point, which is typically either the main() or runuserinterface() function. The name of the argument is arbitrary; for the example in this section, it is args.

    Function Main (args as Dynamic) as Void


  2. Verify that the contentId and mediaType have valid values. To do this, parse the associativeArray received by your channel using the contentId and mediaType key names, and then check the values. 

    if (args.mediaType <> invalid) and (args.contentId <> invalid)
  3. If the contentId and mediaType are valid, launch the specified content item using the appropriate launch behavior for the mediaType. If either the contentId or mediaType are invalid, launch the channel home page.  

    if (args.mediaType = "movie" or args.mediaType = "episode" or args.mediaType = "short-form" or args.mediaType = "series" or args.mediaType = "special")
           if valid_contentId(contentId) ' You define this function in your back-end
               'play content directly, starting at last bookmarked position
           else
               'pop an error message and launch channel home page.
           end if
    else if (args.mediaType = “season”)
           if valid_contentId(contentId) ' You define this function in your back-end
               'display an episodic picker screen with the episode of the contentId selected 
           else
               'pop an error message and launch channel home page.
           end if
    else
            'deep linking issue such as contentId not matching any content in the partner's catalog
            'display an appropriate error message for the user and launch home page.
    end if
    
    ...
  4. Use roInputEvent to check whether a deep link has been passed into the channel while your channel is running. This enables your channel to deep link into content without re-launching your channel. The supports_input_launch attribute (supports_input_launch=1) must be added to the channel manifest for this functionality to work.

    For example, when a voice input request is received (for example, “Play Game of Thrones” while your channel is in the foreground), your channel can send the deep link parameters through the roInputEvent—instead of re-launching your channel with the parameters. A message loop that listens for incoming events is typically used. If that event is an roInputEvent, an action is taken based on the input. If the input is content ID, the channel typically finds the stream URL and metadata for that content ID, and then cues and plays the content. 

    See Sample channel to download and install a sample channel that demonstrates how to use roInputEvent to handle deep links while your channel is running. 

    ...
    screen = CreateObject("roSGScreen")
    m.port = CreateObject("roMessagePort")
    screen.setMessagePort(m.port)
    ...
    while(true)
            msg = wait(0, m.port)
            msgType = type(msg)
            if msgType = "roSGScreenEvent"
                if msg.isScreenClosed() then return
            end if
            if type(msg) = "roInputEvent"
                if msg.IsInput()
                    info = msg.GetInfo()
    				if info.DoesExist("mediaType") and info.DoesExist("contentID")
    					mediaType = info.mediaType
    					contentId = info.contentID
    				end if
                end if
            end if
    end while

Testing deep linking in the channel

You can test whether deep linking is working correctly in your channel using either the Roku Deep Linker Tester and the associated Roku Deep Linking Tester channel or ECP commands sent via cURL. Both methods enable you to test deep linking into content when launching a channel; however, to test deep linking while your channel is running, you must use ECP commands.  

Deep links must work for your channel to pass certification; therefore, it is recommended you do this testing. 

Using the Roku Deep Linking Tester

The Roku Deep Linking Tester provides a UI for configuring, saving, import/exporting, and executing deep linking test cases. To use the tool for testing deep linking in your channel, follow these steps:

  1. Verify that your Roku device and computer are connected to the same sub-network.

  2. Open the Roku Deep Linking Tester (https://devtools.web.roku.com/DeepLinkingTester). Optionally, you can download the Mac, PC, or Linux version of the tool onto your desktop. This saves you the step of having to manually enter the ID and name of the channel to be tested. 



  3. Optionally, install the associated Roku Deep Linking Tester channel (https://my.roku.com/account/add?channel=KX3UPK) on your Roku device to test deep linking directly without using the tool. You can create test cases with the tool and then transfer them to your device. This is particularly useful if you want to test on the device, but items have long contentids that may be cumbersome to enter with the Roku remote control.
     
  4. If you are using the Web tool or desktop channel, add your device.

  5. If you are using the Web tool, enter the ID and name of the channel to be tested. If you are using the desktop channel, select the channel to be tested. 

  6. Add one or more test cases. To do this, click the Add a Test Case icon, enter a name for the test case, and then save the test case. Enter the contentId and mediaType for the test case; these will automatically be saved after you enter them. 

  7. Click Send, and verify that direct playback of the content starts immediately. 

Using ECP commands for testing deep linking

You can test deep linking in a channel by sending ECP commands via cURL to your Roku device. This enables you to test deep linking into content when your channel is launched and while it also running. You can also use this method to pass custom keys, such as a "correlator" key, and test them.  

To test deep linking using ECP/cURL, send an co HTTP POST request to port 8060 on your Roku device using the following syntax:

http://<roku-device-ip-address>:8060/<EcpCommand>/<channelId>?contentId=<contentIdValue>&mediaType=<mediaTypeValue>

The following attributes are required:

ParameterDescriptionExample
EcpCommand

Enter one of the following commands:

  • launch. Test deep linking into content when channel is launched.
  • install. Test deep linking into content while channel is running.
launch
channelId

Enter one of the following:

  • dev. Sideloaded channel.
  • <id>. Public or non-certified channels. To find your channel ID, use the preview page on the Developer Dashboard.

To get a list of all the installed channels and their channel IDs on your Roku device, you can enter http://<roku-device-ip-address>:8060/query/apps in a web browser. An XML file with all the channel (app) IDs on the device is generated.

dev
contentIdValueEnter the contentId of the content item to be used for the deep link test.1234
mediaTypeValueEnter the mediaType of the content item to be used for the deep link test. See mediaType for the possible values.movie

The following examples show how to send ECP commands via cURL HTTP POST requests. The examples are based on a side-loaded channel with contentId of 1234 and a mediaType of movie. The launch command is used to test deep linking into content when the channel is launched; the input command is used for when the channel is already running. When sending the input command, the channel (dev) is not required

curl -d '' 'http://192.168.1.114:8060/launch/dev?contentId=1234&mediaType=movie'
curl -d '' 'http://192.168.1.114:8060/input?contentId=1234&mediaType=movie'

To test deep links on your production channel, replace "dev" with your channel ID (a channel ID of 50000 is used in the following example). Because the input command does not require the channel ID, the same command can be used for testing in development and production. 

curl -d '' 'http://192.168.1.114:8060/launch/50000?contentId=1234&mediaType=movie'
curl -d '' 'http://192.168.1.114:8060/input?contentId=1234&mediaType=movie'

Submitting deep linking samples for certification

As part of the channel certification process, you must use the Developer Dashboard to submit sample deep linking parameters for your channel. This enables Roku to certify that your channel is responding with the correct behavior for the different types of content in your channel.

To submit deep links for certification, follow these steps:

  1. Verify that your channel meets all certification requirements.

  2. Open the Developer Dashboard and click Manage My Channels. Click your channel, and then select Support Information from the list on the right.



  3. In the Test Accounts & Deep Linking Parameters box, enter sample deep linking parameters for each mediaType included in your channel. You need to provide samples for each mediaType in your channel. For example, if your channel has both movies and live feeds, you need to provide two sets of deep link parameters. The following example demonstrates how you could provide the deep linking parameters for a channel that has three different mediaTypes.

    contentId="myMovieName1234"
    mediaType = "movie"
    
    contentId="myEpisodeName5678"
    mediaType = "episode"
    
    contentId="series=mySeries|season=1|episode=myEpisode"
    mediaType = "series"

Sample channel

You can download and install a sample channel that demonstrates how to launch content with deep links. It provides content that you can use to test deep linking via ECP commands sent via cURL. It shows you how you can design your channel to deep link into content when both launching a channel and while the channel is already running.


Attachments: