APL Data Sources

A data source is a JSON structure that defines data you can bind to an Alexa Presentation Language (APL) document. When you send an APL document to Alexa with the RenderDocument directive, you can include one or more data sources. You bind the data sources by including them in the parameters of the APL document. You can then use a data-binding expression to bind the data to component properties within the document.

Send a data source in the RenderDocument directive

Pass a data source to Alexa in an optional datasources object. The datasources object is part of the RenderDocument directive, but outside of the APL document. The datasources object contains an object representing each data source.

The following example shows a skill response with the RenderDocument directive. It passes the document and a data source named "myDocumentData". The document content is omitted for brevity:

{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "type": "SSML",
      "ssml": "<speak>This is a sample</speak>"
    },
    "sessionAttributes": {},
    "directives": [
      {
        "type": "Alexa.Presentation.APL.RenderDocument",
        "token": "[SkillProvidedToken]",
        "document": {
          "type": "APL",
          "version": "1.7",
          "mainTemplate": {
            "parameters": [
              "myDocumentData"
            ],
            "items": []
          }
        },
        "datasources": {
          "myDocumentData": {
            "title": "Example of a title field in a basic data source"
          }
        }
      }
    ]
  }
}

Bind the data source to the document

Use data-binding expressions to bind data in the data source to component properties in your APL document.

To bind data in a data source to component properties in your document

  1. Declare a parameter in the mainTemplate.parameters array that matches the key for the data source object.
  2. In the component properties, refer to the data source properties with the syntax ${dataSourceName.propertyName} where dataSourceName is the same key you used in mainTemplate.parameters.

For example, assume you have the following data source object.

{
  "myDocumentData": {
    "title": "Example of a title field in a basic data source"
  }
}

The key for this data source is myDocumentData. Declare the parameter myDocumentData in mainTemplate.parameters.

{
  "type": "APL",
  "version": "1.7",
  "mainTemplate": {
    "parameters": [
      "myDocumentData"
    ],
    "items": []
  }
}

Then, use a data-binding expression to bind a component property to the data in myDocumentData. Use the myDocumentData key to access the properties. For example, this expression resolves to the value "Example of a title field in a basic data source": ${myDocumentData.title}.

The following example shows an APL document that displays the content from the myDocumentData.title property in a text component.

{
  "type": "APL",
  "version": "1.7",
  "import": [
    {
      "name": "alexa-layouts",
      "version": "1.4.0"
    }
  ],
  "mainTemplate": {
    "parameters": [
      "myDocumentData"
    ],
    "items": [
      {
        "type": "Container",
        "width": "100vw",
        "height": "100vh",
        "items": [
          {
            "type": "Text",
            "text": "${myDocumentData.title}"
          }
        ]
      }
    ]
  }
}

About binding a data source to payload or other parameters

In versions of APL before 1.3, you couldn't use the key for your data source as the parameter in mainTemplate.parameters. Instead, you set the parameter to a string like "payload". The "payload" parameter was then mapped to the entire datasources object provided in your skill response. Your data-binding expressions then had to include this parameter. For example, an expression to get the title property from the earlier example would be ${payload.myDocumentData.title}.

Documents that use "payload" as the mainTemplate.parameters continue to work. However, the simplified form is recommended for new APL documents. Using other strings as the parameter doesn't work. You must use either "payload" or the data source key.

Data source types

APL supports data sources with types and free-form data sources without types.

  • Free-form ("untyped") – A JSON object with an arbitrary set of properties you define. The myDocumentData example shown earlier is an example of a free-form data source.
  • Typed – A JSON object with a structure defined by the Alexa Skills Kit. You must use typed data sources for some functionality. APL supports two typed data sources
    • object – Required to use transformers to manipulate the data, such as converting SSML text to speech or creating a hint that includes the configured wake word for a device.
    • dynamicIndexList – Required to use lazy loading to load data progressively as the user scrolls and for modifying the data source after rendering the document.
    • dynamicTokenList – Required to use token-based lazy loading to load data a page at a time.

object data source

