as

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

Get Started with Vega Subscription Entitlement

Here’s what you need to know to integrate the Vega Subscription Entitlement into your app for Fire TV.

If the data is not accessible or needs to be transformed, this integration could take longer. You can confirm that your data is stored in the requested format using the documentation below.

Prerequisites

  • Access to the source code of your app for Fire TV.
  • A Fire TV device that supports this integration. Check with your Amazon contact for a list of devices currently supported.
  • Your app must participate in the Catalog Ingestion process, so Fire TV recognizes the subscription IDs your app is passing in these APIs.
  • Your app must share entitlements for each customer, so Fire TV shows the entitled provider as part of our content discovery experience. For more information, reach out to your Amazon contact.

Integration steps

Step 1. Include the necessary package dependencies in your app

Add the Kepler-Subscription-Entitlement package and headless-task-manager dependencies in your package.json file.

Copied to clipboard.

Copied to clipboard.

  "dependencies": {
    "@amazon-devices/react-native-kepler": "~2.0.0",
    "react": "18.2.0",
    "react-native": "0.72.0",
    "@amazon-devices/kepler-subscription-entitlement": "^1.1.0",
    "@amazon-devices/headless-task-manager": "^1.0.0"
  }
  • The kepler-subscription-entitlement package provides APIs for sending your subscription entitlement data into the system.
  • The headless-task-manager package provides APIs to register your data-pull background service with the system. You can read more details below.

Step 2. Update your manifest file

Update your manifest.toml file to include Subscription Entitlement support. Below is an example for a sample app:

Copied to clipboard.

schema-version = 1

## Define your package
[package]
title = "Vega Video app"
version = "2.17.0"
id = "com.amazondeveloper.keplervideoapp"

[components]
## Define your app's interactive component (if it doesn't already exist)
[[components.interactive]]
id = "com.amazondeveloper.keplervideoapp.main"
library-name = "com.amazondeveloper.keplervideoapp"
runtime-module = "/com.amazon.kepler.keplerscript.runtime.loader_2@IKeplerScript_2_0"
categories = ["com.amazon.category.kva"]
launch-type = "singleton"

## Define your app's service component which can handle data request.
[[components.service]]
id = "com.amazondeveloper.keplervideoapp.content.dataRefresh.provider"
runtime-module = "/com.amazon.kepler.headless.runtime.loader_2@IKeplerScript_2_0"
launch-type = "singleton"
categories = ["com.amazon.category.kepler.media"]

## Define a process group for each component
[processes]
## <other process related entries>
[[processes.group]]
component-ids = ["com.amazondeveloper.keplervideoapp.main"]

[[processes.group]]
component-ids = ["com.amazondeveloper.keplervideoapp.content.dataRefresh.provider"]

[wants]
## Defines that your app has a dependency on the Subscription Entitlement data service
[[wants.service]]
id = "com.amazon.tv.developer.dataservice.main"

[needs]
## Defines the privilege your app needs in order to use the Subscription Entitlement interface to provide data
[[needs.privilege]]
id = "com.amazon.tv.subscription-entitlement.privilege.provide-data"

[offers]
## Defines the data refresh service component of your app
[[offers.service]]
id = "com.amazondeveloper.keplervideoapp.content.dataRefresh.provider"

## Defines the interactive components of your app
[[offers.interaction]]
id = "com.amazondeveloper.keplervideoapp.main"

## Add extras to declare support for Subscription Entitlement
[[extras]]
key = "interface.provider"
## If you're utilizing account login or content launcher interface,
## replace component-id with appropriate service component. Follow Account Login Integration Guide
component-id = "com.amazondeveloper.keplervideoapp.content.dataRefresh.provider"

[extras.value.application]
## Defines support for the Subscription Entitlement interface and the attributes
[[extras.value.application.interface]]
interface_name = "com.amazon.kepler.media.ISubscriptionEntitlementServer"
attribute_options = ["DataRefreshComponentId"]

[extras.value.application.interface.static_values]
DataRefreshComponentId = "com.amazondeveloper.keplervideoapp.content.dataRefresh.provider"

Each interface configuration must be kept separate. Do not combine or mix attributes between different interfaces in the manifest file.

Here is an example of the correct way to define multiple interfaces.

Copied to clipboard.

[extras.value.application]
[[extras.value.application.interface]]
interface_name = "com.amazon.kepler.media.IContentPersonalizationServer"
attribute_options = ["SupportedCustomerLists", "DataRefreshComponentId"]

