Alexa.Presentation.APL Interface Reference
The Alexa.Presentation.APL interface provides directives and requests that display content on a device with a screen, such as an Echo Show. You use directives in requests in this interface to display a standard APL response on a device with a screen, and to communicate with a widget installed on the device.
Alexa.Presentation.APL in supportedInterfaces
When the user's device has a screen that supports APL, the context.System.device.supportedInterfaces object includes [Alexa.Presentation.APL]:
Always check supportedInterfaces before returning the Alexa.Presentation.APL directives. For an example that does this with the ASK SDK, see Make sure the user's device supports APL in Use Alexa Presentation Language with the ASK SDK v2.
Available Extensions in context
Extensions are optional enhancements that provide additional APL functionality. For some extensions, you must request the extension in the in the skill manifest. When the user's device supports these extensions, the context object includes an Extensions.available property. This property contains a map in which the key for each item is the URI for the available extension.
The following example illustrates a request from a device that supports the smart-motion and entity-sensing extensions.
{
"version": "1.0",
"session": {},
"context": {
"AudioPlayer": {
"playerActivity": "IDLE"
},
"Viewports": [
{
"type": "APL",
"id": "<string>"
}
],
"Extensions": {
"available": {
"alexaext:smartmotion:10": {},
"alexaext:entitysensing:10": {}
}
}
}
}
The context.Extensions property includes extensions that meet both the following criteria:
-
You requested the extension in the skill manifest in the
requestedExtensionsproperty.For details about how to request extensions in the manifest, see Request an extension in the skill manifest.
-
The device supports the extension.
Not all extensions can be included in the manifest. See the topic for the extension you want to use to determine the extension's requirements.
Directives
The following table lists the directives available in the Alexa.Presentation.APL interface. The "Widget support" column indicates whether you can use the directive to communicate with a widget installed on the device.
| Directive | description | Widget support |
|---|---|---|
|
Instructs the device to display the APL content provided in the specified |
No | |
|
Instructs the device to run the provided
|
Yes | |
|
Sends a new set of list items to display, in response to a |
No | |
|
Sends a new page of list items to display, in response to a |
No | |
|
Send a set of data operations to Alexa to insert, set, and delete list items in a data source that has already been sent to the device in a |
No |
RenderDocument directive
Instructs the device to display the APL content provided in the specified document. You can also optionally provide one or more datasources to bind content to document.
The following RenderDocument example sends a document with two Text components and a data source called helloworldData.
{
"type": "Alexa.Presentation.APL.RenderDocument",
"token": "helloworldToken",
"document": {
"type": "APL",
"version": "2024.3",
"mainTemplate": {
"parameters": [
"payload"
],
"items": [
{
"type": "Container",
"height": "100%",
"width": "100%",
"items": [
{
"type": "Text",
"id": "helloTextComponent",
"text": "${payload.helloworldData.properties.helloText}",
"textAlign": "center",
"textAlignVertical": "center",
"maxLines": 3,
"grow": 1
},
{
"type": "Text",
"id": "newHelloTextComponent",
"text": "${payload.helloworldData.properties.newHelloText}",
"textAlign": "center",
"textAlignVertical": "bottom",
"maxLines": 3,
"opacity": 0
}
]
}
]
}
},
"datasources": {
"helloworldData": {
"type": "object",
"objectId": "helloworld",
"properties": {
"helloText": "Hello world! This APL document displays text from a datasource called helloworldData.",
"newHelloText": "I hid the original hello text and then displayed this!"
}
}
}
}
You can also save your document with your skill in the developer console and then provide a link to it in the RenderDocument directive. The following example assumes that "hello world" document has been saved with the name "helloworld-by-link".
{
"directives": [
{
"type": "Alexa.Presentation.APL.RenderDocument",
"token": "helloworldToken",
"document": {
"src": "doc://alexa/apl/documents/helloworld-by-link",
"type": "Link"
},
"datasources": {
"helloworldData": {
"type": "object",
"objectId": "helloworld",
"properties": {
"helloText": "Hello world! This APL document displays text from a datasource called helloworldData.",
"newHelloText": "I hid the original hello text and then displayed this!"
}
}
}
}
]
}
RenderDocument properties
| Property | Type | Required | Description |
|---|---|---|---|
|
|
String |
Yes |
Set to |
|
|
String |
Yes |
String that identifies the document. You use this when you issue subsequent directives that refer to the document. For example, you need this token when you send the |
|
|
Object |
Yes |
An object representing the APL document to send to the device. |
|
|
One of: |
Yes |
Indicates the type of document to send. Set to "APL" when |
|
|
URL |
When |
The URL that identifies the document saved in the developer console. For APL, the link has the following syntax: |
|
|
Map of additional documents or references to documents |
No |
An object containing named APLA documents or links. These documents can be referenced by the "template" parameter in the aplAudioToSpeech transformer. |
|
|
Map of data source objects |
No |
Object that can contain other objects that you can use to bind data to the APL document. |
The document property must always contain either the src property set to the URL for a document, or the JSON for the full document.
For an example showing how you would send RenderDocument with the ASK SDK v2, see Return RenderDocument in your request handler response in Use Alexa Presentation Language with the ASK SDK v2.
Link to an APL document saved in the developer console
You can save an APL document in the developer console and then use a link to that document in the RenderDocument directive. This means you don't need to export the JSON for your APL document and copy it into your code.
A link to a document in the developer console has the following syntax:
doc://alexa/apl/documents/<document-name>
The <document-name> is the name you used when saving the document in the developer console.
RenderDocument directive, build your interaction model in the developer console. When you make changes to the document in the developer console, rebuild the interaction model to make the updated document available to RenderDocument.For details about building and saving a document in the developer console, see Build Documents in the Developer Console.
You can use the Integrate with skill option in the developer console to copy a code snippet with a link to the document in the required format.
- In the developer console, open the skill.
- In the left-hand navigation, click Multimodal Responses.
- Find the document you want to integrate and click Integrate with skill.
- Review the sample code and copy to your skill code as needed.
RenderDocument code. To learn how to synchronize your documents, see the SMAPI Integration page in APL Ninja.RenderDocument and other skill directives
- Your response can combine
RenderDocumentwith any of the of theDialogdirectives except forDialog.Delegate. For example, you can useDialog.ElicitSlotto ask the user for a slot value, and at the same time display information related to that slot on the screen withRenderDocument. - Your response cannot combine
RenderDocumentwith directives from the following interfaces:AudioPlayerDisplayVideoApp
ExecuteCommands directive
Instructs the device to run the provided commands on one of the following:
- Standard document – The currently rendered document identified by the
token. - Widget – The installed widget identified by the
presentationUri.
The following example sends an ExecuteCommands directive that acts on the document identified with the token helloworldToken. This directive has two commands:
- The first
AnimateItemcommand changes the opacity of the componenthelloTextComponentto 0 over 3 seconds to make it fade from view. - The second
AnimateItemcommand changes the opacity of the componentnewHelloTextComponentfrom 0 to 1 over 3 seconds to make it fade into view.
{
"type": "Alexa.Presentation.APL.ExecuteCommands",
"token": "helloworldToken",
"commands": [
{
"type": "AnimateItem",
"componentId": "helloTextComponent",
"duration": "3000",
"easing": "linear",
"value": [
{
"property": "opacity",
"to": "0.0"
}
]
},
{
"type": "AnimateItem",
"componentId": "newHelloTextComponent",
"duration": "3000",
"easing": "linear",
"value": [
{
"property": "opacity",
"to": "1.0"
}
]
}
]
}
The following example shows the directives array for a response with the ExecuteCommands directive targeting a widget.
{
"directives": [
{
"type": "Alexa.Presentation.APL.ExecuteCommands",
"presentationUri": "widget://amzn1.ask.skill.1/MyWidgetSandbox/f1cf2427-1-1-1-1",
"commands": [
{
"type": "AnimateItem",
"duration": 1000,
"componentId": "itemDescription",
"value": {
"property": "opacity",
"to": 0
}
},
{
"type": "SetValue",
"componentId": "successMessage",
"property": "text",
"value": "Item Saved!"
}
]
}
]
}
Widgets support most standard APL commands. For the list of commands that you can send using ExecuteCommands, see Standard Commands.
ExecuteCommands properties
| Property | Type | Required | Description |
|---|---|---|---|
|
|
String |
Yes |
Set to |
|
|
String |
No |
A string that identifies the |
|
|
string |
No |
A string that identifies the widget to target with the commands. For a user interaction with your widget, such as a tap event, you can get the |
|
|
Array of commands |
Yes |
Commands to run on the rendered document identified by the token. The array of commands behaves like an implicit Sequential command. That is, the commands run one after the other rather than in parallel. |
The ExecuteCommands directive targets the commands against the specific document identified with the token or presentationUri
- To target a standard document, the
tokenyou provide must match thetokenyou provided with theRenderDocumentdirective that sent the corresponding document. - To target a widget, the
presentationUrimust match the identifier for a widget installed on the device.
You can send the RenderDocument and ExecuteCommands directives in the same skill response, or separate responses:
- When your response includes both directives, the device displays the specified document first, then runs the commands, provided the
tokenmatches in both directives. -
When you return
ExecuteCommandsin a separate response, the device runs the commands against the document currently displayed on the viewport. Thetokenmust match thetokenused in the earlierRenderDocumentdirective.Before you send
ExecuteCommandsin this scenario, check the visual context in the request to confirm that the document is currently displayed. You can get thetokenfor the currently displayed document from thecontext.["Alexa.Presentation.APL"].tokenproperty in the request.
In both cases, if the token values do not match between the directives, the commands don't run.
The following example request shows that the viewport is currently displaying the document with the token helloworldWithButtonToken (for brevity, some parts of this request are omitted).
{
"version": "1.0",
"session": {},
"context": {
"Alexa.Presentation.APL": {
"token": "helloworldWithButtonToken",
"version": "APL_WEB_RENDERER_GANDALF",
"componentsVisibleOnScreen": [
{
"uid": ":1000",
"position": "1024x600+0+0:0",
"type": "text",
"tags": {
"viewport": {}
},
"children": [
{
"id": "fadeHelloTextButton",
"uid": ":1002",
"position": "270x70+377+450:0",
"type": "text",
"tags": {
"focused": false,
"clickable": true
},
"entities": []
}
],
"entities": []
}
]
},
"System": {},
"Viewport": {},
"Viewports": []
},
"request": {}
}
For an example that shows how you check for this property and return ExecuteCommands with the ASK SDK, see Return ExecuteCommands in a request handler response in Use Alexa Presentation Language with the ASK SDK v2.
ExecuteCommands and other skill directives
Your response cannot combine ExecuteCommands with directives from the following interfaces:
AudioPlayerDialogDisplayVideoApp
SendIndexListData directive
Sends a new set of list items to display, in response to a LoadIndexListData request. Include a dynamicIndexList data source with the next set of items to display. Don't include outputSpeech or shouldEndSession in your response.
| Property | Type | Required | Description |
|---|---|---|---|
|
|
Directive |
Yes |
Set to |
|
|
String |
Yes, when sent in response to a |
The correlation token supplied in the |
|
|
String |
Yes |
The identifier for the list to update with this response. |
|
Integer |
No |
The new version number for the list following the update, used to maintain list consistency between the skill and the device. Required when you also use | |
|
|
Integer |
Yes |
Index of the first element in the items array. |
|
|
String |
No |
The index of the first item in the array. When populated, this value replaces any value specified in a previous interaction. Absence of this property indicates that the minimum index is not yet known and Alexa continues requesting more items as the user scrolls backwards (the list is a backward-scrolling list). When equal to the index of the first item returned, no further backwards scrolling is possible and Alexa stops requesting more items. |
|
|
String |
No |
The last valid index of the array plus one. When populated, this value replaces any value specified in a previous interaction. Absence of this property indicates that the maximum index is not yet known and Alexa continues requesting more items as the user scrolls forwards (the list is a forward-scrolling list). When this property is one more than the index of the last item returned then no further forward scrolling is possible and Alexa stops requesting more items. |
|
|
Array |
No |
Array of objects to add to the list. |
{
"directives": [
{
"type": "Alexa.Presentation.APL.SendIndexListData",
"correlationToken": "alexa-provided-correlation-token",
"listId": "my-list-id",
"listVersion": 3,
"startIndex": 11,
"minimumInclusiveIndex": 11,
"maximumExclusiveIndex": 21,
"items": [
{"primaryText":"item 11"},
{"primaryText":"item 12"},
{"primaryText":"item 13"},
{"primaryText":"item 14"},
{"primaryText":"item 15"},
{"primaryText":"item 16"},
{"primaryText":"item 17"},
{"primaryText":"item 18"},
{"primaryText":"item 19"},
{"primaryText":"item 20"}
]
}
]
}
Proactive loading
You must provide the correlationToken when your skill responds to a LoadIndexListData request. Alexa rejects the skill response if the expected correlationToken is not specified in exactly one SendIndexListData directive.
Omit the correlationToken when you send a set of list items not in response to a LoadIndexListData request.
SendTokenListData directive
Sends a new page of list items to display, in response to a LoadTokenListData request . Include a dynamicTokenList data source with the next page of items to display. Don't include outputSpeech or shouldEndSession in your response.
| Property | Type | Required | Description |
|---|---|---|---|
|
|
Directive |
Yes |
Set to "Alexa.Presentation.APL.SendTokenListData" |
|
|
String |
No |
The correlation token supplied in the |
|
|
String |
Yes |
The identifier of the list whose items are contained in this response. |
|
|
String |
Yes |
Opaque token for the array of items which are contained in this response. |
|
|
String |
No |
Opaque token to retrieve the next page of list items data, in the scroll direction indicated by the requested |
|
|
Array |
No |
Array of objects to be added to the list. |
{
"directives": [
{
"type": "Alexa.Presentation.APL.SendTokenListData",
"token": "developer-provided-token",
"correlationToken": "alexa-provided-correlation-token",
"listId": "my-list-id",
"pageToken": "myListPage2",
"nextPageToken" "myListPage3"
"items": [
{"primaryText":"item 11"},
{"primaryText":"item 12"},
{"primaryText":"item 13"},
{"primaryText":"item 14"},
{"primaryText":"item 15"},
{"primaryText":"item 16"},
{"primaryText":"item 17"},
{"primaryText":"item 18"},
{"primaryText":"item 19"},
{"primaryText":"item 20"}
]
}
]
}
Proactive loading
You must provide the correlationToken when your skill responds to a LoadTokenListData request. Alexa rejects the skill response if the expected correlationToken is not specified in exactly one SendTokenListData directive.
Omit the correlationToken when you send a set of list items not in response to a LoadTokenListData request.
UpdateIndexListData directive
Send a set of data operations to Alexa to insert, set, and delete list items in a data source that has already been sent to the device in a RenderDocument directive. You can include multiple changes in a single directive.
| Property | Type | Required | Description |
|---|---|---|---|
|
|
Directive |
Yes |
Set to |
|
|
String |
Yes |
The presentation token specified in the |
|
|
String |
Yes |
The identifier for the list to update with this response. |
|
Integer |
Yes |
The new version of the list following the update, used to maintain list consistency between the skill and Alexa. | |
|
Array |
Yes |
Individual operations to apply to the list, in array order. Alexa applies each item in it's entirety before processing the next operation in the array. Fully applying an operation includes making the change and updating the index locations of surrounding items. If a failure occurs when processing an operation, Alexa discards later operations in the array and discards further directives which attempt to update the items in the target datasource. |
{
"directives": [
{
"type": "Alexa.Presentation.APL.UpdateIndexListData",
"token": "developer-provided-token",
"listId": "my-list-id",
"listVersion": 3,
"operations": [
{
"type": "InsertItem",
"index": 10,
"item": {
"primaryText": "new item 9.5, inserted before item 10"
}
},
{
"type": "InsertMultipleItems",
"index": 12,
"items": [
{"primaryText":"first of three new items, inserted before item 12"},
{"primaryText":"second of three"},
{"primaryText":"third of three"}
]
},
{
"type": "SetItem",
"index": 14,
"item": {"primaryText":"Replacement text for item 14"}
},
{
"type": "DeleteItem",
"index": 16
},
{
"type": "DeleteMultipleItems",
"index": 17,
"count": 2
}
]
}
]
}
listVersion
The new version of the list following the update, used to maintain list consistency between the skill and Alexa. Alexa assumes all lists start at version 0, so the first UpdateIndexListData directive issued for a particular list sets listIndex to 1. Alexa buffers any UpdateIndexListData directives specifying an out-of-sequence listVersion until the missing or intermediate directives are received and processed.
This field is required for UpdateIndexListData but optional for SendIndexListData in some cases:
- When you don't do any insert, set, or delete updates on the list, you don't need to populate this value.
- When you do perform insert, set, or delete operations on the list, you must populate this value for all
SendIndexListDatadirectives.
Therefore, for a particular list, Alexa discards the following:
- All
UpdateIndexListDatadirectives received after aSendIndexListDatadirective which didn't specify alistVersion. - All
SendIndexListDatadirectives that don't specify a listVersion after receipt of aUpdateIndexListDatadirective.
operations
Enumeration of possible update operations.
InsertItem
Inserts a single item into the data source at the specified index.
You can insert items within the range of the list or add the items to the end of the list. Attempts to insert items at non-adjacent indexes results in an error. For example, if the current indexes range from M to N, you can insert items into in the range M to N+1.
| Field | Type | Required | Description |
|---|---|---|---|
|
|
Integer |
Yes |
The index at which to insert the item in the existing list. All existing list items at indexes greater or equal to the insert index increase by one. If defined, the value of |
|
|
Object |
Yes |
The item data to include at the specified list index. |
For example, the initial data source had 10 items with indexes 0-9. An InsertItem operation with index set to 5 does the following:
- Inserts the new
itemat position 5. - Updates the
indexfor the existing items 5-9 to 6-10. The original item 5 becomes 6, the original 6 becomes 7, and so on. - Updates the
maximumExclusiveIndexproperty for the data source from 10 to 11.
InsertMultipleItems
Inserts an array of items at the specified index.
You can insert items within the range of the list or add the items to the end of the list. Attempts to insert items at non-adjacent indexes results in an error. For example, if the current indexes range from M to N, you can insert items into in the range M to N+1.
| Field | Type | Required | Description |
|---|---|---|---|
|
|
Integer |
Yes |
The index at which to insert the first of the specified items in the existing list, with the rest of the items inserted at sequentially increasing indexes. All existing list items at indexes greater or equal to the insert index increase by the length of the |
|
|
Array |
Yes |
The array of item data to include at the specified list index. |
For example, the initial data source had 10 items with indexes 0-9. An InsertMultipleItem operation with index set to 5 and 2 new items in items does the following:
- Inserts the two new items at positions 5 and 6.
- Adds 2 to the
indexfor the original items 5-9. The original item 5 becomes 7, the original item 6 becomes item 8, and so on. - Updates the
maximumExclusiveIndexproperty for the data source from 10 to 12.
SetItem
Replace the item at the specified index with the provided item.
| Field | Type | Required | Description |
|---|---|---|---|
|
|
Integer |
Yes |
The index of the item to replace in the existing list. The definition and indexes of all other items in the list are unchanged. An attempt to set an item at an unpopulated index results in an error. |
|
|
Object |
Yes |
The new item data for the specified list index. |
For example, the initial data source had 10 items with indexes 0-9. A SetItem operation with index set to 5 does the following:
- Replaces the existing item at position 5 with the new
item.
DeleteItem
Delete the item at the specified index.
| Field | Type | Required | Description |
|---|---|---|---|
|
|
Integer |
Yes |
The index of the item to delete in the existing list. All existing list items at indexes greater than the delete |
For example, the initial data source had 10 items with indexes 0-9. A DeleteItem operation with index set to 5 does the following:
- Deletes the existing item at position 5.
- Updates the
indexfor the existing items 6-9 to 5-8. The original item 6 becomes 5, the original item 7 becomes 6, and so on. - Updates the
maximumExclusiveIndexproperty for the data source from 10 to 9.
DeleteMultipleItems
Delete the specified count of items from the data source, beginning at the specified index.
| Field | Type | Required | Description |
|---|---|---|---|
|
|
Integer |
Yes |
The index of the first item to delete in the existing list, with the rest of the items deleted at sequentially increasing indexes. All existing list items at indexes greater than those which have are deleted decrease their index by the |
|
|
Integer |
Yes |
The number of items at sequentially increasing indexes to delete. |
For example, the initial data source had 10 items with indexes 0-9. A DeleteMultipleItems operation with index set to 5 and count set to 2 does the following:
- Deletes the original items at positions 5 and 6.
- Subtracts 2 from the
indexfor the original items 7-9. The original item 7 gets a new index of 5, the original item 8 becomes item 6, and and the original item 9 becomes 7. - Updates the
maximumExclusiveIndexproperty for the data source from 10 to 8.
Requests
The following table lists the requests available in the Alexa.Presentation.APL interface. The "Widget support" column indicates whether Alexa sends the request to your skill from a widget installed on the device.
| Request | Description | Widget support |
|---|---|---|
|
Alexa sends your skill a |
No | |
|
Alexa sends your skill a |
No | |
|
Sent to notify the skill about any errors that happened during APL processing. This request is for notification only. The skill can't return a response to a |
No | |
|
Alexa sends your skill an For a widget, the request includes the |
Yes |
LoadIndexListData request
Alexa sends your skill a LoadIndexListData request to ask for more list items for a dynamicIndexList data source. For example, your skill gets this request when the user scrolls near the end of the previously-loaded items.
| Property | Type | Required | Description |
|---|---|---|---|
|
|
String |
Yes |
Set to |
|
|
String |
Yes |
The presentation token specified in the RenderDocument directive sent to Alexa. |
|
|
String |
Yes |
An Alexa-generated identifier used to correlate requests with their corresponding response directives. Include this when you respond with a |
|
|
String |
Yes |
The identifier of the list for which to fetch items. |
|
|
String |
Yes |
The lowest index of the items to fetch (inclusive) |
|
|
Integer |
Yes |
The number of items to fetch. |
{
"request": {
"type": "Alexa.Presentation.APL.LoadIndexListData",
"requestId": "amzn1.echo-api.request.1",
"timestamp": "2020-03-12T19:47:02Z",
"locale": "en-US",
"token": "developer-provided-token",
"correlationToken": "101",
"listId": "my-list-id",
"startIndex": 20,
"count": 10
}
}
Valid responses
You can respond to a LoadIndexListData request with a SendIndexListData directive.
LoadTokenListData request
Alexa sends your skill a LoadTokenListData request to ask for the next page of items for a dynamicTokenList data source. For example, your skill gets this request when the user scrolls near the end of the previously-loaded page of items.
| Property | Type | Required | Description |
|---|---|---|---|
|
|
String |
Yes |
Set to |
|
|
String |
Yes |
The presentation token specified in the |
|
|
String |
Yes |
An Alexa-generated identifier used to correlate requests with their corresponding response directives. Include this when you respond with a |
|
|
String |
Yes |
The identifier of the list for which to fetch items. |
|
|
String |
Yes |
A token associated with the items to fetch. You determine the string to use for the |
{
"request": {
"type": "Alexa.Presentation.APL.LoadTokenListData",
"requestId": "amzn1.echo-api.request.1",
"timestamp": "2021-03-12T19:47:02Z",
"locale": "en-US",
"token": "developer-provided-token",
"correlationToken": "101",
"listId": "my-list-id",
"pageToken": "myListPage2"
}
}
Valid responses
You can respond to a LoadTokenListData request with a SendTokenListData directive.
RuntimeError request
Sent to notify the skill about any errors that happened during APL processing. This request is for notification only. The skill can't return a response to a RuntimeError request.
| Property | Type | Required | Description |
|---|---|---|---|
|
|
String |
Yes |
Set to |
|
|
String |
No |
The presentation token specified in the RenderDocument directive sent to Alexa. |
|
Array |
Yes |
An array of reported errors. |
{
"type": "Alexa.Presentation.APL.RuntimeError",
"token": "developer-provided-token",
"errors": [
{
"type": "LIST_ERROR",
"reason": "LIST_INDEX_OUT_OF_RANGE",
"listId": "my-list-id",
"listVersion": 3,
"operationIndex": 3,
"message": ""
}
]
}
errors
| Property | Type | Required | Description |
|---|---|---|---|
|
String |
Yes |
Polymorphic error type indicator. | |
|
String |
Yes |
Describes the reason for the error that occurred. | |
|
|
String |
Yes |
A human-readable description of the error. |
type
Polymorphic error type indicator. Each error type can have type-specific parameters.
| Property | Description |
|---|---|
|
|
Errors related to processing a dynamicIndexList data source. |
reason
Error type specific failure reasons. Generic values available for any type:
- INTERNAL_ERROR – unexpected issue in the Alexa service.
LIST_ERROR
For possible reasons see: Error cases.
| Field | Type | Required | Description |
|---|---|---|---|
|
|
String |
Yes |
Contains the identifier of the list which encountered the error. |
|
|
String |
No |
Contains the listVersion specified by the update which encountered the error (when known) |
|
|
Integer |
No |
Contains the index of the operation which caused the error (when known) |
UserEvent request
Alexa sends your skill an Alexa.Presentation.APL.UserEvent request when an event on the device triggers the SendEvent command. This lets your skill service receive messages in response to the user's actions on the device. You can use event handlers on components in your document to trigger SendEvent. For example, the TouchWrapper component has an onPress event handler. You can set this handler to the SendEvent command to get a UserEvent request when a user touches the component on the viewport.
The UserEvent request includes information about the component and the event that triggered the SendEvent command. When you define SendEvent in a component's event handler, you can specify the information you want to get in the corresponding UserEvent request. Use this in your event handler in your code.
UserEvent properties
| Property | Type | Description |
|---|---|---|
|
|
String |
Always set to |
|
|
String |
Token provided with the |
|
|
Array of values |
Array of values specified in the |
|
|
Object |
Information about the APL component and event handler (if applicable) that was the source of this event. |
|
|
Object |
Value of each component identified in the |
|
|
String |
Applies to widgets. A generated token that identifies the widget. Use this value to identify the widget if you respond with |
Standard APL document UserEvent request example
The following example shows part of an APL document that sends an event to a skill when the user presses one of the TouchWrapper components rendered by the Sequence component via touch or a d-pad on a remote control.
{
"type": "Sequence",
"id": "myCustomSequence",
"height": "100vh",
"data": "${payload.templateData.properties.animalList}",
"numbered": true,
"item": {
"type": "TouchWrapper",
"id": "animalListTouchWrapper",
"item": {
"type": "Text",
"text": "${data.textToShow}"
},
"onPress": [
{
"type": "SendEvent",
"arguments": [
"listItemPressed",
"${ordinal}",
"${data.dataToSend}"
]
}
]
}
}
The Sequence uses a data source called templateData to display a series of items in the Sequence and define the data to include in the UserEvent. The following example illustrates this data source.
{
"templateData": {
"properties": {
"animalList": [
{
"textToShow": "Aardvark",
"dataToSend": "animalKey123"
},
{
"textToShow": "Aardwolf",
"dataToSend": "animalKey124"
},
{
"textToShow": "Baboon",
"dataToSend": "animalKey202"
}
]
}
}
}
In the above example, the arguments array for the SendEvent command specifies three items:
- The static text "
listItemPressed" - The
ordinalproperty from the data-binding context. This property is available since theTouchWrapperis a child component of aSequence. - The value of the item's
dataToSendproperty, from the data source.
Therefore, when the user selects the second item ("Aardwolf"), the skill gets a UserEvent request that looks like the following.
{
"version": "1.0",
"session": {},
"context": {},
"request": {
"type": "Alexa.Presentation.APL.UserEvent",
"requestId": "amzn1.echo-api.request.1",
"token": "token-provided-with-RenderDocument",
"timestamp": "2020-01-17T16:48:11Z",
"locale": "en-US",
"arguments": [
"listItemPressed",
2,
"animalKey124"
],
"components": {},
"source": {
"type": "TouchWrapper",
"handler": "Press",
"id": "animalListTouchWrapper"
},
}
}
Widget UserEvent request example
The following example shows a UserEvent request sent by a widget. The request includes a generated token and presentationUri.
{
"request": {
"type": "Alexa.Presentation.APL.UserEvent",
"requestId": "amzn1.echo-api.request.1",
"timestamp": "2022-04-07T21:51:19Z",
"locale": "en-US",
"arguments": [
{
"itemId": "ItemIDForSmokedWildSalmon"
}
],
"components": {},
"source": {
"type": "TouchWrapper",
"handler": "Press",
"id": "saveItemButton",
"value": false
},
"token": "f1cf2427-1-1-1-1",
"presentationUri": "widget://amzn1.ask.skill.1_development/MyWidgetSandbox/f1cf2427-1-1-1-1"
}
}
Get component data in the UserEvent
In addition to the data provided in the source and arguments properties, you can also get information about other components displayed on the viewport. To do this, assign each component an identifier with the id property. Then include the id for each component you want in the components array in your SendEvent command.
For example, each component has a checked state that can be true or false. You can use the SetValue command to change the checked state in response to user interaction. The following AlexaButton example toggles the checked state and changes the button text when the user selects the button.
{
"type": "AlexaButton",
"id": "idForTheToggleButton",
"buttonText": "Toggle button: false",
"primaryAction": [
{
"type": "SetValue",
"componentId": "idForTheToggleButton",
"property": "checked",
"value": "${!event.source.value}"
},
{
"type": "SetValue",
"componentId": "idForTheToggleButton",
"property": "buttonText",
"value": "Toggle button: ${!event.source.value}"
}
],
"spacing": "@spacingSmall",
"alignSelf": "center"
}
Then, a separate TouchWrapper in the document triggers SendEvent and includes the button ID idForTheToggleButton in the components array, as shown in the following example.
{
"type": "TouchWrapper",
"id": "idForTheTouchWrapper",
"spacing": "@spacingSmall",
"alignSelf": "center",
"onPress": [
{
"type": "SendEvent",
"arguments": [
"textWasPressed",
"Send this data to the skill"
],
"components": [
"idForTheToggleButton",
"idForTheTextComponent"
]
}
],
"item": {
"type": "Text",
"id": "idForTheTextComponent",
"color": "@colorAccent",
"text": "Click to send a UserEvent to the skill."
}
}
The user can select the toggle button repeatedly to flip its state between true and false. When the user then selects the "Click to send…" text, your skill receives the following UserEvent. Note that components includes idForTheToggleButton with its current checked state:
{
"type": "Alexa.Presentation.APL.UserEvent",
"requestId": "amzn1.echo-api.request.1",
"timestamp": "2020-01-20T22:46:04Z",
"locale": "en-US",
"arguments": [
"textWasPressed",
"Send this data to the skill"
],
"components": {
"idForTheTextComponent": "Click to send a UserEvent to the skill.",
"idForTheToggleButton": true
},
"source": {
"type": "TouchWrapper",
"handler": "Press",
"id": "idForTheTouchWrapper"
},
"token": "token-provided-with-RenderDocument"
}
For an additional example that illustrates how you could create a handler for UserEvent with the ASK SDK, see Handle a UserEvent request in Use Alexa Presentation Language with the ASK SDK v2.
Interaction mode for widgets
The interaction mode for a user event defines the capabilities that you can use in your response to that event. You set the mode with the interactionMode flag on the flags property of the SendEvent command.
The interactionMode flag accepts one of two values:
STANDARD– Your widget can launch a full skill experience. For example, you could include a button that launches your skill and continues the skill session. With the standard interaction mode, your skill can return any standard response from the request, just as you would for aLaunchRequestorIntentRequest.INLINE– Your widget can perform actions based on the event, but can't open a full skill experience or return output speech. For example, a button that stores data for later and silently refreshes the data displayed in the widget uses the inline mode. An event with the inline interaction mode restricts the type of responses you can send.
Valid response types
For a standard APL document, your skill can respond to the UserEvent request with a standard response. You can include any custom skill directives except for Dialog.Delegate.
The valid responses for a UserEvent sent from a widget depend on the interaction mode for the event:
STANDARD- The response can be a standard response with speech and directives.
- You can include any custom skill directives except for
Dialog.Delegate.
INLINE(default)- The
shouldEndSessionflag must betrue. The skill session ends with the response. - The response can't include any output speech.
- The response can't include any skill directives except for the
Alexa.Presentation.APL.ExecuteCommandsdirective.
- The
For both modes, your handler for the UserEvent can use the Data Store REST API to update the data store for the widget. For details, see the Data Store REST API Reference.
UserEvent sent to your skill doesn't include the data provided in the flags property of the SendEvent command. Be sure to provide information in the SendEvent command so that your code can identify the source of the UserEvent request and respond appropriately.Error cases
When an error occurs, your skill receives a RuntimeError request.
The following table summarizes the possible error cases.
| Error description | Exception reason | System response |
|---|---|---|
|
UpdateIndexListData is missing a required field |
N/A |
Alexa rejects the incoming directive. |
|
The directive payload, or any list item exceeds the maximum permitted length |
N/A |
Alexa rejects the incoming directive. |
|
UpdateIndexListData has an unrecognized token or listId |
|
Alexa discards the incoming directive. |
|
UpdateIndexListData or SendIndexListData specifies a listVersion which is greater than expected |
N/A |
The directive is sent to Alexa where it is buffered until intermediate directives are received & processed. |
|
The directive is buffered longer than a specified duration. |
|
Alexa continues to buffer the directive. |
|
Alexa is unable or unwilling to buffer further out-of-order directives,for example, due to insufficient memory |
|
Alexa discards the buffered directive with the greatest listVersion. |
|
UpdateIndexListData or SendIndexListData specifies a listVersion which is lower than expected |
|
Alexa discards the incoming directive. |
|
Skill returns an UpdateIndexListData with an unrecognized operation type |
|
Alexa discards the incoming directive and places the list in 'failed' state where it accepts no further updates. |
|
Skill returns an UpdateIndexListData directive for a DynamicTokenList |
|
Alexa discards the incoming directive and places list in ‘failed’ state where it accepts no further updates. |
|
Skill returns an insert, set or delete operation with index outside of the range of permitted values. |
|
Alexa discards the incoming directive and places the list in 'failed' state where it accepts no further updates. |
|
A list receives an UpdateIndexListData directive after a SendIndexListData directive which did not specify a listVersion. |
|
Alexa discards the incoming directive and places the list in 'failed' state where it accepts no further updates. |
|
A list receives a SendIndexListData directive which does not specify a listVersion after a UpdateIndexListData directive. |
|
Alexa discards the incoming directive and places the list in 'failed' state where it accepts no further updates. |
|
SendTokenListData or SendIndexListData specifies an unexpected correlationToken. |
N/A |
The device discards the response directive. |
|
Device does not receive a SendTokenListData response for a correlationToken within a configured timeout. |
|
If no response after several retries, the device assumes that the end of the list has been reached. An exception is reported for each retry attempt. |
|
The device does not receive a SendIndexListData response for a correlationToken within a configured timeout. |
|
If no response after several retries, then the device assumes that no further scrolling is possible beyond the requested position in the list (unless the device has already loaded items beyond this point, in which case the device is to show 'blank' list entries at the requested indexes). |
|
listId or pageToken value(s) are inconsistent with those expected for the correlationToken. |
|
The device ignores listId and pageToken values and uses the values expected for the correlationToken. |
|
SendTokenListData directive contains no items, and does contain a nextPageToken. |
|
The device scrolls using the nextPageToken. |
|
The SendIndexListData directive contains no items. |
|
Alexa retries the lazy load request several times, or until the response min/max index indicates that the end of the list has been reached. |
|
SendTokenListData directive contains no items, and does not contain a nextPageToken. |
N/A |
The device assumes the end of the list has been reached (in the request scroll direction). |
|
Directive for a previously-requested page returns different nextPageToken than that in the previous response. |
|
The device discards the new nextPageToken. |
|
The nextPageToken duplicates a token already used elsewhere in the list. |
|
The device discards the duplicated token value and assumes field was null, and therefore has reached the end of the list. |
|
Directive for a previously-requested page returns a different number of items than those in the previous response. |
|
The device expands or contracts the list as if the newly-returned number of items had been returned in the previous response. |
|
Any field is outside the integer value range. |
N/A |
Alexa discards the response directive. |
|
The response specifies items at indexes which are already populated in the device's cache. |
|
Discard any item data for indexes which are already populated in the device cache. |
|
The response contains items with a different startIndex than those requested. |
N/A |
Accept the items at the reported startIndex (assuming that no items were previously loaded at these locations), and continue from the incoming index. |
|
The maximumExclusiveIndex value is exceeded by returned item indexes. |
|
Device displays items included in the maximumExclusiveIndex range, i.e. from startIndex to maximumExclusiveIndex - 1. |
|
The response contains a different minimumInclusiveIndex or maximumExclusiveIndex than previously reported non-null value(s). |
|
Device discards all previously loaded list items and repopulates the list afresh, starting with the startIndex, minimumInclusiveIndex & maximumExclusiveIndex parameters and item details as specified in the response. |
|
The SendIndexListData response contains more items than the number requested. |
N/A |
Process as if the items had been requested and discard items at already-populated indexes. |
|
The SendIndexListData response contains fewer items than the number requested. |
N/A |
Make a followup request for the remaining items (assuming that min/max indexes do not indicate that the end of the list has been reached). |
Viewport object in the skill request
Every request sent to your skill includes information about the supported viewports for the user's device. You can use this information in your code to craft appropriate responses.
For a device with a screen, the viewport information is in the context.Viewport object.
Viewport information is also available in the data-binding context in the viewport property. The specific information available in the data-binding context differs from the information available in the skill request. For details, see Viewport Object in the Data-binding Context.
- Use the
context.Viewportobject in the skill request when you need viewport information in your skill code. - Use the
viewportproperty in the data-binding context when you need viewport information in your APL document, such as for creating awhencondition to show a particular component only on certain viewports. See Viewport Object in the Data-binding Context
This example shows a skill request with the context.Viewport object, with some details removed for brevity:
{
"version": "1.0",
"session": {},
"context": {
"Viewports": [
{
"type": "APL",
"id": "main",
"shape": "RECTANGLE",
"dpi": 213,
"presentationType": "STANDARD",
"canRotate": false,
"configuration": {
"current": {
"mode": "HUB",
"video": {
"codecs": [
"H_264_42",
"H_264_41"
]
},
"size": {
"type": "DISCRETE",
"pixelWidth": 1280,
"pixelHeight": 800
}
}
}
}
],
"Viewport": {
"experiences": [
{
"arcMinuteWidth": 346,
"arcMinuteHeight": 216,
"canRotate": false,
"canResize": false
}
],
"mode": "HUB",
"shape": "RECTANGLE",
"pixelWidth": 1280,
"pixelHeight": 800,
"dpi": 213,
"currentPixelWidth": 1280,
"currentPixelHeight": 800,
"touch": [
"SINGLE"
],
"video": {
"codecs": [
"H_264_42",
"H_264_41"
]
}
},
"Extensions": {
"available": {
"aplext:backstack:10": {}
}
},
"System": {}
},
"request": {}
}
Viewport properties
The following properties are defined in the Viewport object.
| Property | Type/Values | Description |
|---|---|---|
|
|
Array of |
Different modes in which the customer is expected to interact with the viewport. |
|
|
One of: |
The mode for the device. |
|
|
|
Shape of the viewport. |
|
|
Integer |
Height of the viewport in pixels. |
|
|
Integer |
Width of the viewport in pixels. |
|
|
Integer |
Width of the viewport in pixels that is currently in use. |
|
|
Integer |
Height of the viewport in pixels that is currently in use. |
|
|
Integer |
Pixel density of the viewport. |
|
|
Array of strings |
Touch events that the viewport supports. |
|
|
Array of strings |
Input mechanisms for interacting with the viewport. |
|
|
Object |
Specification of which technologies are available for playing video on a device |
experiences
The experiences property contains a list of experience types supported by the device. The experience types depend on the modes supported by a viewport. You can use this information to optimize your skill's behavior for a specific experience. For example, a tablet device might have two different experiences: one for when it is docked and the other for when the customer is holding it. In these cases the skill's visual response should be optimized for both experiences, as the device owner can arbitrarily switch between the experiences.
experience properties
| Property | Type/Values | Description |
|---|---|---|
|
|
Boolean |
Whether the viewport can be rotated through 90, 180, and 270 degrees. |
|
|
Boolean |
Whether the viewport can be resized. |
The experiences property also reports the deprecated arcMinuteWidth and arcMinuteHeight properties. Although these properties are available, they are deprecated. Use the mode property to determine the viewing distance and available modalities for the device instead.
mode
Represents the type of device.
pixelHeight and pixelWidth
The pixelHeight and pixelWidth properties represent the number of pixels present in the viewport at its maximum height and width. These values assume a static device orientation, and express the entire viewport size regardless of whether areas of the viewport are currently in use by other applications.
currentPixelWidth and currentPixelHeight
The currentPixelWidth and currentPixelHeight properties represent the number of horizontal and vertical pixels that are available for Alexa to render an experience. These values also assume a static device orientation.
shape
The shape of the screen is either ROUND or RECTANGLE.
dpi
The display-independent pixel (dp) measurement of a screen is an artificial value that represents the visual size of the screen assuming that the screen is held at a mobile-phone viewing distance and has a pixel density of approximately 160 pixels per inch. Two screens viewed at the same distance with the same physical size have approximately the same dp dimensions regardless of the actual pixel density of the screen.
The dots-per-inch (dpi) of a viewport is an artificial value that reflects the visual size of a point or pixel relative to the observer, and it does not match the actual pixels-per-inch size of the screen. The formula for dpi is:
dpi = 160 * (pixelSize / dpSize)
For simplicity, dpi values are simplified to fall into consistent buckets of 120, 160, 240, 320, and so forth.
touch
The touch property represents what kind of touch inputs the device supports. The touch array can contain the following values:
SINGLE- indicates that the device supports single-touch inputs
keyboard
The keyboard property represents physical button input mechanisms that can be used to interact with the viewport. The keyboard array can contain the following values:
DIRECTION- there are inputs for the up/down/left/right directions as well as a button to select whatever is at the current location
video
The video property details which technologies are available for playing video on a device. Use the video properties to determine what types of video resources to send in an APL response. For example, your skill's APL response could return video resources with different encodings depending on the video codec level that a device supports.
Note that some devices with screens do not support video playback. In this case, the video property is not present. If your skill includes video, be sure to check for this property and provide an appropriate experience for devices that do not support video. If you send a Video to a device that does not support video, the component remains on the screen, but displays no content so users will see a blank area on the screen.
video properties
| Property | Type/Values | Description |
|---|---|---|
|
|
Array of Strings |
The video codecs that the output device supports. Supported values:
|
Access the viewport information in your code
The Alexa Skills Kit SDKs includes functions that use data in the skill request context to calculate a viewport profile for the device. These functions are deprecated and aren't recommended. Instead, use the @viewportProfile resource in the viewport profiles package to create APL documents that adapt to different devices.
For details about the @viewportProfile resource and responsive documents, see the following:
The following functions are deprecated and not recommended:
- Node –
getViewportProfile - Python –
get_viewport_profile - Java –
ViewportUtils.getViewportProfile
For a list of deprecated features in the Alexa Skills Kit, see Deprecated Features.
APL visual context in the skill request
The Alexa Presentation Language (APL) visual context provides your skill with information about the content displayed on the screen when the user invokes an intent or triggers a user event. Your skill can use the context to determine the state of on-screen elements, such as which parts of a list are visible on the screen.
A request sent to your skill includes the visual context when the user's device has a screen and the screen is displaying an APL document your skill sent with the RenderDocument directive.
The visual context is available in the Alexa.Presentation.APL property within the top-level context property in the request.
{
"version": "1.0",
"session": {},
"context": {
"Viewports": [],
"Alexa.DataStore.PackageManager": {
"installedPackages": []
},
"Viewport": {},
"Extensions": {},
"System": {},
"Alexa.Presentation.APL": {
"token": "helloworldWithButtonToken",
"version": "AriaRuntimeLibrary-2023.2.449.0",
"componentsVisibleOnScreen": [
{
"uid": ":1000",
"position": "960x480+0+0:0",
"type": "text",
"tags": {
"viewport": {}
},
"children": [
{
"id": "fadeHelloTextButton",
"uid": ":1002",
"position": "273x76+344+360:0",
"type": "text",
"tags": {
"focused": false,
"clickable": true
},
"entities": []
}
],
"entities": []
}
]
}
},
"request": {}
}
For details about the objects provided in the visual context, see APL Visual Context in the Skill Request.
Service Interface Reference (JSON)
Request Format and Standard Request Types:
- Request and Response JSON Reference
- Request Types Reference (LaunchRequest, IntentRequest, SessionEndedRequest)
- Alexa.Presentation.APL Interface (this document)
- Alexa.Presentation.APLT Interface
- Alexa.Presentation.HTML Interface
- AudioPlayer Interface
- Connections Interface
- Dialog Interface
- Messaging Interface
- PlaybackController Interface
- VideoApp Interface
Related topics
Last updated: Nov 28, 2023