Skip to end of metadata
Go to start of metadata

Table of Contents

Overview of deep linking

Deep linking lets other parts of the system launch a particular piece of video content using parameters passed to the channel at launch time, rather than launching the home page for the channel. 

To enable the deep link, you must identify each piece of content in your channel with a unique string, a contentid. You can define the contentid with any valid ASCII string, as long as it is less than 255 characters in length. 

You must also associate a valid Roku-defined mediaType with each contentid. The mediaType value tells the Roku platform how to handle the content item. Once defined, this pair of identifiers, contentid and mediaType, must not be changed or the content item cannot be found by the system.

To pass certification all public Roku channels with video content are required to respond correctly to deep link queries. See Certification about the deep linking requirements that must be met.

Constructing a contentid

A contentid is a unique identifier associated with a single piece of content. You define the layout of the contentids in your channel. These IDs are required so Roku can confirm that the content associated with a specific contentid launches the deep link correctly.

A contentid is:

  • an opaque string - The format of a contentid is defined by your channel, not Roku, and the contentid is opaque to the Roku system. You define your own naming convention, but it is important that you maintain absolute consistency with this naming convention.

  • a single string - The contentid must be no more than 255 characters long.

  • an immutable value to identify a specific piece of content - The ID must identify the same content for all time.

  • URL encoded - The contentid must be URL encoded.

  • a command-line argument - The contentid must be passable as a command-line argument in a cURL command.

contentid could be as simple as a number or a name. It could also be the URL for the specific content item.

The contentid can consist of several segments that are used by the channel itself to identify the content item. To separate a contentid into segments, you can use vertical bars. The bars are also counted in the 255 character limit.

This example of an episode's contentid shows the segments separated by vertical bars: theSeries=XYZ|Season=12|contentItem=456.

In this example, each segment, such as theSeries=XYZ, has a meaning to your channel, but not to Roku, since a contentid is opaque to Roku's system. You can construct the contentid to contain whatever you need to identify the episode properly, such as the TV series it is from and the season it is in, as well as the identifier for the specific episode.

If you are participating in Roku Search, the PlayId in the XML feed must match the contentid for the same content item. This is because the PlayId gets passed into your channel as a contentid.

Choosing a mediaType

A mediaType is a value used to categorize each type of content available on your channel. See MediaType behavior for more information.

NOTE: To pass certification, you must submit one sample deep link for each mediaType value used in your channel, along with a matching sample contentid. See Submitting deep linking content for certification.

Roku has defined the mediaType values as:

  • movie - a long-form film or movie
  • series - a set of related TV shows consisting of episodes or seasons
  • season - as part of a series, a season is a single set of related TV shows consisting of episodes
  • episode - a single content item
  • short-form - a standalone content item of 15 minutes or less

  • special - a single content item that does not fit into any other mediaType
  • live - a live feed. *NOTE: You are not required to support deep linking to live feeds unless your channel has only live feeds.

Deep linking behavior

To ensure a standard user experience across the Roku platform, Roku has defined a set of behaviors that a channel should exhibit when responding to a deep link request

  • Support mediaType values to categorize your content: Your channel must support as many or as few mediaType values as is necessary to accurately categorize all the content in your channel. If your channel has a mix of TV shows and feature-length films, you must support mediaType values “movie,” “series,” “season,” and “episode”. If instead, your channel has many live feeds available at a time, use the “live” mediaType. Channels that include only a single live stream have only one possible behavior, but still must implement deep linking.

  • Handle invalid deep links: Channels must handle invalid deep links gracefully and must not cause a crash. When deep linking with an invalid mediaType or contentid, the link must be set to return to the home screen of the channel.

  • Handle unauthenticated users: Your channel must handle unauthenticated users who are deep linking into your channel or launching your channel for the first time. For example, this can happen when a user is deep linking into your channel from an ad or by using Roku Search for the first time. If the channel is uninstalled, Roku OS will prompt the user to install the channel before continuing with the deep link. Your code must route the user to the appropriate screen and then, when the user is authenticated, fulfill the deep link.

  • Display paywall if needed: If your channel requires a purchase prior to launching, you are allowed to display a purchase screen before the user sees the content.

  • Support a default profile If your service supports profiles, you must set a default profile for a movie, episode or series. Do not force a customer to choose a profile prior to playing a movie or episode. This is because Roku does not allow any screen (except a purchase or authentication screen) to be presented to the customer between choosing a movie or episode and playing it. Which profile you select as the default is your decision, but Roku recommends the last profile the customer used.

  • Do not deep link into other channels: Channel must not deep link into 3rd-party channels.

