Alexa.Audio.PlayQueue Interface

Implement the Alexa.Audio.PlayQueue capability interface to enable a voice control experience for your Alexa skill.

Utterances

When you use the Alexa.Audio.PlayQueue interface, the voice interaction model is already built for you. The following examples show some customer utterances:

Alexa, next.
Alexa, previous.

After the customer says one of these utterances, Alexa sends a corresponding directive to your skill.

Overview

Enforcing skip limits

Your skill can enforce skip limits, such as no more than three skips forward or backward per hour, or a maximum of ten skips per day. When the GetNextItem request is triggered by the user ("isUserInitiated": true), the skill can optionally return an error response indicating that the user has reached the skip limit. When the request includes \"isUserInitiated\": false, the request should not apply to the user's skip limit because the request was not initiated by the user.

Configure your skill to receive requests

You must configure your music skill to support this API before Alexa will send requests to it. You can configure your skill in the following ways:

Directives

GetNextItem directive

Support the GetNextItem directive so that customers can navigate forward in a content queue.

Alexa sends a GetNextItem request to the skill when a content queue exists and playback has started on the Alexa device, and one of the following is true:

  • Content is playing on the Alexa device, and Alexa needs to retrieve the next item to buffer on the device to ensure a smooth transition to the next item.
  • The item currently playing has the NEXT control enabled, and the user asks Alexa to skip to the next item, either by voice or in the Alexa app.
  • The user requests to turn shuffle on or off. In this case, Alexa discards the next track queued to play, and calls GetNextItem because changing the shuffle state likely changes which track to play next.

When the currently playing track has the NEXT control disabled and the user asks Alexa for the next song, Alexa tells the user that skipping forward is not allowed, and the GetNextItem request is not sent to the skill.

The following example shows a customer utterance:

Alexa, next.

GetNextItem directive payload details

Field Description Type
requestContext Context information about the request. A RequestContext object.
currentItemReference The currently playing item. An ItemReference.
isUserInitiated true if the user explicitly asked to skip to the next song, false if the current track will soon end and the next track is needed. Boolean

GetNextItem directive Alexa-initiated example

When Alexa needs to get the stream URI for a track to buffer it on the device for a smooth transition, Alexa sends a GetNextItem request as in the following example.

{
    "header": {
      "namespace": "Alexa.Audio.PlayQueue",
      "name": "GetNextItem",
      "messageId": "<message id, a 25-character random alphanumeric string>",
      "payloadVersion": "1.0"
    },
    "payload": {
      "requestContext": {
        "user": {
            "id": "amzn1.ask.account.AAAAABBBBBCCCCCDDDDDEEEEEFFFFFGGGGGHHHHH",
            "accessToken": "<an OAuth2 bearer token>"
        },
        "location": {
          "originatingLocale": "en-US"
        }
      },
      "currentItemReference": {
        "id": "e73befbe-8c27-4e4b-ab0c-9865ce8516f0",
        "queueId": "76f325d5-a648-4e8f-87ad-6e53cf99e4c7",
        "content": {
          "id": "1021012f-12bb-4938-9723-067a4338b6d0",
          "metadataType": "TRACK"
        }
      },
      "isUserInitiated": false
    }
}

GetNextItem directive user-initiated example

When the user says "Alexa, next" while a song is playing, Alexa sends a GetNextItem request as in the following example.

{
  "header": {
      "namespace": "Alexa.Audio.PlayQueue",
      "name": "GetNextItem",
      "messageId": "<message id, a 25-character random alphanumeric string>",
      "payloadVersion": "1.0"
  },
  "payload": {
    "requestContext": {
      "user": {
          "id": "amzn1.ask.account.AAAAABBBBBCCCCCDDDDDEEEEEFFFFFGGGGGHHHHH",
          "accessToken": "<an OAuth2 bearer token>"
      },
      "location": {
        "originatingLocale": "en-US"
      }
    },
    "currentItemReference": {
      "id": "e73befbe-8c27-4e4b-ab0c-9865ce8516f0",
      "queueId": "76f325d5-a648-4e8f-87ad-6e53cf99e4c7",
      "content": {
        "id": "1021012f-12bb-4938-9723-067a4338b6d0",
        "metadataType": "TRACK"
      }
    },
    "isUserInitiated": true
  }
}

