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
requestedExtensions
property.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
RenderDocument
with any of the of theDialog
directives except forDialog.Delegate
. For example, you can useDialog.ElicitSlot
to 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
RenderDocument
with directives from the following interfaces:AudioPlayer
Display
VideoApp
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
AnimateItem
command changes the opacity of the componenthelloTextComponent
to 0 over 3 seconds to make it fade from view. - The second
AnimateItem
command changes the opacity of the componentnewHelloTextComponent
from 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
token
you provide must match thetoken
you provided with theRenderDocument
directive that sent the corresponding document. - To target a widget, the
presentationUri
must 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
token
matches in both directives. -
When you return
ExecuteCommands
in a separate response, the device runs the commands against the document currently displayed on the viewport. Thetoken
must match thetoken
used in the earlierRenderDocument
directive.Before you send
ExecuteCommands
in this scenario, check the visual context in the request to confirm that the document is currently displayed. You can get thetoken
for the currently displayed document from thecontext.["Alexa.Presentation.APL"].token
property 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:
AudioPlayer
Dialog
Display
VideoApp
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
SendIndexListData
directives.
Therefore, for a particular list, Alexa discards the following:
- All
UpdateIndexListData
directives received after aSendIndexListData
directive which didn't specify alistVersion
. - All
SendIndexListData
directives that don't specify a listVersion after receipt of aUpdateIndexListData
directive.
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
item
at position 5. - Updates the
index
for the existing items 5-9 to 6-10. The original item 5 becomes 6, the original 6 becomes 7, and so on. - Updates the
maximumExclusiveIndex
property 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
index
for the original items 5-9. The original item 5 becomes 7, the original item 6 becomes item 8, and so on. - Updates the
maximumExclusiveIndex
property 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
index
for 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
maximumExclusiveIndex
property 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
index
for 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
maximumExclusiveIndex
property 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
ordinal
property from the data-binding context. This property is available since theTouchWrapper
is a child component of aSequence
. - The value of the item's
dataToSend
property, 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 aLaunchRequest
orIntentRequest
.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
shouldEndSession
flag 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.ExecuteCommands
directive.
- 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.Viewport
object in the skill request when you need viewport information in your skill code. - Use the
viewport
property in the data-binding context when you need viewport information in your APL document, such as for creating awhen
condition 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