as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
Ring
AWS
Documentation
Support
Contact Us
My Cases
Get Started
Design and Develop
Publish
Reference
Support

Content Launcher Integration Guide

This document explains how to integrate Content Launcher into your app. Media apps typically require integration with three key APIs:

The system implements Content Launcher and Vega Media Controls APIs as in an interactive component, which is the main component handling Vega media queries. The Account Login API functions as a service component.

For details on how to add the correct dependencies, and update your manifest, see @amazon-devices/kepler-media-content-launcher for the API README file.

Vega Media Content Launcher common use cases

To begin using Vega Media Content Launcher APIs, follow these steps.

  • Instantiate a new ContentLauncherServerComponent. Develop a handler object that encapsulates the callback function. This function should return a Promise to ILauncherResponse, which is created using the ContentLauncherServerComponent instance. The way search parameters are retrieved is explained later in this guide. The callback function should:
    • Process the content launch request.
    • Set the appropriate status in the LauncherResponse:
      • ContentLauncherStatusType.SUCCESS if the request is successfully processed.
      • ContentLauncherStatusType.AUTH_FAILED if authorization issues prevent processing.
      • ContentLauncherStatusType.URL_NOT_AVAILABLE for all other scenarios.

Implement the Content Launcher API

  1. Define the Content Launcher handler.

    Instantiate a new ContentLauncherServerComponent. Develop a handler object that encapsulates the callback function.

    Copied to clipboard.

     import {
       ILauncherResponse,
       IContentLauncherHandler,
       ContentLauncherStatusType,
       ContentLauncherServerComponent,
       IContentSearch,
       ILaunchContentOptionalFields,
     } from '@amazon-devices/kepler-media-content-launcher';
    
     ...
     // Create an instance of ContentLauncherServerComponent.
     const factory = new ContentLauncherServerComponent();
    
     // Create a handler to be called when content is requested to be launched.
     const contentLauncherHandler: IContentLauncherHandler = {
         async handleLaunchContent(
           contentSearch: IContentSearch,
           autoPlay: boolean,
           optionalFields: ILaunchContentOptionalFields,
         ): Promise<ILauncherResponse> {
             console.log('Content_Launcher_Sample: handleLaunchContent invoked');
    
             // Iterate here to fetch data.
             // Add business logic to handle the launch request.
    
             const launcherResponse = factory
                 .makeLauncherResponseBuilder()
                 .contentLauncherStatus(ContentLauncherStatusType.SUCCESS)
                 .build();
             return Promise.resolve(launcherResponse);
         },
     };
    

    The handler should process the request, return a Promise to ILauncherResponse, and create it with an instance of the ContentLauncherServerComponent.

    Set the status of contentLauncherStatus for LauncherResponse to ContentLauncherStatusType.SUCCESS if your app successfully processed the request. Set the status to ContentLauncherStatusType.AUTH_FAILED if your app can't process the request due to authorization issues. Set the status to ContentLauncherStatusType.URL_NOT_AVAILABLE for everything else.

  2. Implement the Vega Media Content Launcher in your interactive app.

    1. Obtain a singleton instance of IContentLauncherServerAsync. Implement IContentLauncherServerAsync by using the getOrMakeServer method on your ContentLauncherServerComponent instance.
    2. Create a handler object to implement the IContentLauncherHandler interface to process content launch requests.
    3. Call the 'setHandlerForComponent' method for the 'IContentLauncherServerAsync' instance. This associates the handler with the correct component.
    4. Pass the handler and the appropriate IComponentInstance.

In an interactive app, you can obtain the IComponentInstance using the useComponentInstance method. For React Native apps, set up the handler with the useEffecthook. It should initialize Content Launcher as soon as the component mounts and IComponentInstance is available. This integrates Content Launcher functionality into your component's lifecycle, so your app handles Vega Content Launcher commands. This setup is important for apps with multiple components, so each component uses IComponentInstance, preventing confusion in callback routing.

Copied to clipboard.

  import { useComponentInstance, IComponentInstance } from '@amazon-devices/react-native-kepler';

  export const App = () => {
      const componentInstance: IComponentInstance = useComponentInstance();

      useEffect(() => {
          const factory = new ContentLauncherServerComponent();

          const contentLauncherHandler: IContentLauncherHandler = {
              async handleLaunchContent(
                  contentSearch: IContentSearch,
                  autoPlay: boolean,
                  _optionalFields: ILaunchContentOptionalFields,
              ): Promise<ILauncherResponse> {
                  console.log('Content_Launcher_Sample: handleLaunchContent invoked.');

                  // Iterate to fetch data.
                  // ...here

                  const launcherResponse = factory
                      .makeLauncherResponseBuilder()
                      .contentLauncherStatus(ContentLauncherStatusType.SUCCESS)
                      .build();

                  return Promise.resolve(launcherResponse);
              },
          };

          const contentLauncherServer = factory.getOrMakeServer();
          contentLauncherServer.setHandlerForComponent(contentLauncherHandler, componentInstance);

          return () => {};
      }, []);

      // Create a user interface for your provider app here.
  };

