APL Standard Commands (APL 2022.2)


(This is not the most recent version of APL. Use the Other Versions option to see the documentation for the most recent version of APL)

Common Properties

A single command is encoded as a JSON object. All commands contain the following properties.

Property Type Default Description

type

String

REQUIRED

Type of the command

description

String

""

Optional documentation for this command

delay

Integer

0

Delay time in milliseconds before this command runs. Must be non-negative. Defaults to 0.

screenLock

Boolean

false

If true, disable the interaction timer.

sequencer

String

""

Specify the sequencer that should run this command.

when

Boolean

true

Conditional expression. If this evaluates to false, the command is skipped. Defaults to true.

type

Specifies the particular command to run. This may be a pre-defined primitive command types or a user-defined command.

delay

The delay value is the amount of time in milliseconds inserted before running this command. The delay value must be a non-negative integer, which if not specified, defaults to 0. The delay value is ignored if the when property resolves to false, or if the command runs from within an event handler.

screenLock

If true, the interaction timer is disabled while this command runs. When a command with screenLock=true finishes running, the interaction timer is reset to 0.

The screenLock applies to the entire extent of the command including any defined delay. For example, the following command holds the screen lock for 30 seconds:

{
  "type": "Idle",
  "delay": 30000,
  "screenLock": true,
}

sequencer

If specified, the sequencer property names the sequencer that this command should run on. The sequencer selection rules are (in order):

  1. If the sequencer is specified, the command runs in normal mode on that sequencer.
  2. Else, if the command is running in fast mode, run normally in fast mode
  3. Else, if the command is a subcommand of a Sequential or Parallel command, run in normal mode on the sequencer of the Sequential or Parallel command.
  4. Else, run the command in normal mode on the "MAIN" sequencer.

For details about the command sequencer, see Command sequencing

when

If when is set to true, run the command. If false, ignore the command. Commands that are ignored also ignore the screenLock property.

Reinflation strategy

The Reinflate command reinflates the document, which by default ends any running commands. You can change this default by defining a sequencer for the command, and preserving that sequencer with the preservedSequencers property on the Reinflate command.

For any command, when the command runs on a preserved sequencer and the Reinflate command runs, the remaining delay for the command is saved.

For example, assume an Idle command has delay set to 2000 ms and 1000 ms have elapsed when a reinflate occurs. After reinflation, the Idle command continue to run for the remaining 1000 ms specified in delay.

All commands can have a delay. Some commands take time to run, such as AutoPage and SpeakItem. These commands resume after reinflation when run on a preserved sequencer. Refer to the reinflation strategy section for each of these commands to understand how the command behaves when it is preserved during reinflation.

AnimateItem

AnimateItem requires APL 1.1 or later. Provide an alternate experience for devices running older versions of APL.

Runs a fixed-duration animation sequence on one or more properties or bound values of a single component. For example:

{
  "type": "AnimateItem",
  "easing": "ease-in-out",
  "duration": 600,
  "componentId": "myFlyingComponent",
  "value": [
    {
      "property": "opacity",
      "to": 1
    },
    {
      "property": "transform",
      "from": [
        {
          "translateX": 200
        },
        {
          "rotate": 90
        }
      ],
      "to": [
        {
          "translateX": 0
        },
        {
          "rotate": 0
        }
      ]
    }
  ]
}

Components support animating opacity and transform properties. The from value isn't required for opacity, but you must provide it for transforms.

To define a custom easing curve, you can write:

{
  "type": "AnimateItem",
  "easing": "path(0.25, 0.6, 0.5, 0.8, 0.75, 0.9)",
  "duration": 1000,
  "value": {
    "property": "opacity",
    "to": 1
  }
}

You can animate bound properties. The following example displays a Frame as a green box in the center of the viewport. The Frame defines an animation in which tapping the component animates the SIDE bound value. The animation changes the size and color of the Frame smoothly over one second.

Click the green box in the simulator pane to see the animation. Click a second time to see the same animation in reverse.


You can also animate parameters passed to a vector graphic.

The following example defines a box with a thin stroke value as a vector graphic. Tapping the vector graphic starts an animation in which the line thickness of the box expands until the box is solid. Then the animation reverses to return to the original shape.

Click the blue box in the simulator pane to see the animation.


AnimateItem defines the following properties in addition to normal command properties:

Property Type Default Description

componentId

String

SELF

The id of the component.

duration

Integer

REQUIRED

The duration of the animation (in milliseconds)

easing

linear, ease-in, …

linear

Specify an easing curve.

repeatCount

Integer

0

Number of times to repeat.

repeatMode

restart, reverse

restart

How repeated animations will play.

value

Array of animated properties

REQUIRED

An array of animated component properties.

In fast mode, the AnimateItem command jumps ahead to the end state of the animation. When an AnimateItem command stops, the animation jumps ahead to the end state; refer to repeatMode for a discussion of how to calculate the end state.

componentId

The ID of the component. If omitted, the component issuing the AnimateItem command is used.

duration

The duration in milliseconds of a single pass of the animation. If the repeatCount property is set to greater than 0, the total duration of the animation will be the product of the duration and one more than the repeat count. For example, the following animation will have a total duration of 10 seconds:

{
  "type": "AnimateItem",
  "duration": 1000,
  "repeatCount": 9,
  "repeatMode": "reverse",
  "value": {
    "property": "opacity",
    "from": 0,
    "to": 1
  }
}

easing

An easing curve specifies how the value of the parameter changes over time. The curve must be a function starting at (0,0) and ending at (1,1). Two standard general ways of writing an easing curve are defined:

  1. cubic-bezier(x1,y1,x2,y2): Following the CSS standard, this defines a cubic Bézier curve with starting point (0,0) and ending point (1,0). The parameterized values (x1, y1) and (x2, y2) defined the interior control points of the curve and are normally between 0 and 1.
  2. path(x1,y1,...,xN,yN): A linear-piecewise function from (0,0) to (1,1). The x values must be in ascending order and between 0 and 1; the y values may be arbitrary. The end values of (0,0) and (1,1) are implicit.

The following easing curves are pre-defined:

Name Equal to
linear path()
ease cubic-bezier(0.25, 0.10, 0.25, 1.00)
ease-in cubic-bezier(0.42, 0.00, 1.00, 1.00)
ease-out cubic-bezier(0.00, 0.00, 0.58, 1.00)
ease-in-out cubic-bezier(0.42, 0.00, 0.58, 1.00)

repeatCount

The repeatCount defines how many times an animation will repeat before the command stops. By default, the repeatCount is set to 0; the animation will play through once and stop.

repeatMode

The repeatMode defines whether animations will be played from start to finish each time or if the animation will play backwards to the start each alternative time. The following repeat modes are defined:

