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 content using parameters passed to the channel at launch time, rather than launching the home page for the channel.  

When you created your channel, you defined meta-data for your channel and created a contentID for each of your content items.

To pass certification all public Roku channels with video content are required to respond correctly to deep link queries.

To implement deep linking, you parse the associative array passed in to your channel's main entry point — usually main() in the main.brs file.

There are two keys in this associate array that will be defined for the channel to be deep linked to:


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"

Basic steps to implement deep linking

Step 1: Modify your channel to handle deep linking by editing your channel's main() or runuserinterface(). (See the section “Implementing deep linking in a channel” below.) Add one argument to the function, name it "args".

Step 2: Test args[contentID] and args[MediaType] <> invalid. If they have values, then the channel is being deep linked too. Otherwise, do a normal channel launch.

Step 3: Depending on the mediaType parameter, your channel should play the content immediately or should allow the user to choose which episode to play. For a movie, episode, series, short-form, special or live stream you must playback the specified piece of content immediately. For a TV season, users must choose an episode from the season's episode picker screen.

Step 4:  If you are implementing "series", then implement bookmarking using an event handler. This is a timer that runs while you are playing content and periodically saves the location to your back-end.

Step 5: You can test your channel by side-loading it and using the External Control API or you can use the Deep Linking Tester Tool and the associated Roku Deep Linking Tester channel.

What is a contentID?

A contentID is a unique ID that is associated with a single piece of content as defined for your channel using the attributes on Content Meta-Data. It is required so Roku can confirm that the content associated with a specific ID launches the deep link correctly. 

Roku Search is not required for channel certification but if you do implement it, for each piece of content use the same contentID you use for deep linking. In the XML feed Roku Search uses, a contentID is identified with the tag playID but it should use the same string as contentID and identify the same piece of content.

The following example contentID string shows how the contentID can be split into segments if that helps you track the specific item:

ContentID = "MyGroup=abc|ProductID=1234|groupID=456"

Notice the contentID often consists of several other IDs that are used by the channel itself to identify the movie.

Requirements for a contentID

  • The format of a contentID is defined by the partner or content provider. Roku treats the contentID as an opaque string, meaning that we allow you to define your own naming convention. However, it is important that you maintain absolute consistency with this naming convention.

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

  • The contentID is a single string and is no more than 255 characters in length.

  • The contentID must be URL encoded and cannot contain “&” characters.

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

What is a mediaType?

mediaType is used to categorize each type of content available on your channel. See MediaType and Behavior for more information.

NOTE: To pass certification, you must submit working sample deep links for each type of media in your channel.

Supported types of media are:

  • movie
  • series
  • season
  • episode
  • short-form
  • special
  • live

Requirements for deep linking behavior

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

  • Your channel must support as many or as few mediaType as is necessary to accurately index all the content in your channel. If your channel has a mix of TV shows and feature-length films, you must support the “movie,” “series,” “season,” and “episode”. If instead, your channel has many live feeds available at a time, use the “live” mediaType. The one exception to this rule is for channels that only include one single live stream. Since such channels only have one possible behavior, there are no extra steps required from the developer.

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

  • 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.

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

  • 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.

MediaType and required behavior

When many types of media are launched with a deep link, the expected behavior is to begin playing the content directly. However, for the mediaType season, the user should be brought to an episodic picker screen. 

mediaTypecontentIDRequired Behavior
movieMovie to be played

For a movie or an episode, the required behavior is to launch directly into playback. If the content is paywalled or the user is not authenticated, you can redirect to the appropriate screen. The user should be able to play content directly after the required action is performed.

Note: There are several acceptable ways for a channel to respond to a series contentID. Your channel must always launch directly into video playback of an episode, but determining which specific episode to launch is defined by your channel. See Behavior for Deep Linking to a Series for guidance.

episodeEpisode to be played
contentID of an episode in the series


Item to be playedIf your content is a movie trailer, news clip, digital short, or must stand-alone content less than 15 minutes in duration, it is likely considered a short-form mediaType. If the content includes seasons or is considered a movie, the short-form mediaType would not apply, regardless of duration.



contentID to be played