GetNextItem response event

If you handle a GetNextItem directive successfully, respond with an Alexa.Response event.

If your skill has a next item to return, return the next item. If the currently playing item is the last item in the queue, your skill should send "isQueueFinished": true to indicate that there are no more items.

GetNextItem response event payload details

Field Description Type Required
isQueueFinished A flag that indicates whether the currently playing item is the last item in the queue. Boolean Yes
item The requested item in the play queue. An Item object. Required when isQueueFinished is false.

GetNextItem Response event queue-finished example

When the currently playing item is the last item in the queue, the skill returns a response indicating that there are no more tracks to return.

{
    "header": {
        "namespace": "Alexa.Audio.PlayQueue",
        "name": "GetNextItem.Response",
        "messageId": "<message id, a 25-character random alphanumeric string>",
        "payloadVersion": "1.0"
    },
    "payload": {
        "isQueueFinished": true,
        "item": null
    }
}

GetNextItem Response event with item example

In the following example, the skill returns information about the next item that Alexa should play for the user.

{
    "header": {
        "namespace": "Alexa.Audio.PlayQueue",
        "name": "GetNextItem.Response",
        "messageId": "<message id, a 25-character random alphanumeric string>",
        "payloadVersion": "1.0"
    },
    "payload": {
      "isQueueFinished": false,
      "item": {
        "id": "533718fe-b22d-4f64-8b1c-49ffdb85f619",
        "playbackInfo": {
          "type": "DEFAULT"
        },
        "metadata": {
          "type": "TRACK",
          "name": {
            "speech": {
              "type": "PLAIN_TEXT",
              "text": "in circles"
            },
            "display": "In Circles"
          },
          "art": {
            "sources": [
              {
                "url": "https://images.example.com/images/cover/48x48-000000-80-0-0.jpg",
                "size": "X_SMALL",
                "widthPixels": 48,
                "heightPixels": 48
              },
              {
                "url": "https://images.example.com/images/cover/60x60-000000-80-0-0.jpg",
                "size": "SMALL",
                "widthPixels": 60,
                "heightPixels": 60
              },
              {
                "url": "https://images.example.com/images/cover/110x110-000000-80-0-0.jpg",
                "size": "MEDIUM",
                "widthPixels": 110,
                "heightPixels": 110
              },
              {
                "url": "https://images.example.com/images/cover/256x256-000000-80-0-0.jpg",
                "size": "LARGE",
                "widthPixels": 256,
                "heightPixels": 256
              },
              {
                "url": "https://images.example.com/images/cover/600x600-000000-80-0-0.jpg",
                "size": "X_LARGE",
                "widthPixels": 600,
                "heightPixels": 600
              }
            ]
          }
        },
        "durationInMilliseconds": 276000,
        "controls": [
          {
            "type": "COMMAND",
            "name": "NEXT",
            "enabled": true
          },
          {
            "type": "COMMAND",
            "name": "PREVIOUS",
            "enabled": false
          }
        ],
        "rules": {
          "feedbackEnabled": true
        },
        "stream": {
          "id": "STREAMID_92_14629004",
          "uri": "http://cdn.example.com/api/1/a2f318467fbf2829996adc0880e0abd03d03b1ba6ac.mp3",
          "offsetInMilliseconds": 0,
          "validUntil": "2018-05-10T19:11:35Z"
        },
        "feedback": {
          "type": "PREFERENCE",
          "value": "POSITIVE"
        }
      }
    }
}

GetNextItem directive error handling

If your skill can't handle a GetNextItem directive successfully, it should respond with an Alexa.Media.ErrorResponse event or an Alexa.ErrorResponse event. For more information, see Alexa Music and Radio Skill API Error Responses.