Name Description
restart The animation starts over from the original value on each repeat.
reverse The animation reverses direction each time.

The end state of an animation is a function of the repeatCount and repeatMode. If the repeatMode is reverse and the repeatCount is an odd number, the animation end state will be the same as its starting state. In all other cases the end state will be the "natural" end state assigned as the to value.

A prematurely stopped animation always "jumps" to its end state.

value

The array of animated properties. Each element in the array has the following form:

Property Type Required Description
from Number No The starting value of the property
property String Yes The name of the property to animate
to Number Yes The ending value of the property

A property animation is defined by the to/from properties or the inputRange/outputRange properties. If you don't specify a "from" value, the current value of the property is used.

There are a few special cases to consider with the transform property. First, the transform property does not implicitly define a from property; both the from and to properties must be set.

Second, interpolating between smoothly between transformations requires that the same series of transformation operations appear in the from list and the to list and in the same order. For example:

"from": [ { "translateX": 30 }, { "rotate": 90 }],
"to": [ { "translateY": 30 }, { "rotate": 45 }]

is a valid from/to transformation because each array contains a translation followed by a rotation. A non-working example:

"from": [ { "translateX": 30 }, { "scale": 1 }, { "rotate": 90 }],
"to": [ { "scale": 2 }, { "rotate": 45 }]

In this case the arrays don't match; they have different lengths and the first element differs between the arrays. The APL author may expect the system to automatically fill in the "missing" { "translateX": 0 } transformation at the start of the to array, but the APL runtime is not clever enough to automatically find and fix the difference.

Reinflation strategy

When the Reinflate command runs, the AnimateItem can resume after Alexa reinflates the document. The command resumes when it runs on a sequencer that is specified in the preservedSequencers array on Reinflate.

The following properties are saved:

  • repeatCount
  • value
  • componentId

This is the same behavior as preserving each of these properties for the target Component. For details about preserving component properties, see the preserve property.

If the target component doesn't exist in the reinflated hierarchy or if the property does not exist, then the command is ignored.

For example, assume the following AnimateItem command is running on the EXAMPLE_SEQUENCER sequencer (t = 0 ms).

{
  "type": "AnimateItem",
  "sequencer": "EXAMPLE_SEQUENCER",
  "duration": 1000,
  "easing": "linear"
  "componentId": "MyComponent"
  "repeatCount": 1,
  "value": {
    "property": "PROPERTY",
    "from": 0,
    "to": 1
    }
}

At t = 500 ms, Reinflate command runs and preserves the EXAMPLE_SEQUENCER sequencer. The document reinflates and the reinflated document has a component with the id MyComponent and bound value PROPERTY. The value for this property of MyComponent is set to 0.5 and the AnimateItem command continues to run its first iteration.

At t = 1 s, the second iteration of the command runs, setting the bound value to 0 and animating the value to 1.

AutoPage

The AutoPage command automatically progresses through a series of pages displayed in a Pager component. The AutoPage command finishes after the last page has been displayed for the requested time period.

The AutoPage command has the following properties in addition to the regular command properties.

Property Type Default Description

componentId

String

SELF

The id of the Pager to page through.

count

Integer

All pages in the pager

The number of pages to display.

duration

Integer

0

The amount of time (in milliseconds) to wait after advancing to the next page.

For example, to auto page through a Pager called mySportsPager:

  {
    "type": "AutoPage",
    "componentId": "mySportsPager",
    "duration": 1000,
    "delay": 500
  }

The above example first pauses for 500 milliseconds (the delay property), then advances to the next page, pauses for 1000 milliseconds (the duration property), and continues advancing and pausing until the final pause has completed. For example, if mySportsPager has three pages and initially displays page 1, then AutoPage does the following:

  • Displays page 1 for 500ms while waiting to start.
  • Changes to page 2 and pauses for 1000ms.
  • Changes to page 3 and pauses for 1000ms.

At this point the command is complete, so the Pager continues to display page 3 until another command or event causes a change.

The AutoPage command has no effect if the count is non-positive.

The AutoPage command does the following when it stops:

  • Moves the display ahead to the target page if the AutoPage command sequence is at least 50% complete.
  • Returns the display to the previous page if it is not at least 50% complete.

The onPageChanged command runs one time with the new page if the page has changed

The AutoPage command is ignored in fast mode.

componentId

The identifier of the Pager component. If omitted, the component issuing the AutoPage command is used.

count

The number of pages to display. If not specified, this defaults to the number of pages remaining. Wrapping is not supported; the count is internally clipped to fall in the range [0, pager.children.length - pager.currentIndex - 1].

duration

The amount of time to wait after advancing to the next page. Any animated transition between pages is not included in the duration and therefore increases the overall command run time.

Since the duration is applied after advancing to the next page, it does not apply to the first page of the pager. To delay the start of paging, use the standard command delay property.

Reinflation strategy

When the Reinflate command runs, the AutoPage command can resume after Alexa reinflates the document. The command resumes when it runs on a sequencer that is specified in the preservedSequencers array on Reinflate.

If the target component isn't a Pager in the reinflated hierarchy, the command is ignored.

If a page transition is running when the reinflation occurs, the command continues from the currently preserved position (if any) or 0 when reinflation completes.

To continue AutoPage from the same page where the command paused, explicitly preserve the pageIndex with the Pager

In case if it is desired to continue from the same page where command were paused - the pageIndex needs to be preserved explicitly with the preserve for the Pager.

ClearFocus

ClearFocus requires APL 1.1 or later. Provide an alternate experience for devices running older versions of APL.

Removes focus from the actionable component that is currently in focus. See Focused for the actionable components that can receive and lose focus.

Only one component may have focus at a time, so ClearFocus only ever affects one component.

When ClearFocus runs, the command removes focus from the component that has it, and sets that component's focused state to false.

The ClearFocus command has no additional properties to the regular command properties.

For example, to clear focus from any component that has it:

{
  "type": "ClearFocus"
}

The ClearFocus command runs in fast mode, but without any delay.

Finish

Finish requires APL 1.3 or later. Provide an alternate experience for devices running older versions of APL.

Closes the current APL document and exits. The finish command has no properties beyond the common command properties.

Running the finish command stops all other processing in APL, including any commands that are still running. For example, if you wish to both use SendEvent and Finish on a button press, you must write them in the following order:

{
  "onPress": [
    {
      "type": "SendEvent",
      "arguments": [
        "now stopping"
      ]
    },
    {
      "type": "Finish"
    }
  ]
}

If you write the commands in the reverse order, SendEvent never runs.

The finish command runs in both normal and fast mode.

Idle

The Idle command does nothing. Use as a placeholder or to insert a calculated delay in a longer series of commands. For example, consider this command.

  {
    "type": "Parallel",
    "commands": [
      {
        "type": "Idle",
        "delay": 3000
      },
      {
        "type": "SpeakItem",
        "componentId": "item7"
      }
    ]
  }