The object data source type adds properties required for transformers. You use transformers to manipulate the data. For example, you use a transformer to put wake word configured for the user's device into a hint string.

The object data source has the following properties:

Property Type Required Description

type

object

Yes

Must be "object".

properties

object

No

An object containing properties that you can use with transformers. The transformers always expect to find data in the properties object. You define the structure of the data within properties

objectID

String

No

An optional identifier for an object data source.

description

String

No

Optional description of the data source.

transformers

Array

No

An array of transformers to apply to values in the properties object.

An object data source can also include other arbitrary properties that you can bind to your document as needed.

The following example shows an object data source with data in both the properties object and an arbitrary property (hello). The data source also has the textToSpeech transformer. The transformer references data within the properties object. For more about how to use transformers, see Transformers.

{
  "myDocumentData": {
    "type": "object",
    "properties": {
      "title": "This is another very simple sample.",
      "mainText": "Note these properties are in a <code>properties</code> object."
    },
    "hello": "Hello, World!"
    "transformers": [
      {
        "inputPath": "title",
        "outputName": "titleSpeech",
        "transformer": "textToSpeech"
      }
    ]
  }
}

Dynamic data sources

APL supports two types of dynamic data sources. Use dynamic data sources to update the data source after sending it to Alexa and therefore change the values on the screen without sending an entirely new document. These data sources also enable lazy loading, where Alexa displays large lists progressively as the user scrolls through the content.

There are two types of dynamic data sources:

  • dynamicIndexList – Uses an index to keep track of the items. Users can scroll to arbitrary locations in the list.
  • dynamicTokenList – Uses tokens to keep track of the items. Users can scroll forward or backwards one page at time.

dynamicIndexList data source

The dynamicIndexList data source adds properties required for lazy loading and dynamic data sources.

The dynamicIndexList data source has the properties shown in the following table.

Property Type Required Description

type

String

Yes

Must be dynamicIndexList.

listId

String

Yes

Identifier to distinguish between different data sources in the same APL document.

startIndex

Integer

Yes

Index of the leading item in the items array. Specify a non-zero value to start the experience at an arbitrary offset. For example, show an alphabetical list of contact names beginning 'M'.

minimumInclusiveIndex

Integer

No

The index of the first item in the array, inclusive. The list is a backward-scrolling list if minimumInclusiveIndex is less than startIndex. When not specified, the list is backwards scrollable, but the first index of the array is unknown. Explicitly set this property equal to the startIndex property to make a list that doesn't load any more items when the user scrolls backwards.

maximumExclusiveIndex

Integer

No

The last index of the array, exclusive. When not set, the list is a forward-scrolling list, but the final index of the array is unknown. Explicitly set this property to the last index of the items array + 1 to make a list that doesn't load any more items when the user scrolls forward. For example, to create a forward-scrolling experience across 200 items, set startIndex and minimumInclusiveIndex to 0, and maximumExclusiveIndex to 200. After all items from 0 to 199 have loaded, Alexa no longer asks your skill for more items.

items

Array

No

Array of object data of the first items to render. The first element to display should be indexed at startIndex. Alexa displays the first item at the top-left of the visible list area.

The following example shows a dynamicIndexList data source that initially displays ten items. Alexa asks for more items to load when the user scrolls forward until all 200 items have loaded.

{
  "dynamicSourceExample": {
    "type": "dynamicIndexList",
    "listId": "my-list-id",
    "startIndex": 0,
    "minimumInclusiveIndex": 0,
    "maximumExclusiveIndex": 200,
    "items": [
      {"primaryText":"item 1"},
      {"primaryText":"item 2"},
      {"primaryText":"item 3"},
      {"primaryText":"item 4"},
      {"primaryText":"item 5"},
      {"primaryText":"item 6"},
      {"primaryText":"item 7"},
      {"primaryText":"item 8"},
      {"primaryText":"item 9"},
      {"primaryText":"item 10"}      
    ]
  }
}

dynamicTokenList data source

The dynamicTokenList data source has the properties shown in the following table.

Property Type Required Description

propertyName

String

Yes

Must be dynamicTokenList.