MediaType behavior

When a deep link is requested, the channel's behavior depends on the mediaType value for the content. When content is launched with a deep link, it should start playing immediately except for the mediaType season. For season the user should be taken to an episodic picker screen. 

mediaTypecontentid to LaunchRequired Behavior on Launch
moviemovie's contentidLaunch directly into playback.
episodeepisode's contentidLaunch directly into playback.
episode's contentid*

Launch directly into playback, but determining which specific episode to launch or where in the episode to start playback is defined by your channel. See Series behavior for guidance.

*NOTE: There is no "series" contentid. Series is only a mediaType that is identified in the contentid for each episode in the series.


item's contentid

Launch directly into playback.


item's contentid

Launch directly into playback.


episodic picker screen for the season with the selected episode highlighted*

Launch episodic picker screen. Highlight the episode identified by the contentid.

An episodic picker screen displays episodes organized by season.

*NOTE: There is no "season" contentid. Season is only a mediaType that is identified in the contentid for each episode in the season.

livelive feed's contentid to launchLaunch directly into playback.

Series behavior

When a channel is passed a series mediaType, it should receive an episode's contentid that identifies the content to be played and also the series it is in.

Remember: There is no "series" contentid. "series" is only a mediaType.

Once the series is identified from the episode's contentid, you should start playback based on the user's past viewership of the series and on the type of series it is. There are many different types of series: Serialized TV shows usually watched in sequence, sitcoms, nightly news, talk shows, etc., so there are several ways your channel could respond to a series mediaType.

Below are Roku’s recommended deep linking behavior for series:

Type of SeriesDefinitionRecommended Behavior
Followed TV series

A series that the user has already started watching in the past.

Using the user’s bookmarked position, bring the user to the next episode in the series from where they last watched. Or, if they did not watch the last episode to completion, drop them into the moment where they last left off.
Unwatched TV seriesA cataloged series that the user has not yet watched on your service.Drop the user directly into video playback at the beginning of Season 1 Episode 1. 
Daily or weekly showsA regularly-occurring show that does not necessarily need to be watched in chronological order. News broadcasts, talk shows, sports podcasts, or religious sermons are examples of this type of series.Play the most recent episode of the series.

Implementing deep linking in a channel

The basic steps to implement deep linking are:

Step 1: Modify the channel's main.brs file.

Step 2: Test that args[contentid] and args[MediaType] are valid. 

Step 3: Add code for launching.

Step 4: For a series, implement bookmarking.

Step 5: Use roInputEvent.

Step 6: Test using the Deep Linking Tester tool. 

Step 1: Modify the channel's main.brs

Modify your channel to handle deep linking by editing your channel's main() or runuserinterface(). Add one argument to the function and name it args

Function Main (args as Dynamic) as Void

Parse the associative array passed in to your channel's main entry point — usually main() in the main.brs file. The two keys in the associate array that will be defined for the content item are the pair of deep link parameters, contentid and mediaType:


DescriptionPossible Values
contentidUnique identifier you define for a specific piece of content.

Any ASCII String < 255 characters long

mediaTypeIdentifies the type of media to give context to the type of contentID passed.

"series", "season", "episode", "movie", "short-form", "special" and "live"

correlatorOptional third argument sent by ads when ads launch the channel.Any ASCII String < 255 characters long

Modify the Main() function for your channel to accept the two deep linking parameters by adding a variable. This variable can be any arbitrary name. In this example, the variable name args is used. For a complete example, see Example.

Step 2: Add a test for args[contentid] and args[MediaType]

Add code that tests args[contentid] and args[MediaType] are not invalid. If they have values, the channel is being deep linked to. Otherwise, do a normal channel launch.

if (args.mediaType <> invalid) and (args.contentid <> invalid)

Step 3: Add code for launching

Add code to launch the appropriate screen, unless your contentid is invalid. If it is invalid, display an error message and launch the channel normally. See the Example.

Step 4: Implement bookmarking for a series 

Step 5: Use roInputEvent to catch deep links while the channel is running

The roInput component enables deep linking without re-launching your channel.  When the firmware resolves a voice input request (for example, “Play Game of Thrones” while your channel is in the foreground), your application 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 a 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. 