Use special if your content does not match a particular mediaType.

seasoncontentID of an episode in the seasonFor season you are REQUIRED to go to an episode picker screen that lists the episodes in the season. Even if your channel does not yet have a picker screen, you must implement one for deep linking. A picker screen is defined as a screen that only shows episodes from that particular season of a TV show. The layout of the picker screen is defined by your channel. For example, it could be a grid or a list. On the episode picker screen you should highlight the episode passed in using the contentID.
liveStream to be launchedUse live when you are identifying a specific live feed. The live mediaType should launch directly into playback.


Behavior for deep linking to a series

When a channel is passed the series mediaType, it will receive a contentID that can be used to identify the content to be played. The contentID passed may not be the specific episode that should be played; rather, it can be used to indicate the series. Once the series is identified, the channel should implement its own logic to start playback at the best position in the series possible, based on the user's past viewership of the series and based on the type of series.

In most cases, the channel should refer to a smart bookmark on their service's backend to determine where in the series' chronology the user last watched, and resume playback from that position. This may be in the middle of an episode, the start of the next episode in the series, or, if the user has never watched an episode from that series at all, it may be the beginning of the very first episode in the series.

In some cases, this implementation might not make sense. For instance, if a user deep links to a nightly news series, it is reasonable to assume they want to watch tonight or last night's news, as opposed to the very first episode ever aired as part of that news series. In this case, the channel service should be intelligent enough to initiate playback of the most recent episode of the series.

Remember: There is no "series" contentID. "Series" is only a mediaType. Use an episode contentID to identify the content to be played. 

Keep in mind that there are many different types of content series: Serialized television dramas, reality TV, sitcoms, nightly news, talk shows, etc. As such, there are several different ways you could choose to respond to a series deep link in order to build the best user experience.

Below are some common types of series and Roku’s recommended deep linking behavior for each:

Type of SeriesDefinitionRecommended Behavior
Current 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.
Library 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

Deep linking is implemented by passing launch parameters to your channel's Main() function. These launch parameters are passed in using an associative array similar to argv in C. Your channel is responsible for parsing these parameters and taking the appropriate action, or in the case of an error, detecting it and going to the channel's home screen.

The first step is to 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.

Function Main (args as Dynamic) as Void

Then, determine if the channel is being launched via a deep link. If either args.contentID or args.mediaType is invalid, disregard the deep link and launch the channel normally.

if (args.mediaType <> invalid) and (args.contentID <> invalid)
    'mediaType and contentID are valid so deep link to content
    'launch channel normally
end if


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")

    'Create a scene and load /components/yourchannel.xml'
    scene = screen.CreateScene("Hello Channel")

        msg = wait(0, m.port)
        msgType = type(msg)
        if msgType = "roSGScreenEvent"
            if msg.isScreenClosed() then return
        end if
    end while

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")
        'play content directly
    else if (args.mediaType = “season”)
        'display an episodic picker screen with the content item of the corresponding contentID in focus
        '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


end sub

Testing Deep Linking

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

Using the 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.

Using cURL for Testing

Deep linking can be tested using cURL and the External Control Protocol (ECP).

You can trigger deep linking by doing an HTTP post to port 8060 on your Roku device. The form of the cURL is:

http://<IP of Roku>:8060/launch/[dev | channel ID]?contentId=<content ID>&MediaType=<mediaType>

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 toseason
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 

When submitting a channel for certification, you are required to provide one or many pairs of deep link parameters, dependant on how many unique mediaTypes your channel includes. These deep link parameters should be provided in the "Test Accounts & Deep Linking Parameters" field on the Support Information page of the channel submission survey found within the Developer Dashboard.

You are required to provide one pair of deeplinking parameters for each type of media included in your channel. These parameters are used by Roku to certify that your channel is responding with the correct behavior for each type of content in your channel.

On the Support Information screen of the channel submission survey, you can enter your deep linking content by pasting in your mediaType and contentID, such as a movie's deep linking parameters:

contentID = "MyGroup=abc|ProductID=1234|groupID=456"

mediaType = "movie"

The following illustrates the location in the Support Information screen:

  • No labels