[extras.value.application.interface.static_values]
SupportedCustomerLists = ["Watchlist"]
DataRefreshComponentId = "com.amazondeveloper.keplervideoapp.content.dataRefresh.provider"

[[extras.value.application.interface]]
interface_name = "com.amazon.kepler.media.IContentLauncherServer"
override_command_component = { LaunchContent = "com.amazondeveloper.keplervideoapp.main" }
attribute_options = ["partner-id"]

[extras.value.application.interface.static_values]
partner-id = "<Your partner id>"

And here is an incorrect way to do this. Do not do it this way.

Copied to clipboard.

[extras.value.application]
[[extras.value.application.interface]]
interface_name = "com.amazon.kepler.media.IContentPersonalizationServer"
attribute_options = ["SupportedCustomerLists", "DataRefreshComponentId"]

[[extras.value.application.interface]]
interface_name = "com.amazon.kepler.media.IContentLauncherServer"
override_command_component = { LaunchContent = "com.amazondeveloper.keplervideoapp.main" }
attribute_options = ["partner-id"]

[extras.value.application.interface.static_values]
partner-id = "<Your partner id>"
SupportedCustomerLists = ["Watchlist"]
DataRefreshComponentId = "com.amazondeveloper.keplervideoapp.content.dataRefresh.provider"

Step 3. Make a sample API call

Begin with a sample/mock event generated at the app launch. To construct the event and send it, use the following code:

Copied to clipboard.

// Example subscription entitlement entry generated and sent

const subscriptionEntry: ISubscriptionEntitlementEntry = new SubscriptionEntitlementEntryBuilder()
    .acquisitionTimestamp(new Date())
    .expirationTimestamp(new Date())
    .subscriptionId('testSubscriptionId')
    .build();

// Send the event
SubscriptionEntitlementServer.reportNewSubscription(subscriptionEntry);

Step 4. Validate the integration

Trigger the sample event code you constructed to run inside your app. After you run the code successfully, view the logs to validate the SDK has been linked to your app and is processing the message.

You can validate the steps by searching your app logs:

Copied to clipboard.

journalctl --follow |grep -Ei 'kepler.tv.subscription_entitlement'

The log message you receive for the event shown in Step 3 should contain at least one of the below logs:

Copied to clipboard.

Dec 15 01:00:17.721539 carat-3fc19fb5ae526e4d local0.info keplerscript-ru[22814]: 1483317178 INFO kepler.tv.subscription_entitlement:ISubscriptionEntitlementServer getOrMakeServer called
Dec 15 01:00:17.725200 carat-3fc19fb5ae526e4d local0.info keplerscript-ru[22814]: 1483317178 INFO kepler.tv.subscription_entitlement.anse.turbomodule:reportNewSubscription called
Dec 15 01:00:17.725311 carat-3fc19fb5ae526e4d local0.info keplerscript-ru[22814]: 1483317178 INFO kepler.tv.subscription_entitlement:SubscriptionEntitlementEntryBuilder build() called
Dec 15 01:00:17.725360 carat-3fc19fb5ae526e4d local0.info keplerscript-ru[22814]: 1483317178 INFO kepler.tv.subscription_entitlement:reportNewSubscription call received

Step 5. Make API calls as part of in-app functionality

Review the When to Send section and locate where in your app you need to make API calls to the Vega Subscription Entitlement.

Step 6. Implement your data pull service for background or off-device data

