Request an Access Token
Before you can use Amazon Device Messaging (ADM) to send a message to an instance of your app, on the server side you must have:
- Obtained and stored the app instance's registration ID; for more details, see Integrate Your App.
- Exchanged your OAuth client credentials for a current access token. This document describes that process.
To send a message and for information about the high-level architecture of ADM, see Send a Message and Overview of ADM.
- Client credentials and access tokens
- Request format
- Response format
- Making the token request and handling the response
Client credentials and access tokens
To acquire an access token, your server provides ADM servers with your OAuth client credentials. Your client credentials are assigned to you by Amazon and are two pieces of data that are unique to your app: a client_id and a client_secret value. Your servers use both pieces of your client credentials in their requests to obtain ADM access tokens. For information about how to get your client credentials, see Obtain Credentials.
An access token is short-lived metadata that authenticates your server's identity to ADM, so that you can send messages. When you send a message using ADM, that message request must include an access token. Although a server only uses a single access token at any given time, you must obtain a new access token when an old one expires. Also, although it is possible to share an access token across multiple servers, it is typically more convenient for each of your servers to obtain their own access token and independently request, track, and use it for sending messages.
Request format
Your servers obtain their access tokens by providing your client credentials in a request call to ADM servers. You can use this same request to acquire an initial access token or to obtain a new one when a prior access token has expired.
To obtain an access token, your server issues a POST request on an HTTPS connection. The request looks similar to this:
POST /auth/O2/token HTTP/1.1
Host: api.amazon.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
grant_type=client_credentials&scope=messaging:push&client_id=(YOUR_CLIENT_ID)&client_secret=(YOUR_CLIENT_SECRET)
The request itself consists of two parts: a header and a message body. The header must contain the following field:
Field | Description | Example |
---|---|---|
Content-Type
|
The content type of the resource. Must be: application/x-www-form-urlencoded
|
Content-Type: application/x-www-form-urlencoded
|
For the content of the message body, you must provide a URL-encoded string containing the following parameters:
Parameter | Description | Example |
---|---|---|
grant_type
|
Value must be client_credentials
|
grant_type=client_credentials
|
scope
|
Value must be messaging:push
|
scope=messaging:push
|
client_id
|
The "client identifier" portion of your client credentials. |
client_id=amzn1.iba-client.<hexidecimal client credentials>
|
client_secret
|
The "client secret" portion of your client credentials. |
client_secret=<YOUR_CLIENT_SECRET>
|
Response format
After successfully receiving and interpreting your POST request message, ADM sends your server an HTTP response message that looks similar to this:
X-Amzn-RequestId: <client ID>
Content-Type: application/json
{
"access_token":"Atc|<client access token>",
"expires_in":3600,
"scope":"messaging:push",
"token_type":"Bearer"
}
The header for the response contains the following fields:
Header | Description | Example |
---|---|---|
X-Amzn-RequestId
|
A value created by ADM that uniquely identifies the request. In the unlikely event that you have problems with ADM, Amazon can use this value to troubleshoot the problem. |
X-Amzn-RequestId: <hexidecimal request ID>
|
Content-Type
|
The content type of the resource: application/json
|
Content-Type: application/json
|
When one of your servers successfully requests an access token you receive a 200 status code response, and the message body for the response to that request includes both the access token and its lifespan in seconds.
Parameter | Description | Example |
---|---|---|
access_token
|
An access token that must be used for all enqueue requests. |
"access_token":"<hexidecimal access token>"
|
expires_in
|
The duration in seconds of the access token lifetime. For example, the value "3600" denotes that the access token expires in one hour from the time the response was generated. |
"expires_in":3600
|
token_type
|
The type of the token issued. One of the supported token types. Currently only "Bearer" tokens are supported. |
"token_type":"Bearer"
|
scope
|
The scope specified in the access token request. Value will be messaging:push .
|
"scope":"messaging:push"
|
ADM returns a non-200 error status code for an unsuccessful request. In the case of a non-200 code, the response message might contain the following parameter in the body of the JSONObject
:
reason
: The reason the request was not accepted.
The following table lists possible error status codes for an access token request.
Code | Description | Example |
---|---|---|
400
|
Reasons for this response include:
* The content type is not supported by the authorization server. In other words, it is not application/x-www-form-urlencoded .
* The request is missing a required parameter: client_id , client_secret , scope , grant-type .
* The request is otherwise malformed.
* ADM has not been enabled for your security profile. See Obtain Credentials.
|
INVALID_REQUEST
|
400
|
The client is not authorized for the requested operation. |
UNAUTHORIZED_CLIENT
|
400
|
The grant type is not supported by the authorization server. In other words, it is not client_credentials .
|
UNSUPPORTED_GRANT_TYPE
|
400
|
The requested scope is invalid. In other words, it is not messaging:push .
|
INVALID_SCOPE
|
401
|
The client authentication failed. |
INVALID_CLIENT
|
500
|
There was an internal server error. The requester can retry the request. |
SERVER_ERROR
|
503
|
The server is temporarily unavailable. The requester must retry later honoring the Retry-After header included in the response. See the HTTP/1.1 specification, section 14.37, for possible formats for the Retry-After value.
|
SERVICE_UNAVAILABLE
|
Making the token request and handling the response
The following code sample is an example of how your server software might send the access token request and handle the ADM servers' response:
/**
* To obtain an access token, make an HTTPS request to Amazon
* and include your client_id and client_secret values.
*/
public String getAuthToken(String clientId, String clientSecret) throws Exception
{
// Encode the body of your request, including your clientID and clientSecret values.
String body = "grant_type=" + URLEncoder.encode("client_credentials", "UTF-8") + "&" +
"scope=" + URLEncoder.encode("messaging:push", "UTF-8") + "&" +
"client_id=" + URLEncoder.encode(clientId, "UTF-8") + "&" +
"client_secret=" + URLEncoder.encode(clientSecret, "UTF-8");
// Create a new URL object with the base URL for the access token request.
URL authUrl = new URL("https://api.amazon.com/auth/O2/token");
// Generate the HTTPS connection. You cannot make a connection over HTTP.
HttpsURLConnection con = (HttpsURLConnection) authUrl.openConnection();
con.setDoOutput( true );
con.setRequestMethod( "POST" );
// Set the Content-Type header.
con.setRequestProperty( "Content-Type" , "application/x-www-form-urlencoded" );
con.setRequestProperty( "Charset" , "UTF-8" );
// Send the encoded parameters on the connection.
OutputStream os = con.getOutputStream();
os.write(body.getBytes( "UTF-8" ));
os.flush();
con.connect();
// Convert the response into a String object.
String responseContent = parseResponse(con.getInputStream());
// Create a new JSONObject to hold the access token and extract
// the token from the response.
org.json. JSONObject parsedObject = new org.json.JSONObject(responseContent);
String accessToken = parsedObject.getString("access_token");
return accessToken;
}
private String parseResponse(InputStream in) throws Exception
{
InputStreamReader inputStream = new InputStreamReader(in, "UTF-8" );
BufferedReader buff = new BufferedReader(inputStream);
StringBuilder sb = new StringBuilder();
String line = buff.readLine();
while (line != null )
{
sb.append(line);
line = buff.readLine();
}
return sb.toString();
}
Last updated: Sep 21, 2022