Your skill can also reject a user's attempt to skip to the next item when enforcing skip limits.

When the skill determines that the user has reached their daily skip limit, it returns an error response indicating the error case as in the following example.

{
  "header": {
    "messageId": "<message id, a 25-character random alphanumeric string>",
    "namespace": "Alexa.Audio",
    "name": "ErrorResponse",
    "payloadVersion": "1.0"
  },
  "payload": {
    "type": "SKIP_LIMIT_REACHED",
    "message": "The user has reached their daily skip limit.",
    "retryPeriod": "DAILY"
  }
}

GetPreviousItem directive

Support the GetPreviousItem directive so that customers can navigate backward in a content queue.

Alexa sends a GetPreviousItem request to the skill when a content queue exists and playback has started on the Alexa device, and one of the following is true:

  • The user asks Alexa to skip back to the previous item.
  • The user chooses to skip back to the previous item (for example, in the Alexa app).

Alexa sends a GetPreviousItem request only when the currently playing item has the PREVIOUS control enabled, indicating that the user can skip backwards.

For example, when a user is listening to the fourth track from an album and asks Alexa to skip back, Alexa sends a GetPreviousItem request to the skill. The skill should respond with the third track from the album, which Alexa then plays on the device.

When the currently playing track has the PREVIOUS control disabled and the user asks Alexa for the previous song, Alexa tells the user that skipping back is not allowed, and the GetPreviousItem request is not sent to the skill.

The following example shows a customer utterance:

Alexa, previous.

GetPreviousItem directive payload details

Field Description Type
requestContext Context information about the request. A RequestContext object.
currentItemReference The currently playing item. An ItemReference.

GetPreviousItem directive example

When a user says "Alexa, previous" while listening to a song in a queue, Alexa sends a GetPreviousItem request as in the following example.

{
    "header": {
      "namespace": "Alexa.Audio.PlayQueue",
      "name": "GetPreviousItem",
      "messageId": "<message id, a 25-character random alphanumeric string>",
      "payloadVersion": "1.0"
    },
    "payload": {
      "requestContext": {
        "user": {
          "id": "amzn1.ask.account.AGF3NETIE4MNXNG2Z64Z27RXB6JCK2R62BCPYUZI",
          "accessToken": "e72e16c7e42f292c6912e7710c838347ae178b4a"
        },
        "location": {
          "originatingLocale": "en-US"
        }
      },
      "currentItemReference": {
        "id": "533718fe-b22d-4f64-8b1c-49ffdb85f619",
        "queueId": "76f325d5-a648-4e8f-87ad-6e53cf99e4c7",
        "content": {
          "id": "1021012f-12bb-4938-9723-067a4338b6d0",
          "metadataType": "TRACK"
        }
      }
    }
}

GetPreviousItem response event

If you handle a GetPreviousItem directive successfully, respond with an Alexa.Response event.

GetPreviousItem response event payload details

Field Description Type Required
item The previous item in the play queue. An Item object. Yes

GetPreviousItem Response event example

When the skill has a previous item to return, it should respond with a GetPreviousItem.Response message as in the following example.

