Note: Sign in to the developer console to build or publish your skill.
Important: Anyone can build a music skill for public distribution in the United States. However, radio and podcast skills are currently in developer preview. To register your radio or podcast skill for the preview, contact your Alexa Music, Radio, or Podcast representative.
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:
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:
If you build your skill by using the ASK CLI, configure it in your skill manifest JSON.
Directives
GetNextItem directive
Support the GetNextItem directive so that customers can navigate forward in a content play queue. The following table shows which content types use this directive.
Note:GetNextItem and GetPreviousItem aren't required for radio content. However, if your skill combines radio content with music or podcast content, it might need GetNextItem and GetPreviousItem.
Content type
Required?
Music
Required
Radio
Optional
Podcast
Required
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 asks Alexa 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 or program series episode, Alexa tells the user that skipping forward isn't allowed, and the GetNextItem request isn't sent to the skill.
For podcast skills, when the GetNextItem request is initiated by the user (isUserInitiated is true), your skill should return the next newer program. This is true whether the program series is serial or episodic (non-serial). When the GetNextItem request is initiated by Alexa, (isUserInitiated is false), your skill should return the next newer program for a serial program series. It should return the next older program for an episodic program series.
When the currently playing track is part of a subscription play queue, the skill is expected to return the next item to play for a GetNextItem request. The ContentId field in the GetNextItem request object uniquely identifies the subscription play queue. In addition, the following requirements apply:
"Play next," "Play next podcast," and "Play next episode" are synonymous. All refer to the next item to play in the subscription play queue.
The next item can be from a different podcast if the customer has subscribed to multiple podcasts.
The next item should be an episode that the customer hasn't listened to or has only partially listened to.
The next item is same whether the request is initiated by the user or by Alexa.
Voice navigation should provide the same experience a customer would see navigating the subscription playlist within the provider's app.
true if the user explicitly asked to skip to the next track (for music) or program (for podcasts), false if the current track or program will soon end and the next item is needed.
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.
If the provider supports premium audio (or audio quality streams in addition to the default), the request will also contain an endpoint object which lists the provider's content type identifiers that are playable on the target device. The following example demonstrates support for premium audio.
When Alexa needs to get the stream URI for a program to buffer it on the device for a smooth transition, Alexa sends a GetNextItem request as in the following example.
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. When this value is false, the item field must be present and contain a non-null value. When this value is true, the item field must be absent or set to null.
The following example adds a background image for Alexa to display while playing the item. For more information, see the background field of the BaseMetadata object.
When the skill determines that the user has reached their daily skip limit, it returns an error response indicating the error case as shown in the following example.
{"header":{"messageId":"[MESSAGE_ID]","namespace":"Alexa.Audio","name":"ErrorResponse","payloadVersion":"1.0"},"payload":{"type":"SKIP_LIMIT_REACHED","message":"The user has reached their daily skip limit.","retryPeriod":"DAILY"}}
When the currently playing item is the last item in the queue, the skill returns a response indicating that there are no more programs to return.
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, Radio, and Podcast 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]","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. The following table shows which content types use this directive.
Note:GetNextItem and GetPreviousItem aren't required for radio content. However, if your skill combines radio content with music or podcast content, it might need GetNextItem and GetPreviousItem.
Content type
Required?
Music
Required
Radio
Optional
Podcast
Required
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 or podcast episode, Alexa tells the user that skipping back isn't allowed, and the GetPreviousItem request isn't sent to the skill.
For podcast skills, when your skill receives a GetPreviousItem request, your skill should return the next older program. This is true whether the program series is serial or episodic (non-serial).
When the currently playing track is part of a subscription play queue, the skill is expected to return the previous item to play for a GetPreviousItem request. The ContentId field in the GetPreviousItem request object uniquely identifies the subscription play queue. In addition, the following requirements apply:
"Play previous," "Play previous podcast," and "Play previous episode" are synonymous. All refer to the previous item to play in the subscription play queue.
"Previous item" here refers to the previous episode in the queue and not to an older episode of the podcast.
The previous item can be from a different podcast if the customer has subscribed to multiple podcasts.
Voice navigation should provide the same experience a customer would see navigating the subscription playlist within the provider's app.
When a user says, "Alexa, previous" while listening to a song or podcast episode in a queue, Alexa sends a GetPreviousItem request as in the following example.
If the provider supports premium audio (or audio quality streams in addition to the default), the request will also contain an endpoint object which lists the provider's content type identifiers that are playable on the target device. The following example demonstrates premium audio support.
When a user says, "Alexa, previous" while listening to a song or podcast episode in a queue, Alexa sends a GetPreviousItem request as in the following example.
When the skill has a previous item to return, it should respond with a GetPreviousItem.Response message as shown in the following example.
{"header":{"namespace":"Alexa.Audio.PlayQueue","name":"GetPreviousItem.Response","messageId":"[MESSAGE_ID]","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"}}}}
If the provider supports premium audio, then one of the content types in the request will have been selected as the most appropriate type of audio quality to provide to the customer. Whichever is the selected content format should be returned as part of the stream object in the response. Even if the provider selects the default Alexa audio quality for the response, a content format object for that quality should be returned as part of the stream object. The following example demonstrates support for premium audio.
{"header":{"messageId":"[MESSAGE_ID]","namespace":"Alexa.Audio.PlayQueue","name":"GetPreviousItem.Response","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":[]}},"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":"2021-11-10T19:11:35Z","contentFormat":{"type":"AUDIO","contentTypeId":"CT-1236"}},"feedback":{"type":"PREFERENCE","value":"POSITIVE"}}}}
The following example adds a background image for Alexa to display while playing the item. For more information, see the background field of the BaseMetadata object.
{"header":{"namespace":"Alexa.Audio.PlayQueue","name":"GetPreviousItem.Response","messageId":"[MESSAGE_ID]","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}]},"background":{"type":"STATIC_IMAGES","images":[{"art":{"contentDescription":"","sources":[{"url":"url","size":"LARGE"}]}}]}},"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 response event example (podcast)
When the skill has a previous item to return, it should respond with a GetPreviousItem.Response message as in the following example.
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 program in a queue, the skill sends an error response as in the following example.
{"header":{"messageId":"[MESSAGE_ID]","namespace":"Alexa.Media","name":"ErrorResponse","payloadVersion":"1.0"},"payload":{"type":"ITEM_NOT_FOUND","message":"There is no previous item."}}
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, Radio, and Podcast 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]","namespace":"Alexa.Audio","name":"ErrorResponse","payloadVersion":"1.0"},"payload":{"type":"ITEM_NOT_FOUND","message":"There is no previous item."}}
JumpToItem directive
Note:JumpToItem isn't supported for podcast skills.
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. The following table shows which content types use this directive:
Content type
Required?
Music
Optional
Radio
Not applicable
Podcast
Not applicable
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 can't 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.
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 item in a queue of five items, the user opens the Alexa app and views the active play queue. From there, the user chooses the fifth item in the queue. At that point, Alexa invokes the music skill to jump to the fifth item.
JumpToItem directive user-initiated example with premium audio
If the provider supports premium audio (or audio quality streams in addition to the default), the request will also contain an endpoint object which lists the provider's content type identifiers that are playable on the target device. The following example demonstrates support for premium audio.
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.
In response to the preceding example request, the skill returns information about the item identified in the request, as shown in the following example.
If the provider supports premium audio, then one of the content types in the request will have been selected as the most appropriate type of audio quality to provide to the customer. Whichever is the selected content format should be returned as part of the stream object in the response. Even if the provider selects the default Alexa audio quality for the response, a content format object for that quality should be returned as part of the stream object. The following example demonstrates support for premium audio.
{"header":{"messageId":"[MESSAGE_ID]","namespace":"Alexa.Audio.PlayQueue","name":"JumpToItem.Response","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":[]}},"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":"2021-11-10T19:11:35Z","contentFormat":{"type":"AUDIO","contentTypeId":"CT-1236"}},"feedback":{"type":"PREFERENCE","value":"POSITIVE"}}}}
The following example adds a background image for Alexa to display while playing the item. For more information, see the background field of the BaseMetadata object.
If your skill can't handle a JumpToItem directive successfully, it should respond with an Alexa.Media.ErrorResponse event or an Alexa.ErrorResponse event.
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":"[MESSAGE_ID]","namespace":"Alexa.Media","name":"ErrorResponse","payloadVersion":"1.0"},"payload":{"type":"INVALID_ITEM","message":"The requested item is no longer valid."}}