listId

String

Yes

Identifier to distinguish between different data sources in the same APL document.

pageToken

String

Yes

A token associated with the items included in the data source. You determine the string to use for the pageToken. Your skill must keep track of the data associated with the token.

backwardPageToken

String

No

A token to retrieve item data for the previous page of items. You determine the string to use for the backwardPageToken. Your skill must keep track of the data associated with this token, and must also identify that the token represents going backwards through the list of items.

When not provided, there are no previous list items to render. The user can't scroll backwards through the list.

forwardPageToken

String

No

A token to retrieve item data for the next page of items. You determine the string to use for the forwardPageToken. Your skill must keep track of the data associated with this token, and must also identify that the token represents going forwards through the list of items.

When not provided, there are no next list items to render. The user can't scroll forwards through the list.

items

Array

No

Array of object data of the first items to render. Alexa displays the first item at the top-left of the visible list area.

Bind a dynamic data source to your APL document

To use a dynamic data source in your document, you must use the data source key in the mainTemplate.parameter. Don't use the pre-1.3 "payload" parameter.

Then, use the data source key in your data-binding expression. For example, assume you create a data source called dynamicSourceExample. To bind to this data source, use the expression ${dynamicSourceExample}. This syntax provides your document with the set of items in the items property. Don't include the items property in the expression.

Bind the data source to the data property of a Pager, GridSequence, Sequence, or Container. Note that Container doesn't support lazy loading, but it does support dynamic data sources. You can't use a dynamicIndexList with any other component types.

This example shows a Sequence that displays the ten items defined in a data source called dynamicSourceExample data source.

{
  "type": "APL",
  "version": "1.7",
  "mainTemplate": {
    "parameters": [
      "dynamicSourceExample"
    ],
    "items": [
      {
        "type": "Sequence",
        "data": "${dynamicSourceExample}",
        "items": {
          "type": "Text",
          "text": "${data.primaryText}"
        }
      }
    ]
  }
}

Use directives and requests to manage the list

The Alexa.Presentation.APL interface provides several directives and requests for managing a dynamic data source.

With a dynamicIndexList data source, you can load items progressively. You can also change the contents of the list. With a dynamicTokenList, you can load additional pages of content as the user scrolls the list.

To load items progressively with a dynamicIndexList

  1. Send the dynamicIndexList data source with your initial set of items in the RenderDocument directive.
  2. As the user scrolls the list, Alexa sends your skill LoadIndexListData requests to ask for more items to display.
  3. Respond to the LoadIndexListData request with the SendIndexListData directive with another dynamicIndexList data source containing the next set of items to display.

To change the contents of a dynamicIndexList

  1. Send the initial dynamicIndexList data source with a set of list items in the RenderDocument directive.
  2. Use the UpdateIndexListData directive to make updates to the data, such as inserting new items or deleting existing items.

To load pages of data with a dynamicTokenList

  1. Send the dynamicTokenList data source with your initial set of items in the RenderDocument directive.
  2. As the user scrolls the list, Alexa sends your skill LoadTokenListData requests to ask for more items to display.
  3. Respond to the LoadTokenListData request with the SendTokenListData directive with another dynamicTokenList data source containing the next set of items to display.

For more about requests and directives, see the Alexa.Presentation.APL Interface Reference.

Sequence component size and the number of items to load

When you use a dynamic data source with a Sequence for lazy loading, send enough items to fill the Sequence at least three times in each response. For example, if the Sequence is tall enough to display five items, your initial dynamicIndexList should contain at least 15 items. Each subsequent SendIndexListData or SendTokenListData directive should also contain at least 15 items. The same applies for a horizontally-scrolling Sequence. If the Sequence is wide enough to display five items, send at least 15 in each call.

Providing a large enough set of items improves the list performance and user experience. If you send a small number of items in each response, the user experience might be poor as Alexa must then continually request new items as the user scrolls.

To make sure that the Sequence height or width remains static when loading items and scrolling, don't use the auto setting for the height or width properties on the Sequence. Set the Sequence size to either a relative or absolute dimension.