This command sequence speaks "item7". The use of the Idle command guarantees that the overall command will last at least 3000 milliseconds even if the speech ends earlier.

The type of the Idle command is Idle.

The idle command is ignored in fast mode

OpenURL

OpenURL requires APL 1.1 or later. Provide an alternate experience for devices running older versions of APL.

Open a URL. The OpenURL command, if successful, opens the specified URL in a web browser or other application on the device. You must provide a suitable URL that works on the current device. The OpenURL command has the following properties in addition to the regular command properties:

Property Type Default Description
source String REQUIRED The URL to open.
onFail Array of command [ ] Command to run if the URL fails to open.

For example, to open the Amazon home page in the browser on the device:

{
  "type": "OpenURL",
  "source": "https://www.amazon.com/",
  "onFail": {
    "type": "SetValue",
    "componentId": "errorText",
    "property": "text",
    "value": "Unable to open Amazon.com (${event.source.value})"
  }
}

Not all devices support opening a URL. If the device does not support opening URLs, the command is ignored and it does not run onFail commands. Check the value of the allowOpenURL in the data-binding context to determine if OpenURL is supported on the device.

The OpenURL command is ignored in fast mode.

source

The source property is a URL/URI suitable for launching an application on the local device. It may also be used with the http or https schema to open a web page in the local web browser.

onFail

The onFail property contains one or more commands to run if the URL cannot be opened. There is no guarantee that the onFail command will run within a time limit or that it will appear to be successful to the end user; for example, a URL could open a blank or error web page. However, the APL runtime should try to report failure within three seconds. The event generated for the onFail command has the following form:

"event": {
  "source": {
    "source": "OpenURL",
    "handler": "Fail",
    "value": NUMBER    // Platform-defined numerical error
  }
}

The event.source.value field passed to the onFail command will be set to a platform-defined numerical error code. This error code is not suitable for showing to the user (despite the example provided above), but may be used to send failure information back to the cloud skill through a SendEvent command.

Parallel

Run a series of commands in parallel. The Parallel command starts running all child commands simultaneously. The Parallel command is considered finished when all of its child commands have finished. When the Parallel command stops early, all currently running commands stop.

The type of the Parallel command is Parallel. The Parallel command has the following properties in addition to the common command properties.

Property Type Default Description
commands Array of commands REQUIRED An unordered list of command to run in parallel

In fast mode, the parallel command runs all of the sub-commands in parallel, but without delays (giving a net zero duration)

commands

An un-ordered array of commands to run in parallel. Once all commands have finished running, the Parallel command finishes. The delay value set for the Parallel command is added to the delay value set for each of the commands in the array. In the following example, the first SendEvent command starts after 1500 milliseconds, and the second SendEvent command after 750 milliseconds, which means the second SendEvent command starts before the first.

{
  "type": "Parallel",
  "delay": 500,
  "commands": [
    {
      "type": "SendEvent",
      "delay": 1000
    },
    {
      "type": "SendEvent",
      "delay": 250
    }
  ]
}

Reinflate

Reinflates the current document with updated configuration properties. Alexa rebuilds the entire document, following the same process as when initially displaying the document on the screen. Alexa creates a new, updated data-binding context with environment and viewport constants that match the new device configuration.

The Reinflate command has the following properties in addition to the common command properties.

Property Type Default Description

preservedSequencers

Array of command sequencers

[]

An array of named sequencers to preserve during reinflation.

Running Reinflate command stops all other processing in APL, including any commands that are running on sequencers not named in the preservedSequencers array. For details about sequencers and command sequencing, see Command sequencing.

For example, to run both SendEvent and Reinflate in the same handler, invoke SendEvent first. The following example sends a UserEvent request to the skill, and then reinflates the document.

{
  "onConfigChange": [
    {
      "type": "SendEvent",
      "sequencer": "ConfigSendEvent",
      "arguments": [
        "reinflating the APL document"
      ]
    },
    {
      "type": "Reinflate"
    }
  ]
}

If you write the commands the reverse order, the SendEvent never runs. The SendEvent command in this example defines a sequencer because the onConfigChange handler runs in fast mode. Fast mode ignores SendEvent.

The document and component-level onMount commands run after the document reinflates.

The Reinflate command runs in both normal and fast mode.

For details about using reinflate to support tablets, see Support Tablets and Other Devices that Can Change Size.

preservedSequencers

The preservedSequencers property specifies an array of command sequencers to continue to run during and after reinflation. You can preserve the sequencers you define. You can't preserve the default MAIN sequencer.

For example, assume your document invokes the SpeakList command. As Alexa reads the list items, the user's device triggers a configuration change, which invokes Reinflate. The default behavior in this scenario stops all running commands when the document reinflates, which stops the SpeakList audio playback.

To continue the audio playback in this scenario instead, you do the following:

  • Define a sequencer for the SpeakList command.
      {
        "type": "Speaklist",
        "componentId": "myListToSpeak",
        "start": 0,
        "count": 10,
        "sequencer": "SpeakListSequencer"
      }
    
  • Set the preservedSequencers property for the Reinflate command to the sequencer you defined.
      {
        "type": "Reinflate",
        "preservedSequencers": [ "SpeakListSequencer" ]
      }
    

Make sure that commands on preserved sequencers target components that exist in the reinflated hierarchy. Provide an id for the component, and use the preserve property to save the values of component properties and bindings.

When a preserved sequencer runs a command that doesn't resolve instantly, such as AnimateItem or Scroll, the command continues after reinflation if the target component exists in the reinflated hierarchy.

Any commands running on the preserved sequencer that target non-existent components are ignored during reinflation.

For details about how an individual command handles reinflation, see the reinflation strategy section for the specific command:

Extension commands don't support preservation.

For example, assume the following command is running on the "EXAMPLE_SEQUENCER" sequencer (t = 0):

{
  "type": "Sequential",
  "sequencer": "EXAMPLE_SEQUENCER",
  "commands": [
    {
      "type": "AnimateItem",
      "componentId": "MyComponent"
      "duration": 1000,
      "easing": "linear"
      "value": {
        "property": "opacity",
        "from": 0,
        "to": 1
        }
    },
    {
      "type": "SpeakItem",
      "componentId": "MyMissingComponent"
    },
    {
      "type": "SendEvent",
      "arguments": [ "finished" ]
    }
  ]
}

At t = 300 ms, a Reinflate command preserving the "EXAMPLE_SEQUENCER" sequencer runs. After reinflation, the reinflated hierarchy has a component with id MyComponent, but doesn't have a component with id MyMissingComponent. Because the reinflation happened before the AnimateItem finished, the component MyComponent has opacity set to 0.3. The AnimateItem command continues from where it left off and runs for 700 ms.