{
    "header": {
        "namespace": "Alexa.Audio.PlayQueue",
        "name": "GetPreviousItem.Response",
        "messageId": "<message id, a 25-character random alphanumeric string>",
        "payloadVersion": "1.0"
    },
    "payload": {
      "item": {
        "id": "e73befbe-8c27-4e4b-ab0c-9865ce8516f0",
        "playbackInfo": {
          "type": "DEFAULT"
        },
        "metadata": {
          "type": "TRACK",
          "name": {
            "speech": {
              "type": "PLAIN_TEXT",
              "text": "come as you are"
            },
            "display": "Come As You Are"
          },
          "art": {
            "sources": [
              {
                "url": "https://images.example.com/images/cover/48x48-000000-80-0-0.jpg",
                "size": "X_SMALL",
                "widthPixels": 48,
                "heightPixels": 48
              },
              {
                "url": "https://images.example.com/images/cover/60x60-000000-80-0-0.jpg",
                "size": "SMALL",
                "widthPixels": 60,
                "heightPixels": 60
              },
              {
                "url": "https://images.example.com/images/cover/110x110-000000-80-0-0.jpg",
                "size": "MEDIUM",
                "widthPixels": 110,
                "heightPixels": 110
              },
              {
                "url": "https://images.example.com/images/cover/256x256-000000-80-0-0.jpg",
                "size": "LARGE",
                "widthPixels": 256,
                "heightPixels": 256
              },
              {
                "url": "https://images.example.com/images/cover/600x600-000000-80-0-0.jpg",
                "size": "X_LARGE",
                "widthPixels": 600,
                "heightPixels": 600
              }
            ]
          }
        },
        "durationInMilliseconds": 218000,
        "controls": [
          {
            "type": "COMMAND",
            "name": "NEXT",
            "enabled": true
          },
          {
            "type": "COMMAND",
            "name": "PREVIOUS",
            "enabled": false
          }
        ],
        "rules": {
          "feedbackEnabled": true
        },
        "stream": {
          "id": "STREAMID_92_14629004",
          "uri": "http://cdn.example.com/api/1/a2f318467fbf2829996adc0880e0abd03d03b1ba6ac.mp3",
          "offsetInMilliseconds": 0,
          "validUntil": "2018-11-10T19:11:35Z"
        },
        "feedback": {
          "type": "PREFERENCE",
          "value": "POSITIVE"
        }
      }
    }
}

GetPreviousItem directive error handling

If your skill can't handle a GetPreviousItem directive successfully, it should respond with an Alexa.Media.ErrorResponse event or an Alexa.ErrorResponse event. For more information, see Alexa Music and Radio Skill API Error Responses.

When there is no previous item to return, the skill should respond with an ErrorResponse of type ITEM_NOT_FOUND. For example, when the user says "Alexa, previous" while listening to the first track in a queue, the skill sends an error response as in the following example.

{
  "header": {
    "messageId": "<message id, a 25-character random alphanumeric string>",
    "namespace": "Alexa.Audio",
    "name": "ErrorResponse",
    "payloadVersion": "1.0"
  },
  "payload": {
    "type": "ITEM_NOT_FOUND",
    "message": "There is no previous item."
  }
}

JumpToItem directive

Support the JumpToItem directive so that customers can jump to a specific item in an audio content queue by choosing it in a play queue displayed in the Alexa app.

Alexa sends a JumpToItem request when audio content is playing from a music skill, and the user views the active queue of music (resulting from a GetView response) in the Alexa app then clicks on a track in the list to play. The skill can return the requested item to play, or return an error if the user cannot jump to the selected track because of skip limit enforcement or another reason. The JumpToItem request is similar to the GetNextItem and GetPreviousItem requests, except that instead of moving one position forward or back through the active queue of music, the user jumps directly to the desired position in the queue.

If your skill supports this directive, it must also support the GetView directive.

JumpToItem directive payload details

Field Description Type
requestContext Context information about the request. A RequestContext object.
currentItemReference An object identifying the currently playing item. See the ItemReference object for more information. object
targetItemId The identifier of the item to jump to. String

JumpToItem directive example

In the following example, while listening to the second song in a queue of five songs, the user opens the Alexa app and views the active play queue. From there, the user chooses the fifth song in the queue. At that point, Alexa invokes the music skill to jump to the fifth track.

{
    "header": {
        "messageId": "2cae4d53-6bc1-4f8f-aa98-7dd2727ca84b",
        "namespace": "Alexa.Audio.PlayQueue",
        "name": "JumpToItem",
        "payloadVersion": "1.0"
    },
    "payload": {
        "requestContext": {
            "user": {
                "id": "amzn1.ask.account.ABCD1234",
                "accessToken": "e72e1234567890"
            },
            "location": {
                "originatingLocale": "en-US"
            }
        },
        "currentItemReference": {
            "id": "e73befbe-8c27-4e4b-ab0c-9865ce8516f0",
            "queueId": "76f325d5-a648-4e8f-87ad-6e53cf99e4c7",
            "contentId": "1021012f-12bb-4938-9723-067a4338b6d0"
        },
        "targetItemId": "533718fe-b22d-4f64-8b1c-49ffdb85f619"
    }
}