To allow Amazon to pull data from your app, implement the service as described below. This service contains everything needed for setup and connection and requires you to implement functions to send data to a receiver object. The object allows you to share data in chunks, as needed, to prevent loading large lists into memory.

  1. Create a service.js file on the same path as the package.json with the following content. This alerts the system about the entry points for your content.dataRefresh.provider service.

    Copied to clipboard.

    import { HeadlessEntryPointRegistry } from '@amazon-devices/headless-task-manager';
    
    import {
    onStartService,
    onStopService,
    } from './src/headless/HeadlessService';
    
    HeadlessEntryPointRegistry.registerHeadlessEntryPoint2(
    'com.amazondeveloper.keplervideoapp.content.dataRefresh.provider::onStartService',
    () => onStartService,
    );
    HeadlessEntryPointRegistry.registerHeadlessEntryPoint2(
    'com.amazondeveloper.keplervideoapp.content.dataRefresh.provider::onStopService',
    () => onStopService,
    );
    
  2. Create your Headless Service Interface file under src/headless/HeadlessServiceInterface.ts with the following content:

    Copied to clipboard.

    import {
    IComponentInstance,
    } from "@amazon-devices/react-native-kepler";
    
    export interface HeadlessServiceInterface {
    /**
    * This function is called when native service onStart is called.
    * @param {IComponentInstance} componentInstance - The headless component instance.
    */
    onStart(componentInstance: IComponentInstance): Promise<void>;
    
    /**
    * This function is called when native service onStop is called.
    * @param {IComponentInstance} componentInstance - The headless component instance.
    */
    onStop(componentInstance: IComponentInstance): Promise<void>;
    }
    
  3. Create your data pull service under src/headless/HeadlessService.ts with the following content:

    Copied to clipboard.

    import { ISubscriptionEntitlementsHandler, ISubscriptionEntitlementsProvider, SubscriptionEntitlementServer } from "@amazon-devices/kepler-subscription-entitlement";
    import { HeadlessServiceInterface } from "./HeadlessInterface";
    import { IComponentInstance } from "@amazon-devices/react-native-kepler";
    
    /***********Subscription Entitlement Handlers*************/
    const subscriptionEntitlementHandler: ISubscriptionEntitlementsHandler = {
       getAllSubscriptionEntitlements: (
          subscriptionEntitlementsProvider: ISubscriptionEntitlementsProvider,
       ) => {  
          subscriptionEntitlementsProvider.addSubscriptionEntitlementChunk(<ADD ENTITLEMENTS>);
          subscriptionEntitlementsProvider.commit();
       },
    }; 
    
    class HeadlessService implements HeadlessServiceInterface {
       onStart(componentInstance: IComponentInstance): Promise<void> {
          SubscriptionEntitlementServer.setSubscriptionEntitlementsHandlerForComponent(
                subscriptionEntitlementHandler, componentInstance
          );
          return Promise.resolve();
          }
    
       onStop(componentInstance: IComponentInstance): Promise<void> {
          return Promise.resolve();
       }
    }
    
    const HeadlessServiceInstance = new HeadlessService() as HeadlessServiceInterface;
    
    export const onStartService = 
    (componentInstance: IComponentInstance): Promise<void> => {
       return HeadlessServiceInstance.onStart(componentInstance);
    };
    
    export const onStopService = 
    (componentInstance: IComponentInstance): Promise<void> => {
       return HeadlessServiceInstance.onStop(componentInstance);
    };
    

Implementation details

Make changes to your catalog integration when directed by your Amazon contact

To make use of the entitlement and activity data, Fire TV needs the following data from your existing Fire TV catalog integration. Fire TV’s public catalog integration documentation will be updated to include these elements in the future, but here is a preview of what will be needed concerning the Vega Subscription Entitlement integration. Your Amazon contact will inform you of the right time to begin these catalog changes.

  • Subscription IDs - Existing subscription offers need to specify the Subscription ID they apply to.

Reporting updates

The SDK allows you to share information using three types of operations:

  • New (reportNewSubscription)- Represents an incremental update to add a new entry to the dataset.
  • Removed (reportRemovedSubscription) - Represents a decremental update to remove an entry from the dataset.
  • Refreshed (reportRefreshedSubscriptions) - Indicates that there have been changes to the dataset due to off-device actions, and a new refreshed version of the list needs to be fetched using the data pull service.

The New and Removed operations are useful when the customer interacts with your app and changes their subscription levels. The Refreshed operation is useful for situations when there are significant changes to the list due to customer sign-in, off-device activity, or if you suspect the list is out of sync for another reason.

Providing large sets of data

When supplying large amounts of data through the data pull service, we recommend you pull the data in reasonably small pages from your cloud backend and call the provider APIs as the data is is being pulled down. This limits the memory usage of your service and prevent your app from being terminated by the system.

Here is an example flow.

Copied to clipboard.

const subscriptionEntitlementHandler: ISubscriptionEntitlementsHandler = {
    getAllSubscriptionEntitlements: (
      provider: ISubscriptionEntitlementsProvider,
    ) => {
        let myCloudHasMoreData = true;
        while(myCloudHasMoreData){
            let myCloudResponse = getNextPageFromMyBackend(); 
            let myCloudData = myCloudResponse.getData();
            let subscriptions: ISubscriptionEntitlementEntry[] = [];
            for(let element in myCloudData){
                let subscription = <build data with SubscriptionEntitlementEntryBuilder>
                subscriptions.push(subscriptions)
            }
            provider.addSubscriptionEntitlementChunk(subscriptions);

            myCloudHasMoreData = myCloudResponse.hasMoreData();
        }
        provider.commit();
    },
  };

Last updated: Sep 30, 2025