At t = 1 s, the SpeakItem command fails to find the component with id MyMissingComponent and returns. Then, the SendEvent command runs.

Commands specified in the document onMount handler or the component onMount handler run after reinflation. These commands terminate any preserved sequencers of the same name.

For more about reinflation, see Support Tablets and Other Devices that Can Change Size.

Scroll

The Scroll command scrolls a ScrollView or Sequence forward or backward by a set number of pages. The Scroll command has the following properties in addition to the regular command properties.

Property Type Default Description

componentId

String

SELF

The id of the component to read.

distance

Number or dimension

1

The number of pages to scroll. Defaults to 1.

The distance sets how far to scroll, in pages. For example, to scroll a list forward a single page:

  {
    "type": "Scroll",
    "componentId": "myScrollingList",
    "distance": 1
  }

Scrolling stops when any of the following occur:

  • The destination is reached.
  • The end of the scrollable content is reached.
  • The user touches the screen.
  • Alexa sends a new command. Starting a new command ends the Scroll command, which stops scrolling immediately.

To smoothly scroll through all available content, set the distance to a large number. For example, to smoothly scroll back to the beginning of a list:

  {
    "type": "Scroll",
    "componentId": "myScrollingList",
    "distance": -10000
  }

The Scroll command is ignored in fast mode.

componentId

The ID of the ScrollView or Sequence. If omitted, the component issuing the ScrollPage command is used.

distance

The scrolling distance, measured in pages. One "page" is the width or height of the ScrollView or Sequence, less any applied padding. Negative numbers scroll backwards. Setting distance to 0 does not scroll.

For example consider a ScrollView with a height of 400dp and 50dp of padding on the top and bottom. A "page" of the ScrollView is 300dp. Specifying a distance of 0.5 will scroll forward by 50% of the page, or 150dp.

The distance may also be expressed as a relative or absolute dimension with a suitable suffix; for example, "50%", "33dp", or "25vh". Note that setting the distance to a relative number (e.g. "50%") is exactly equal to using a simple number (in this case, 0.5). Because APL documents are commonly written to adjust to the size of the screen it is preferable to use relative scrolling dimensions such as "50%" or 0.5 over using absolute dimensions such as "100dp". This ensures that the content will scroll a sensible distance for the user no matter what device it is displayed on.

Reinflation strategy

When the Reinflate command runs, the Scroll command can resume after Alexa reinflates the document. The command resumes when it runs on a sequencer that is specified in the preservedSequencers array on Reinflate. The Scroll command saves the target component and the remaining distance.

If the target component is not a scrollable component in the reinflated hierarchy, the command is ignored.

After Alexa reinflates the document, scrolling continues for the remaining distance as calculated when the Scroll command started running. For example, assume a ScrollView with a height of 400dp. The Scroll command started scrolling 50% of the height and was halfway finished, so it had scrolled 25% of the total height (100dp) when the document reinflated. After reinflation, the ScrollView is now has 500 dp height. The Scroll command resumes and scrolls the 100dp that was calculated before reinflation.

ScrollToComponent

Scroll forward or backward through a ScrollView or Sequence to ensure that a particular component is in view. The ScrollToComponent command has the following properties in addition to the regular command properties.

Property Type Default Description

align

first, center, last, visible

visible

The alignment of the item after scrolling

componentId

String

SELF

The id of the component.

For example, to scroll to ensure a particular item is in view:

{
  "type": "ScrollToComponent",
  "componentId": "recipeSteps",
  "align": "center"
}

The ScrollToComponent command looks for the first Sequence or ScrollView at or above the componentId and scrolls that one.

Scrolling stops if the user touches the screen. Stopping the command stops scrolling immediately.

The ScrollToComponent command is ignored in fast mode.

align

The alignment of the item on the screen after scrolling and before speech. Alignment is an enumerated value with the following options:

Alignment Description
first The top/left side of the item will be placed at the top/left side of the scrolling container.
center The center of the item will be placed in the center of the container.
last The bottom/right side of the item will be placed at the bottom/right side of the scrolling container.
visible The item will be moved the minimal distance necessary to bring it fully into view.

componentId

The ID of component. If omitted, the component issuing the ScrollToComponent command is used.

Reinflation strategy

When the Reinflate command runs, the ScrollToComponent command can resume after Alexa reinflates the document. The command resumes when it runs on a sequencer that is specified in the preservedSequencers array on Reinflate. The command saves the target component and the alignment specified in the align property.

If the target component is not in the reinflated hierarchy or isn't a descendant of a scrollable component, the command is ignored.

When Alexa reinflates the document, scrolling resumes and scrolls the target component into position as specified by align.

ScrollToIndex

Scroll forward or backward through a ScrollView or Sequence to ensure that a particular child component is in view. The ScrollToIndex command has the following properties in addition to the regular command properties.

Property Type Default Description

align

first, last, center, visible

visible

The alignment of the item after scrolling.

componentId

String

SELF

The id of the component to read.

index

Integer

REQUIRED

The 0-based index of the child component to display.

For example, to scroll to show the fifth step in a recipe displayed in a list, set index to 4.

  {
    "type": "ScrollToIndex",
    "componentId": "recipeSteps",
    "index": 4,
    "align": "center"
  }

The componentId doesn't have to be a Sequence or ScrollView component. The ScrollToIndex command looks for the first Sequence or ScrollView at or above the componentId and scrolls that one.

Scrolling stops if the user touches the screen. Stopping the command stops scrolling immediately.

The ScrollToIndex command is ignored in fast mode.

align

The alignment of the item on the screen after scrolling and before speech. Alignment is an enumerated value with the following options.

Alignment Description
first The top/left side of the item will be placed at the top/left side of the scrolling container.
center The center of the item will be placed in the center of the container.
last The bottom/right side of the item will be placed at the bottom/right side of the scrolling container.
visible The item will be moved the minimal distance necessary to bring it fully into view.

componentId

The identifier of the parent container. If omitted, the component issuing the ScrollToIndex command is used.

index

The 0-based index of the child item in the parent container to scroll into view. Negative values are measured from the end of the parent container. For example, to show the second-to-last item in a list:

  {
    "type": "ScrollToIndex",
    "index": -2,
  }

The algorithm for finding the item to display can be described loosely as follows:

  let itemIndex = index < 0 ? index + children.length : index;
  if (itemIndex >= 0 && itemIndex < children.length) {
    let child = children[itemIndex];
    scrollIntoView(child);
  }

Reinflation strategy

When the Reinflate command runs, the ScrollToIndex command can resume after Alexa reinflates the document. The command resumes when it runs on a sequencer that is specified in the preservedSequencers array on Reinflate. The command saves the target scrollable component, the target index, and the alignment.

