Amazon Music Device API
Overview
The Amazon Music Device API provides programmatic access to the Amazon Music service, including millions of songs in the Amazon Music Unlimited catalog.
NOTE: This document consistently uses the following terms to signify requirements and recommendations:
- MUST, REQUIRED, OR SHALL: means an absolute requirement for the application.
- MUST NOT: means that the definition is an absolute prohibition of the application.
- SHOULD, RECOMMENDED: mean that there may exist valid reasons in particular circumstances to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course. “Should not” or “not recommended” means the reverse.
Device API Overview
The Amazon Music Device API uses a REST-like model. As the user browses Amazon Music content, items such as playlists, stations, and tracks are represented by corresponding JSON objects. When a user selects a browsable item on the client device, the API sends an HTTP resource GET
request to retrieve a JSON object document. This document contains objects representing one or more branches or ‘nodes’ of a tree. Your application then parses these objects and displays them as interface items to the user. Some of these are playable, like tracks and stations; others are nested nodes representing categories or playlists; still others are unique types of nodes with special functions. Each object provides a local or remote reference (URI), which the application should follow if the user selects the item associated with it. If a particular HTTP resource is unavailable, the API responds with an appropriate error message.
It is important to emphasize the key way the Device API differs from standard Restful APIs: rather than providing multiple fixed endpoints for different resources, most resources are retrieved starting from a single endpoint. This endpoint acts as a root node connecting all other items in a tree-like hierarchy. Browsable JSON objects may expose additional dynamic endpoints, but those endpoints should not be regarded as fixed or permanent. For instance, if the Device API surfaces an endpoint for retrieving a specified playlist, you should not assume that this same endpoint will continue to refer to that playlist in the future. Device API endpoints that are not specified as ‘fixed’ in this document are dynamically generated and subject to change. Do not hard-code them.
The Device API’s root node endpoint retrieves several primitive nodes that contain all the items under the same item category. For instance, the Playlists node contains all the available playlists in the Amazon Music catalog (Prime playlists for Prime members, Unlimited playlists otherwise). Nodes can be browsed, played, both browsed and played, or neither. For instance, you can both browse and play the contents of playlists, but you can only play stations, not browse them to view the included tracks. A node may be a Navigation Node, a track container, or both, or neither. An example of a node that can neither be played nor browsed is the Amazon Unlimited Music signup dialogue.
A single HTTP response originates from an endpoint URL. The Device API root endpoint URL (domain) is https://music-api.amazon.com/
. To protect customers and partners, only HTTPS connections supporting TLS 1.2 or higher are permitted between this domain and client devices. Other Amazon subdomains may be used to serve some specific content, but the overall functionality and user experience are determined by GET requests to and responses from this root endpoint.
The Amazon Music Device API can be divided conceptually into the following parts:
- Protocols – JSON, URI, OAuth 2.0
- Login with Amazon - Authentication
- Browse – Navigating music collections
- Playback – Playing music collections
Let’s start with a brief introduction to the protocols you’ll need to know.
JSON Protocol
API response entities generally use JavaScript Object Notation (JSON) as a data-interchange format. JSON is an excellent format for representing strictly hierarchical, tree-like data. However, the Amazon Music API often must represent non-hierarchical data with no obvious parent/child relationship between objects.
To allow non-hierarchical data to be represented efficiently, all JSON response entities use the document object type. A document allows multiple objects to be defined, named, and referenced. An object is an unordered collection of zero or more name/value pairs, where a name is a string, and a value is a string, number, Boolean, null, object, or array. There are different types of JSON object types with various members and values. These objects have relationships with other objects.
A JSON document object contains a result
which is the primary browsable item retrieved. It also contains any sub-nodes organized in a hierarchy. A list of child nodes of the current node can be found in the itemDescriptions
dictionary. Sub-items that are Navigation Nodes will have a value listed in their navigationNodeSummary
field, prefixed by a ‘#’. That value is used to look up the navigationNode
in the navigationNodeSummaries
dictionary. The entry there will include a title
attribute that can be used to label the node in the user interface. The description field is a pointer to the node itself and any sub-nodes it has. Document objects in the Device API use the ‘#’ prefix to indicate a local reference that can be found in the existing document object. In cases where no ‘#’ prefix is found, the description field may contain a URI endpoint that can be queried for more information. These endpoints are dynamic, not fixed.
Below is an example of the JSON returned for the root node, with some parts omitted for brevity.
{
"result": "#catalog_desc",
"navigationNodeDescriptions": {
"catalog_desc": {
"summary": "#catalog_desc_summary",
"items": ["#label_0_desc", "#label_1_desc", "#label_2_desc", ... ],
}
},
"navigationNodeSummaries": {
"label_0_summary": { "title": "Try Amazon Music Unlimited", "description": "upsell-banner/#upsell_banner" },
"label_1_summary": { "title": "Playlists", "description": "catalog/playlists/#prime_playlists" },
"label_2_summary": { "title": "Stations", "description": "catalog/stations/#prime_stations" },
...
"catalog_desc_summary": { "title": "Browse", "description": "#catalog_desc" }
},
"itemDescriptions": {
"label_0_desc": {
"itemLabel": "Try Amazon Music Unlimited", "navigationNodeSummary": "#label_0_summary" ... },
"label_1_desc": {
"itemLabel": "Playlists", "navigationNodeSummary": "#label_1_summary", ... },
"label_2_desc": {
"itemLabel": "Stations", "navigationNodeSummary": "#label_2_summary", .... },
},
}
We will examine this example in more detail in the Browse section.
URI Protocol
As defined in RFC 3986:
A Uniform Resource Identifier (URI) is a compact sequence of characters that identifies an abstract or physical resource.
In general, any URI transferred in a request or response entity (or header, where permitted by HTTP/1.1) may be either absolute or relative to the resource where it appears. Relative URIs are resolved into absolute URIs according to RFC 3986.
URIs obtained from Device API responses should be considered semantically opaque. Do not attempt to parse URIs to extract semantic information such as IDs or tokens. Do not attempt to construct your own URIs by concatenating pieces of information. All URIs surfaced through Device API responses should be considered dynamic and should not be saved or hard-coded.
A URI may be divided into two parts: the base portion and a fragment portion (which can be identified by its ‘#’ prefix). The non-fragment portion of the URI identifies the resource from which the document may be obtained by sending a GET request. The fragment identifier portion refers to a particular object in that document by name. If the fragment identifier is absent or blank, the URI refers to the object whose name is given by the result
member.
A local fragment URI consists only of a fragment identifier; the first character of the URI is #. Such a URI refers to a named object within the same document from which the URI was obtained. A client that receives a local fragment URI must not resolve it to an absolute URI or attempt to send a request for the named object to the resource identified by the absolute URI.
"label_2_summary": {
"title": "Stations", "description": "catalog/stations/#prime_stations" },
In the example above (some lines omitted for brevity) the description
for the label_2
node is a URI. The base portion of the URI is the relative URI of an endpoint. The #prime_stations
segment of the URI is an example of a local fragment identifier. If the user selects this node, the application should query the catalog/stations/
endpoint. The document object that is returned will contain a prime_stations
object.
Authentication (OAuth 2.0 Protocol)
The Amazon Music APIs require valid OAuth 2.0 authentication tokens for access. Amazon provides a single, unified authentication service called Login With Amazon which provides valid OAuth 2.0 tokens for most Amazon services, including the Amazon Music APIs. To use LWA, you will need to create an LWA account and security profile to receive the client ID and device ID you use for authentication.
To learn more about Login with Amazon, click here.
To continue on and start learning how to query the Device API, click here.