Implementation details

The handleLaunchContent callback function takes three parameters:

  1. An object implementing the IContentSearch interface.
  2. A boolean value called autoPlay.
  3. Additional fields, passed as an object implementing the ILaunchContentOptionalFields interface.

The IContentLauncherHandler handler takes one parameter that defines what content to play or show search results.

Determining action based on autoPlay

The autoPlay parameter guides the handler's behavior:

  • When autoPlay is set to true: This indicates a quick play request. The specified content should begin playback immediately without requiring any further user interaction.
  • When autoPlay is set to false: In this case, the handler should present search results to the user instead of initiating playback. This allows the user to review and select from the available options.

By leveraging these parameters, particularly autoPlay, the IContentLauncherHandler can efficiently manage content discovery and playback.

Retrieving search values

The IContentSearch parameter holds the content information to be searched. The following schema is for values stored in IContentSearch.

Copied to clipboard.

1     "parameterList": [{
1.1     "type": "<entity type>",
1.2     "value": "<entity value>",
1.3     "externalIdList": [{
1.3.1          "name": "<externalId name>",
1.3.2          "value": "<externalId value>"
        }]
      }]
  • parameterList has one or more entries. contentSearch.getParameterList().length returns the number of parameters. Use getParameterList() to retrieve the full list. (Line 1 in the schema)
  • represents the type of entity listed in the parameter. For example, "type" is `ContentSearchParamType::VIDEO` for a movie or TV Show. See the `ContentSearchParamType` enum for the full set of supported values. Call `getParamType()` to fetch the type. (Line 1.1 in the schema)
  • represents the value of the entity mentioned in the type. Call `getValue()` to retrieve this field. (Line 1.2 in the schema) Each parameter has zero or more `externalIds`. Use `getExternalIdList()`.length to get the size of the list. `getExternalIdList()` returns the full list. (Line 1.3 in the schema)
  • <externalId name> is retrieved by getName(). The two recognized names are: (Line 1.3.1 in the schema) amzn_id — the catalog ID for the requested content. launch_url — a deep-link string supplied by external experiences, such as Matter Casting, that can be used directly to start playback.
  • <externalId value> represents the value of the externalId. To retrieve the value, use getValue(). For amzn_id, the value is the same <ID> or <launchId> used in your catalog integration. For launch_url, the value is the full deep link as provided by the requesting experience.

Content Launcher request examples

The following examples explain contentSearch parameter values for some key Content Launcher use cases. This example lists all supported use cases. Content Launcher is invoked and the app launches for every use case.

The following sample catalog for streamz_us includes example entries for the movie Seabound and the TV show The SeaShow: The Real Story.

Copied to clipboard.

...
<Movie>
  <ID>1700000725</ID>
  <Title locale="en-US">Seabound</Title>
  <Offers>
    <SubscriptionOffer>
      <LaunchDetails>
        <Quality>UHD</Quality>
        <Subtitle>en-US</Subtitle>
        <LaunchId>tv.streamz/movie/46720001</LaunchId>
      </LaunchDetails>
    </SubscriptionOffer>
    <FreeOffer>
      <Regions>
        <Territories>US</Territories>
      </Regions>
      <LaunchDetails>
        <Quality>SD</Quality>
        <Subtitle>en-US</Subtitle>
        <LaunchId>tv.streamz/movie/467200002</LaunchId>
      </LaunchDetails>
    </FreeOffer>
  </Offers>
</Movie>

<TvShow>
  <ID>1700000123</ID>
  <Title locale="en-US">The SeaShow: The Real Story</Title>
  <Offers>
    <FreeOffer>
      <Regions>
        <Territories>US</Territories>
      </Regions>
      <LaunchDetails>
        <Quality>HD</Quality>
        <Subtitle>en-US</Subtitle>
        <LaunchId>459800033</LaunchId>
      </LaunchDetails>
    </FreeOffer>
  </Offers>
</TvShow>