If the scrolling component isn't contained in the reinflated hierarchy, the command is ignored.

When Alexa reinflates the document, scrolling resumes and scrolls the target index into position as specified by align.

Select

Select requires APL 1.3 or later. Provide an alternate experience for devices running older versions of APL.

Select a single command from an array of commands and data. The Select command has the following properties in addition to the standard command properties:

Property Type Default Description
commands Array of Commands REQUIRED An ordered list of commands to select from
data Array [] A list of data to map against the commands
otherwise Array of Commands [] An array of commands to run if no command is selected from the commands array

When the data array is empty, the Select command runs the first command in the commands array where when evaluates to true.

In this example, assume age is 7. The command iterates the commands array until it reaches the third command. The when statement for this command evaluates to true, so Select runs the SetValue command and updates the specified text property to the value "Kid".

{
  "type": "Select",
  "commands": [
    {
      "when": "${age < 2}",
      "type": "SetValue",
      "property": "text",
      "value": "Infant",
      "componentId": "${textIdToUpdate}"
    },
    {
      "when": "${age < 5}",
      "type": "SetValue",
      "property": "text",
      "value": "Toddler",
      "componentId": "${textIdToUpdate}"
    },
    {
      "when": "${age < 13}",
      "type": "SetValue",
      "property": "text",
      "value": "Kid",
      "componentId": "${textIdToUpdate}"
    },
    {
      "when": "${age < 18}",
      "type": "SetValue",
      "property": "text",
      "value": "Teen",
      "componentId": "${textIdToUpdate}"
    },
    {
      "type": "SetValue",
      "property": "text",
      "value": "Adult",
      "componentId": "${textIdToUpdate}"
    }
  ]
}

When you provide the data array, the Select command checks each command in the commands array for a true when clause one time per item in the data array. The data-binding context is extended by binding data, index, and length properties. The Select command finishes after it runs a single command; it does not continue iterating over the data array.

In this example, assume age is 17. The command iterates through data array. The when statement for the command evaluates to true for the data provided in the fourth item (17 < 18), so Select stops iterating through the data array and runs the SetValue command, which updates the specified text property to "Your category is Teen".

{
  "type": "Select",
  "commands": {
    "when": "${!data.until || age < data.until}",
    "type": "SetValue",
    "property": "text",
    "value": "Your category is ${data.category}",
    "componentId": "${textIdToUpdate}"
  },
  "data": [
    {
      "until": 2,
      "category": "Infant"
    },
    {
      "until": 5,
      "category": "Toddler"
    },
    {
      "until": 13,
      "category": "Kid"
    },
    {
      "until": 18,
      "category": "Teen"
    },
    {
      "category": "Adult"
    }
  ]
}

You can combine multiple commands with a data array. Select still runs only a single command in the commands array. For example:

{
  "type": "Select",
  "commands": [
    {
      "when": "${searchCategory == data.category && data.rating >= 8.0}",
      "type": "SetValue",
      "property": "text",
      "componentId": "${textIdToUpdate}",
      "value": "Here's a great movie for your category: <em>${data.title}</em>"
    },
    {
      "when": "${searchCategory == data.category}",
      "type": "SetValue",
      "property": "text",
      "componentId": "${textIdToUpdate}",
      "value": "Here's an okay movie for your category: <em>${data.title}</em>"
    }
  ],
  "data": "${movieData}"
}

In this example, movieData is bound to an array of movies sorted by category and rating, with the highest rated movies first:

{
  "movieData": [
    {"title":"Avatar","category":"Adventure","rating":7.8},
    {"title":"Aladdin","category":"Adventure","rating":7.1},
    {"title":"Coco","category":"Animation","rating":8.4},
    {"title":"Toy Story 4","category":"Animation","rating":8},
    {"title":"The Lion King","category":"Animation","rating":7}
  ]
}

If SearchCategory is "Animation", Select iterates until it reaches the third item in data, which matches both of the criteria in the first when statement. The first command then runs and updates the text property of the movieResultTextComponent component with the text "Here's a great movie for your category: Coco".

If SearchCategory is "Adventure", Select chooses the first item in data since this item matches the criteria for the second when statement. The second command then runs and updates the text property of movieResultTextComponent to "Here's an okay movie for your category: Avatar".

commands

An array of commands. The first command in the array with a true when clause runs.

data

The array of data to iterate over. During iteration the data-binding context is extended with the following properties:

Name Description
data Data assigned from the data array property
index The 0-based index of the current data item
length The total number of data items in the data array

Note that these properties are only set if the data array property contains at least one item.

otherwise

The otherwise commands run when none of the commands in the commands property run. The otherwise commands do not have access to the data property. For example:

{
  "type": "Select",
  "commands": {
    "when": "${data.breed == breed}",
    "type": "SetValue",
    "property": "text",
    "componentId": "${textIdToUpdate}",
    "value": "Your dog is ${data.description}"
  },
  "otherwise": {
    "type": "SetValue",
    "property": "text",
    "componentId": "${textIdToUpdate}",
    "value": "Your dog is indescribable!"
  },
  "data": "${dogBreedData}"
}

Contents of the dogBreedData array:

{
  "dogBreedData": [
    {
      "breed": "Affenpinscher",
      "description": "loyal, curious, and amusing"
    },
    {
      "breed": "Bassett Hound",
      "description": "endearing with floppy ears"
    },
    {
      "breed": "Beagle",
      "description": "happy-go-lucky and cheerful"
    }
  ]
}

In the above example, passing the breed "Mixed Mutt" falls throught to the otherwise and updates the provided Text component text with "Your dog is indescribable!"

The otherwise property provides fallback behavior for when nothing from the data array matches.

SendEvent

Use the SendEvent command to generate and send an event to Alexa. The SendEvent command sends an Alexa.Presentation.APL.UserEvent request to your skill. The UserEvent request includes information about the components and events that triggered the command.

The following example illustrates a SendEvent command on the onPress handler of a TouchWrapper.

{
  "type": "TouchWrapper",
  "id": "idForTheTouchWrapper",
  "spacing": "@spacingSmall",
  "alignSelf": "center",
  "onPress": [
    {
      "type": "SendEvent",
      "arguments": [
        "textWasPressed",
        "Send this data to the skill"
      ],
      "components": [
        "idForTheTextComponent"
      ]
    }
  ],
  "item": {
    "type": "Text",
    "id": "idForTheTextComponent",
    "color": "@colorAccent",
    "text": "Click to send a UserEvent to the skill."
  }
}

SendEvent has the following properties in addition to the regular command properties.

Property Type Default Description
arguments Array of objects [ ] An array of argument data to send to the skill in the UserEvent request.
components Array of strings [ ] An array of component IDs. The value associated with each identified component is included in the the resulting UserEvent request.