Step 6. Test using Deep Linking Tester

Test the channel meets the requirements listed on this page as well as those listed on Certification. You can use the Deep Linking Tester Tool and the associated Roku Deep Linking Tester channel. See Testing deep linking. Another tool to play content using a deep link is to use the External Control API.

Example main.brs file

This is an example of a main.brs file for a basic channel that requires no authentication:

sub Main()
    print "in showChannelSGScreen"
    'Indicate this is a Roku SceneGraph application'
    screen = CreateObject("roSGScreen")
    m.port = CreateObject("roMessagePort")
    if type(msg) = "roInputEvent"
args = msg.GetInfo()
contentid = args.contentid 
    'Create a scene and load /components/yourchannel.xml'
    scene = screen.CreateScene("Hello Channel")
    if (args.mediaType <> invalid) and (args.contentid <> invalid)
   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
  'pop an error message and launch channel normally.
                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
  'pop an error message and launch channel normally.
                end if
        'deep linking issue such as a contentid not matching any content in the partner's catalog
        'display an appropriate error message for the user
     end if

     'launch channel normally
end if
        msg = wait(0, m.port)
        msgType = type(msg)
        if msgType = "roSGScreenEvent"
            if msg.isScreenClosed() then return
        end if
        if type(msg) = "roInputEvent"
args = msg.GetInfo()
contentid = args.contentid
            if msg.IsInput()
             info = msg.GetInfo()
         end if
   end if
end while

Sample channel

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

Testing deep linking

You can test your deep links using cURL or by using the Roku Deep Linking Tester tool.

Using the Roku Deep Linking Tester

The Roku Deep Linking Tester tool allows you to do a test of your deep links prior to it going through the testing certification process.

NOTE: Roku highly recommends you use this tool as deep links must work for your channel to pass certification.

This tool requires the same deep linking attributes as defined for cURL, but provides a UI plus other features to help, such as saving deep linking parameters to reuse.

  1. Open the Deep Linking Tester tool in your browser. 
  2. Your Roku device and your PC should be connected to the same sub-network.
  3. Start the channel on the Roku device.
  4. Enter all required information in the Deep Linking Tester tool.
  5. Click "SEND".
  6. Verify the content plays immediately.

Using cURL for testing

Optionally, deep linking can be tested using cURL and the External Control Protocol (ECP). Using cURL for testing allows you to pass custom keys, such as a "correlator" key, and test them. However, passing a test using cURL does not indicate your deep link has passed; you should still run the Deep Linking Tester tool.

You can trigger deep linking by doing an HTTP post to port 8060 on your Roku device.

The contentid must be URL encoded. The form of the cURL is:

The following  attributes are required:

IP AddressIP address of the Roku device with the channel sideloaded or installed192.168.1.114
Port8060 is used for ECP commands8060
ECP commandlaunch (additional ECP commands can be found here)launch
Channel ID
  • If the channel is side-loaded, use dev
  • If the channel is an installed public or non-certified channel, the channel ID can be found on the Developer Dashboard on the preview page for your particular channel or 
  • enter http://<roku-device-ip-address>:8060/query/apps in a web browser to see a list of installed channels (and the Channel IDs) on the Roku device.
mediaTypethe mediaType of the content to deep link tomovie
contentidthe contentid of the content to deep link to1234

The following example shows the cURL for a side-loaded channel with a mediaType of movie and a contentid of 1234:

Submitting deep linking content for certification 

Prior to submitting your channel, ensure all requirements listed on Certification have been met.

You submit your channel for certification using Developer Dashboard. Every type of mediaType value used in your channel requires a sample when submitting the channel for certification. For example, if you have both movies and live feeds, you would need two sample values, "mediaType=movie" and "mediaType=live".

Each sample consists of a pair of deep link parameters, the mediaType value and a matching contentid. These parameter pairs are used by Roku to certify that your channel is responding with the correct behavior for each type of content in your channel. For instance, if your channel has both movies and live feeds, you need to provide two sets of parameter pairs.

This pair should be provided in Developer Dashboard on the Support Information page for the channel in the field "Test Accounts & Deep Linking Parameters". You can enter your deep linking content by pasting in your mediaType and contentid, such as this movie's deep linking parameter pair:

contentid = "MyGroup=abc|ProductID=xyz|itemID=456"

mediaType = "movie"

  • No labels