<TvSeason>
  <ID>1700000234</ID>
  <Title locale="en-US">Season 1</Title>
    <Offers>
     <FreeOffer>
       <Regions>
         <Territories>US</Territories>
       </Regions>
       <LaunchDetails>
         <Quality>HD</Quality>
         <Subtitle>en-US</Subtitle>
         <LaunchId>453200012</LaunchId>
        </LaunchDetails>
     </FreeOffer>
   </Offers>
   <ShowID>1700000123</ShowID>
   <SeasonInShow>2</SeasonInShow>
</TvSeason>

<TvEpisode>
  <ID>1700000825</ID>
  <Title locale="en-US">The Seashow. Story Starts</Title>
  <Offers>
    <FreeOffer>
      <Regions>
        <Territories>US</Territories>
      </Regions>
      <LaunchDetails>
        <Quality>HD</Quality>
        <Subtitle>en-US</Subtitle>
        <LaunchId>453100008</LaunchId>
      </LaunchDetails>
    </FreeOffer>
  </Offers>
  <ShowID>1700000123</ShowID>
  <SeasonID>1700000234</SeasonID>
  <EpisodeInSeason>5</EpisodeInSeason>
</TvEpisode>
...

Launch content through the remote

Launch the movie Seabound using a remote from the Vega TV Home screen.

Copied to clipboard.

"parameterList": [
    {                                               // parameter 0
        "type": 13,                                 // ContentSearchParamType::VIDEO
        "value": "",                                // Content title won't be populated
        "externalIdList": [
            {
                "name": "catalogContentId",         // To be deprecated. Ignore this
                "value": "tv.catalog/movie/46720000" // ID or LaunchId from catalog
            },
            {
                "name": "amzn_id",
                "value": "tv.catalog/movie/46720000" // ID or LaunchId from catalog
            }
        ]
    }
]

The app should identify the movie using tv.streamz/movie/46720000 for the LaunchId, and play it directly.

Quickplay with voice

Play movie Seabound through voice. Use the utterance "Alexa, Play Seabound."

autoPlay is true here. The following example includes the contentSearch: IContentSearch values. The app launches and it should play content directly using ID 1700000725.

Copied to clipboard.

[
    {                             // parameter 0
        "type": 13,               // ContentSearchParamType::VIDEO
        "value": "Seabound",      // search string
        "externalIdList": [{
            "name": "streamz_us"   // your catalog id. To be deprecated. Ignore this
            "value": "1700000725" // ID from catalog
        },
        { 
            "name": "amzn_id"  
            "value": "1700000725" // ID from catalog
        }
      ]
    }
]

Playing a specific episode with voice

The following catalog sample represents a TV Show SeaShow: The Real Story, its season, and an episode. The Alexa utterance "Alexa, Play Season 2 Episode 5 from The SeaShow: The Real Story," invokes the app to play the specific episode.

autoPlay is true here. contentSearch includes the show ID, not the episode ID. The app must identify the exact episode using ID 1700000123, ContentSearchParamType::SEASON, and ContentSearchParamType::EPISODE values.

Copied to clipboard.

"parameterList": [
    {
        "type": 13,
        "value": "",
        "externalIdList": [
            {
                "name": "catalogContentId",
                "value": "tv.catalog/movie/46720000"
            },
            {
                "name": "amzn_id",
                "value": "tv.catalog/movie/46720000"
            }
        ]
    }
]

Example: Launch an episode using Alexa

The following example launches an episode using the following Alexa utterance: "Watch The SeaShow: The Real Story season two episode five in Streamz."

Copied to clipboard.

// Iterate to fetch data.
const searchParameters = contentSearch.getParameterList();
if (searchParameters.length > 0) {
    for (const searchParameter of searchParameters) {
        const paramType = searchParameter.getParamType();
        const searchString = searchParameter.getValue();

        const additionalInfoList = searchParameter.getExternalIdList();
        for (const additionalInfo of additionalInfoList) {
            const searchName = additionalInfo.getName();
            const entityID = additionalInfo.getValue();

            switch (searchName) {
                case 'amzn_id':
                    // Use this entity ID to look up exact content in your catalog.
                    break;
                case 'launch_url':
                    // Use this deep-link URL to start playback directly.
                    break;
                // Add cases here for any additional externalId names your app supports.
                default:
                    // Fall through for unrecognized externalId names.
                    break;
            }
        }
    }

    if (autoPlay === true) {
        console.log(`Content_Launcher_Sample: Quickplay`);
        // Handle play logic here using the data retrieved.
    } else {
        console.log(`Content_Launcher_Sample: In-App search`);
        // Handle search logic here using the data retrieved.
    }
} else {
    console.log('Content_Launcher_Sample: Error fetching search string');
}

Last updated: Jun 18, 2026