The SendEvent command is ignored in fast mode.

arguments

An array of data to send to the skill in the UserEvent request. Data binding applies to each element in the array when SendEvent runs. This allows an argument to contain data about the event itself, such as ${event.source.value}. Use this to send arbitrary data to your skill.

Access this data in your UserEvent handler in the arguments property of the request.

components

The components property is an array of selector strings. The UserEvent request includes the value of each component. For example, you can use the components property to construct a form that sends the contents of each component to your skill.

The value for a given component depends on the type of component:

  • A component with a basic press interaction, such as a TouchWrapper, reports the checked state of the component.
  • A rich component that supports interaction, such as a Pager, Sequence, or ScrollView, reports component-specific values. For example, a Pager reports the index of the displayed page. Refer to component documentation for what they report.
  • Other components report null, unless stated otherwise the component documentation.

Access the component values in the components property of the request.

UserEvent

The SendEvent command sends the skill an Alexa.Presentation.APL.UserEvent request.

For example, the SendEvent defined in the TouchWrapper shown earlier generates the following UserEvent request.

{
  "type": "Alexa.Presentation.APL.UserEvent",
  "requestId": "amzn1.echo-api.request.1",
  "timestamp": "2020-01-20T22:28:44Z",
  "locale": "en-US",
  "arguments": [
    "textWasPressed",
    "Send this data to the skill"
  ],
  "components": {
    "idForTheTextComponent": "Click to send a UserEvent to the skill."
  },
  "source": {
    "type": "TouchWrapper",
    "handler": "Press",
    "id": "idForTheTouchWrapper"
  },
  "token": "token-provided-with-RenderDocument"
}

This UserEvent includes the following information defined in the SendEvent command:

  • The arguments property contains an array containing the data passed to the arguments array of the SendEvent command. In this example, these are static strings, but you could use data-binding to include dynamic information here.
  • The source property includes details about the component that triggered the event. In this example, this is the TouchWrapper.
  • The components property contains the value of the component with the ID "idForTheTextComponent". Since this is a Text component, the value included in the UserEvent is the value of the text property. This is included because the SendEvent included this same ID in the components array.

For more details about the UserEvent request, see UserEvent request.

For an example of a UserEvent handler, see Handle a UserEvent request.

Sequential

The Sequential command runs a series of commands in order, waiting for the previous command to finish before starting the next. The Sequential command is finished when all of its child commands have finished.

The type of the Sequential command is Sequential. The Sequential command has the following properties in addition to the common command properties.

Property Type Default Description

catch

Array of Commands

[]

An ordered list of commands to run if this sequence stops early.

commands

Array of Commands

REQUIRED

An ordered list of command to run in series.

repeatCount

Integer

0

Additional number of times to run these commands.

finally

Array of Commands

[]

An ordered list of commands to run after the normal commands and the catch commands

  • In normal mode the commands run in order, followed by the finally commands. The repeatCount only applies to the regular commands.
  • In fast mode the commands run in order without repeating, followed by the finally commands.
  • If one of the commands stops early (in normal mode), the catch commands and finally commands run in fast mode.
  • If one of the finally commands stops while running in normal mode, the remaining finally commands run in fast mode.

catch

catch requires APL 1.1 or later. Provide an alternate experience for devices running older versions of APL.

The catch commands run if the Sequential command stops due to another command running. The catch commands run in "fast" mode – that is, all durations are ignored and commands jump to their final values. The catch commands run before any finally commands.

The catch commands run one time. The repeatCount property doesn't apply to catch commands.

commands

An array of commands to run. The commands run in array order, and each command must finish before the next one can begin. The delay value of the Sequential command and the delay value of the first command in the sequence are additive. In the following example, the first SendEvent command runs after 3000 milliseconds.

{
  "type": "Sequential",
  "delay": 1000,
  "repeatCount": 2,
  "commands": [
    {
      "type": "SendEvent",
      "delay": 2000
    },
    {
      "type": "SendEvent",
      "delay": 2000
    }
  ]
}

finally

finally requires APL 1.1 or later. Provide an alternate experience for devices running older versions of APL.

The finally commands run after the normal sequential commands finish or after the catch commands run due to the command stopping early. The finally commands run in normal mode unless (a) the entire Sequential command ran in fast mode or (b) the sequential command stopped early.

The finally commands run one time. The repeatCount property doesn't apply to finally commands.

repeatCount

The number of times to repeat this series of commands. Defaults to 0. Negative values will be ignored.

Reinflation strategy

When the Reinflate command runs, the Sequential command can resume after Alexa reinflates the document. The command resumes when it runs on a sequencer that is specified in the preservedSequencers array on Reinflate. The command saves the current repeat number, repeat count, and list of commands.

When Alexa reinflates the document, the currently running command continues to run as specified by its reinflation strategy.

SetFocus

SetFocus requires APL 1.1 or later. Provide an alternate experience for devices running older versions of APL.

Changes the actionable component that is in focus. See Focused for the actionable components that can receive and lose focus.

Only one component has focus at a time. Setting the focus on a component automatically clears it from other components.

When SetFocus runs, the command does the following:

  1. Places the targeted component into focus and sets that focused state to true.
  2. Removes focus from any component that had it before and sets that component's focused state to false.

The SetFocus command is ignored if the targeted component is disabled, not actionable, or has the inheritParentState property set to true.

The SetFocus command has the following properties in addition to the standard command properties.

Property Type Default Description
componentId String SELF The id of the component which will receive focus.

For example, to focus a specific component with the id myButton:

{
  "type": "SetFocus",
  "componentId": "myButton"
}

The SetFocus command runs in fast mode, but without any delay.

componentId

The ID of the component which will receive focus. If this property is omitted, the component issuing the SetFocus command is the recipient.

To open a document with a component in focus, set the document onMount property to SetFocus.

For example, to focus the component with the id myButton on document mount:

{
  "onMount": {
    "type": "SetFocus",
    "componentId": "myButton"
  }
}

SetPage

The SetPage command changes the page displayed in a Pager component. The SetPage command finishes when the item is fully in view. The SetPage command has the following properties in addition to the regular command properties.

Property Type Default Description

componentId

String

SELF

The id of the component to read.

position

relative, absolute

absolute

Whether the value is a relative or absolute offset. Defaults to absolute.

value

Integer

REQUIRED

The distance to move. Can be an absolute or relative value.

When there are N pages in the Pager component, the first is index 0 and the last has index N-1. A relative position offsets from the current page. For example, to move one page forward:

  {
    "type": "SetPage",
    "componentId": "myWeatherPager",
    "position": "relative",
    "value": 1
  }

An absolute position sets the index of the current page. A negative absolute position is an offset from the end of the list. For example, to go to the last page:

  {
    "type": "SetPage",
    "componentId": "myWeatherPager",
    "position": "absolute",
    "value": -1
  }