JumpToItem response event

If the requested item is valid and the jump is allowed, respond with a JumpToItem.Response event. The response header contains the common response header fields.

JumpToItem.Response event payload details

Field Description Type Required
item The requested item in the play queue. An Item object. Yes

JumpToItem.Response event example

In response to the preceding example request, the skill returns information about the item identified in the request, as shown in the following example.

{
    "header": {
        "messageId": "2cae4d53-6bc1-4f8f-aa98-7dd2727ca84b",
        "namespace": "Alexa.Audio.PlayQueue",
        "name": "JumpToItem.Response",
        "payloadVersion": "1.0"
    },
    "payload": {
        "item": {
            "id": "533718fe-b22d-4f64-8b1c-49ffdb85f619",
            "playbackInfo": {
                "type": "DEFAULT"
            },
            "metadata": {
                "type": "TRACK",
                "name": {
                    "speech": {
                        "type": "PLAIN_TEXT",
                        "text": "hello"
                    },
                    "display": "Hello"
                },
                "art": {
                    "sources": [
                        {
                            "url": "https://abcd.com/images/cover/album-art.jpg",
                            "size": "X_SMALL",
                            "widthPixels": 48,
                            "heightPixels": 48
                        },
                        {
                            "url": "https://abcd.com/images/cover/album-art.jpg",
                            "size": "SMALL",
                            "widthPixels": 60,
                            "heightPixels": 60
                        },
                        {
                            "url": "https://abcd.com/images/cover/album-art.jpg",
                            "size": "MEDIUM",
                            "widthPixels": 110,
                            "heightPixels": 110
                        },
                        {
                            "url": "https://abcd.com/images/cover/album-art.jpg",
                            "size": "LARGE",
                            "widthPixels": 256,
                            "heightPixels": 256
                        },
                        {
                            "url": "https://abcd.com/images/cover/album-art.jpg",
                            "size": "X_LARGE",
                            "widthPixels": 600,
                            "heightPixels": 600
                        }
                    ]
                }
            },
            "durationInMilliseconds": 143000,
            "controls": [
                {
                    "type": "COMMAND",
                    "name": "NEXT",
                    "enabled": true
                },
                {
                    "type": "COMMAND",
                    "name": "PREVIOUS",
                    "enabled": false
                }
            ],
            "rules": {
                "feedbackEnabled": true
            },
            "stream": {
                "id": "STREAMID_92_14629004",
                "uri": "https://example-cdn.com/streaming-file.mp3",
                "offsetInMilliseconds": 0,
                "validUntil": "2018-05-10T19:11:35Z"
            },
            "feedback": {
                "type": "PREFERENCE",
                "value": "POSITIVE"
            }
        }
    }
}

JumpToItem directive error handling

If your skill can't handle a JumpToItem directive successfully, it should respond with an Alexa.Media.ErrorResponse event or an Alexa.ErrorResponse event.

Your skill can enforce skip limits by returning a SKIP_LIMIT_REACHED error when the user tries to jump after having reached their skip limit. See Alexa Music and Radio Skill API Error Responses.

JumpToItem.Response error handling example

In this example the music skill has called GetView and displayed a list of items to the user in the Alexa app. The user chooses one of the items from the list, causing Alexa to send a JumpToItem request. Between the GetView call and the JumpToItem call, the skill has updated the playlist, causing the jump target to be no longer valid. The skill should return the following error response.

{
    "header": {
        "messageId": "2cae4d53-6bc1-4f8f-aa98-7dd2727ca84b",
        "namespace": "Alexa.Media",
        "name": "ErrorResponse",
        "payloadVersion": "1.0"
    },
    "payload": {
        "type": "INVALID_ITEM",
        "message": "The requested item is no longer valid."
    }
}