No intermediate pages display when switching between two pages (unlike a Sequence). For example, if the current page is 13 and SetPage runs with "position"="relative","value": 2, the current page transitions out and page 11 displays without showing page 12.

The SetPage command can set any page for display. It does not respect the allowed navigation direction in the Pager component. However, wrapping behavior affects page switch calculations, as shown in approximate algorithm.

Stopping a SetPage command jumps ahead to the target page if the SetPage command sequence is at least 50% complete, and it returns to the previous page if it is not at least 50% complete. The onPageChanged command runs one time when the command stops if the page has changed from the last page.

The SetPage command is ignored in fast mode.

componentId

The identifier of the Pager component. If omitted, the component issuing the SetPage command is used.

position

If the position is relative, the value is a relative distance to move from the current page. If the position is absolute, the value is the absolute page number to which the display will move.

value

The value is either the distance to move or the absolute page number to move to.

The algorithm to calculate final position and direction can be approximated with this pseudo-code.

  if (command.position == 'absolute') {  // Absolute motion
    let index = command.value < 0 ? pager.children.length + command.value : command.value;
    index = Math.max(0, Math.min(pager.children.length - 1, index));  // Clamp range

    // Return the final index and the direction of motion
    if (index == pager.currentIndex)
      return NO_MOVE

    return (index, index < pager.currentIndex ? "LEFT" : "RIGHT");
  }
  else {  // Relative motion
    let index = pager.currentIndex + command.value;

    // If relative motion goes out of bounds and we don't support wrapping, ignore the command
    if (pager.navigation != "wrap" && (index < 0 || index >= pager.children.length))
      return NO_MOVE;

    // Wrap appropriately
    index = ((index % pager.children.length) + pager.children.length) % pager.children.length;
    if (index == pager.currentIndex)
       return NO_MOVE;

    return (index, command.value < 0 ? "LEFT" : "RIGHT");
  }

The pager animation is driven by the returned direction.

This algorithm has these characteristics:

  • Absolute values clamp within the valid range of pages. The direction is relative to the current page.

  • Relative values on a wrapping pager will wrap arbitrarily. The direction is based on the commanded value, and wrapping doesn't change the direction.

  • Relative values on a non-wrapping pager that go out of range are ignored.

Reinflation strategy

When the Reinflate command runs, the SetPage command can resume after Alexa reinflates the document. The command resumes when it runs on a sequencer that is specified in the preservedSequencers array on Reinflate. The command saves the index of the target page.

If the target component is not a Pager component in the reinflated hierarchy, the command is ignored.

If a page transition is running when Alexa reinflates the document, the target page renders when reinflation completes. This has the same effect as preserving the pageIndex (see preserve).

When preserving the SetPage command, the experience works best when both of the following are true:

  • The data source for the Pager has the same number of elements before and after reinflation
  • The Pager content remains at the same indicies.

If the number of elements, or the content at the original indicies change during reinflation, users might find the experience jarring.

SetValue

Changes a property or binding of a component. Each component has a defined set of dynamic properties that can be changed with SetValue. Each component also may have named bindings. Refer to the specifics of each component for the dynamic properties you can change with SetValue.

The SetValue command has the following properties in addition to the regular command properties.

Property Type Default Description
componentId String SELF The id of the component whose value should be set.
property String REQUIRED The name of the property to set.
value String REQUIRED The value to set on the property.

This example sets a value so that the punchline for a joke appears, because an opacity value of 1 means the component is fully visible.

{
  "type": "SetValue",
  "componentId": "jokePunchline",
  "property": "opacity",
  "value": 1
}

The SetValue command changes the value of a component property or component binding. The following rules are followed:

  1. If the component has a property named property that is dynamic, then the property is updated with the new value.
  2. Otherwise, if the component has a bind property with that name, then that bound property is updated.
  3. If a bound property changes value, then all dynamic properties of components that depend on that property are updated.

The following example shows how to update a binding value. Click the text in the simulator and note how the number increments each time. Refresh the page or change viewport profiles to reset the counter.


In the above example, each time you press the TouchWrapper, the text displayed increments.

The SetValue command runs in fast mode, but without any delay.

componentId

The identifier of the component whose value will change. If this property is omitted, then the component that issues the SetValue command is the recipient.

property

The name of the property to change. This may be a built-in property or a binding.

value

The value evaluates when the command runs, so it can take advantage of existing component properties. In this example, the SetValue command sets the opacity of the target component to 50% of its actual value.

{
  "type": "SetValue"
  "property": "opacity",
  "value": "${event.target.opacity * 0.5}"
}

SpeakItem

The SpeakItem command reads the contents of a single component on the screen. The component scrolls or pages into view if it isn't already visible.

The SpeakItem command speaks the content provided in the speech property for the component. When the component doesn't have a speech property, the SpeakItem command scrolls the component into view, but doesn't render any speech.

Set the speech property of the component to the output of a transformer that converts to speech, such as the ssmlToSpeech, textToSpeech, or aplAudioToSpeech transformer.

Some environments might not allow dialog, including speech. Use the environment property disallowDialog to determine whether the device and configuration supports speech-related commands.

The SpeakItem command has the following properties in addition to the regular command properties.

Property Type Default Description

align

first, last, center, visible

visible

The alignment of the item after scrolling. Defaults to "visible".

componentId

String

SELF

The id of the component to read.

highlightMode

line, block

block

How karaoke is applied: on a line-by-line basis, or to the entire block. Defaults to "block".

minimumDwellTime

Integer

0

The minimum number of milliseconds that an item will be highlighted.

The following example shows the SpeakItem command that reads the contents of a single text component and aligns the text in the center of the screen:

{
  "type": "SpeakItem",
  "componentId": "myJokeSetup",
  "highlightMode": "line",
  "align": "center"
}

The SpeakItem command sets the karaoke state of the component to true during the speech and then sets it back to false after the speech completes. The highlightMode property applies to Text components. When Alexa reads a Text component in "highlightMode": "line" mode, individual lines of text are set to the karaoke state during speech and reset to false after speech completes.

Note these restrictions:

  • The SpeakItem command doesn't scroll the content during speech in block mode. For example, if the component is larger than the scrolling container of the component, those parts of the component that aren't visible after scrolling remain hidden.
  • Components on round screens should use center alignment, or much of the content won't be visible.
  • SpeakItem doesn't highlight individual words or lines of text during speech when highlightMode is block.
  • The algorithm used to scroll the item into view assumes there is only a single scrolling component. Nested scrolling components aren't supported.
  • Components without a speech property scroll into view, but don't render any speech.
  • The SpeakItem stops during configuration changes, such switching the orientation on a tablet.

When a SpeakItem command stops early, it clears any visual changes and stops speech immediately.

The SpeakItem command is ignored in fast mode.

align

The alignment of the item on the screen after scrolling and before speech. Alignment is an enumerated value with the following options.

Alignment Description
first The top/left side of the item will be placed at the top/left side of the scrolling container.
center The center of the item will be placed in the center of the container.
last The bottom/right side of the item will be placed at the bottom/right side of the scrolling container.
visible The item will be moved the minimal distance necessary to bring it fully into view.

componentId

The ID of the spoken component. If omitted, the component issuing the SpeakItem command is used.

highlightMode

Controls how contents of a Text component are styled during speech. If set to "block", the entire Text component has the karaoke state set to true during speech. If highlightMode is set to "line", the individual lines of the Text component are treated separately. Each line will scroll to match the align property and be styled separately.

In line-by-line karaoke mode, the only styling change accepted is the color property; other properties are ignored.

When a component other than a Text component is the recipient of SpeakItem, the highlightMode is ignored.

minimumDwellTime

The minimum amount of time in milliseconds to highlight an item.

Reinflation strategy

When the Reinflate command runs, the SpeakItem command can resume after Alexa reinflates the document. The command resumes when it runs on a sequencer that is specified in the preservedSequencers array on Reinflate. In this scenario, the Reinflate command doesn't interrupt audio playback. The command saves the target component.

If the target component is not in the reinflated hierarchy, then audio stops and the command is ignored.

If the target component is in the reinflated hierarchy, then the following occurs after reinflation:

  • The component scrolls into view
  • The [karaoke](../alexa-presentation-language/apl-style-definition-and-evaluation.html state for the component updates to true
  • Any line-by-line highlighting resumes

SpeakList

Read the contents of a range of items inside a common container. Each item scrolls into view before Alexa reads the item. The speech property on each item defines the speech to play. If an item doesn't have the speech property set, the item scrolls into view without the accompanying speech.

Some environments might not allow dialog, including speech. Use the environment property disallowDialog to determine whether the device and configuration supports speech-related commands.

The SpeakList command has the following properties in addition to the regular command properties.

Property Type Default Description

align

first, center, last, visible

visible

The alignment of the item. Defaults to visible.

componentId

String

SELF

The id of the Sequence or Container (or any other hosting component).

count

integer

REQUIRED

The number of children to read.

minimumDwellTime

number

0

The minimum number of milliseconds that an item will be highlighted for. Defaults to 0.

start

integer

REQUIRED

The index of the item to start reading.

The minimumDwellTime prevents items with short titles from being read too quickly. For example, a series of movie titles like "Venom", "Fences", and "Dear Zachary: A Letter to a Son About His Father" needs some dwell time for the first two items.

This example reads three components out of the middle of a list and ensures that each aligns in the center of the screen:

{
  "type": "SpeakList",
  "componentId": "movieList",
  "start": 3,
  "count": 3,
  "minimumDwellTime": 700,
  "align": "center"
}

The karaoke state of the component is set to true during the speech of each component and reset to false after that speech completes.

You can use the SpeakList command with child components:

For multi-child components, the SpeakList command can also speak the firstItem and lastItem properties. When the component has a firstItem defined, the index of the firstItem is 0 and the indices of the child components in items start at 1. When the component doesn't have a firstItem defined, the indices of the child components in items start at 0.

Note these characteristics of the SpeakList command:

  • The SpeakList command doesn't scroll the content during speech. For example, if the component is larger than the scrolling container of the component, those parts of the component that are not visible after scrolling remain hidden.
  • Components on round screens should use center alignment, or much of the content isn't visible.
  • SpeakList does not highlight individual words or lines of text during speech.
  • To scroll the item into view, the component hierarchy is searched upwards to find the first ancestor that can be scrolled.
  • The algorithm that scrolls the item into view assumes there is only a single scrolling component. SpeakList doesn't support nested scrolling components.
  • Components without a speech property still scroll into view.
  • Components without a speech property, but with a positive minimumDwellTime, have the karaoke state set for that time.
  • Components without a speech property and no minimumDwellTime won't have karaoke state set.

The SpeakList command is ignored in fast mode.

align

The alignment of the item on the screen after scrolling and before speech. Alignment is an enumerated value with the following options:

Alignment Description
first The top/left side of the item will be placed at the top/left side of the scrolling container.
center The center of the item will be placed in the center of the container.
last The bottom/right side of the item will be placed at the bottom/right side of the scrolling container.
visible The item will be moved the minimal distance necessary to bring it fully into view.

componentId

The ID of the parent component. If omitted, the component issuing the SpeakList command is used.

count

The number of items to speak. The command does not run if the count is less than 1 (no scrolling, no speech). If the count is larger than the number of remaining items in the container, it is trimmed to the maximum number of items that can be spoken from the starting point.

minimumDwellTime

The minimum amount of time in milliseconds that an item will be highlighted (that is, have the karaoke state set to true). This defaults to 0.

start

The 0-based index of the first child item in the parent container to scroll into view and speak. Negative values are measured from the end of the parent container. This example the last three items in a list:

{
  "type": "SpeakList",
  "start": -3,
  "count": 3
}

The following algorithm approximates how the reading is done.

let first = start < 0 ? start + children.length : start;
   let last = Math.min(first + count, children.length  1);

first = Math.max(0, first);

for (let index = first ; index <= last ; index++) {
  let child = children[index];
  scrollIntoView(child);

  if (child.speech) {
    child.setState("karaoke", true);
    speakChildWithMinimumDwell(child, minimumDwellTime);
    child.setState("karaoke", false);
  }
  else if (minimumDwellTime > 0) {
    child.setState("karaoke", true);
    waitForTimeout(minimumDwellTime);
    child.setState("karaoke", false);
  }
}

Reinflation strategy

When the Reinflate command runs, the SpeakList command can resume after Alexa reinflates the document. The command resumes when it runs on a sequencer that is specified in the preservedSequencers array on Reinflate. In this scenario, the Reinflate command doesn't interrupt audio playback. The command saves the current index being read, the minimumDwellTime, and the count of remaining items to read.

If the target component isn't in the reinflated hierarchy or is not an appropriate target of this command, then the audio stops and no more items are read.

If the target component is in the reinflated hierarchy, then the following occurs after reinflation:

  • The target component scrolls into view
  • The [karaoke](../alexa-presentation-language/apl-style-definition-and-evaluation.html state for the component updates to true

After this, Alexa reads the remaining number of items as specified by count.

When preserving the SpeakList command, the experience works best when the reinflated hierarchy contains a matching component with the same count and order of items with the same speech bindings. Otherwise, the SpeakList command might read components that the user doesn't expect.


Was this page helpful?

Last updated: Nov 28, 2023