Get a User-Specific Access Token for Out-of-Session Calls to Alexa

There are certain Alexa resources that your custom skill might need to access at any time. For example, your skill might send a notification to a user, access their shopping list, read their device location, and so on. These actions might happen outside of the skill session. To call Alexa APIs outside of a skill session, your skill must store and refresh user-specific Alexa access tokens asynchronously.

Overview

To understand why a skill might need to access Alexa resources outside of a skill session, let's review what a skill session is. Skill sessions begin and end as follows:

  1. A skill session begins when a user invokes your skill with an utterance such as "Alexa, open Ride Hailer." This utterance causes Alexa to send your skill a request. This request is usually a launch request, although a user might invoke your skill with a specific intent also. The request contains a session object that contains a sessionId that uniquely identifies the skill session.
  2. As the user interacts with your skill, Alexa sends your skill requests. These requests contain the unique sessionId described previously. Your skill responds to the requests.
  3. The skill session ends when the user doesn't respond to Alexa or the skill sends Alexa a request with shouldEndSession set to true. When the skill session ends, Alexa no longer sends the skill requests with that particular sessionId. A user can invoke a new skill session, which has a new sessionId, but the previous skill session no longer exists.

Although most interactions between Alexa and a skill happen inside of a skill session, your skill might need to access Alexa resources even when the user doesn't explicitly invoke your skill as described previously. For example, a skill that manages a user's shopping list might need to update the list at any time. These requests are called out-of-session requests.

For out-of-session requests, your skill needs a user-specific access token. Before your skill can get a user-specific access token, your skill must first receive a user-specific authorization code. Your skill then uses the typical OAuth 2.0 authorization code grant flow to exchange the authorization code and client credentials for an access token.

If your skill doesn't properly exchange the authorization code for an access token, Alexa shows the user an error when the user enables the skill or modifies consent. In these cases, Alexa prompts the user to retry authorization.

The endpoint that you use to receive authorization code depends on whether your skill uses account linking, as described next.

Steps for skills that use account linking

When users link an account from your service with an Alexa skill, the user allows Alexa to access their account resources in your service. Alexa then stores and refreshes access tokens through the typical OAuth 2.0 authorization grant flow.

In many cases, however, the user also wants to authorize your skill to access their Alexa resources without having to go through another log-in flow. This is called reciprocal authorization.

Step 1: Receive the authorization code

Alexa provides an authorization code by making a secure HTTP POST application/x-www-form-urlencoded request to the following endpoint with the following parameters.

Endpoint

Your skill receives authorization codes at the reciprocalAccessTokenUrl that you specify in the account linking schema within the skill manifest.

Request parameters

The POST request contains the following parameters.

Field Description

grant_type

The grant type, which is reciprocal_authorization_code.

code

The Alexa authorization code for the user.

client_id

An identifier for your skill. You can use the client_id to provide any skill-specific functionality, such as distinguishing between different skills you have configured with account linking. You define the client_id when you configure account linking for your skill.

Example

The following is an example of a request that provides an authorization code.

POST
Content-Type: application/x-www-form-urlencoded
Authorization: Bearer (3P access token)
grant_type=reciprocal_authorization_code&code=EXAMPLEAUTHCODE1234&client_id=someClientId

Step 2: Exchange the authorization code for an access token

After the reciprocal access token endpoint receives the authorization token, the reciprocal access token endpoint must do the following:

  1. Verify that the provided access token in the authorization header is valid and represents a user in the authorization server configured in the account linking settings of the skill.
  2. Exchange the provided Alexa authorization code for the Alexa access token. For details about exchanging an authorization code for an access token, see Access Token Request in the Login with Amazon (LWA) documentation.
  3. Return one of the following HTTP codes:
    • Return HTTP 200 (OK) if you successfully exchange the authorization code for an access token.
    • Return HTTP 400 (BAD_REQUEST) if something goes wrong when you try to exchange the authorization code for an access token.
    • Return HTTP 500 (INTERNAL_SERVER_ERROR) if anything else goes wrong.

Steps for skills that don't use account linking

If your skill doesn't require account linking, you can identify the Alexa user by using the userId from the system object of in-session requests and events from Alexa. For details about the system object, see System object.

Step 1: Receive the authorization code

Alexa provides an authorization code by sending an Alexa.Authorization.Grant request to the following endpoint with the following parameters.

Endpoint

Your skill receives authorization codes at the endpoint that you specify in the custom object of the skill manifest.

If you have different regionalized endpoints set up for your skill, Alexa invokes the URI of the appropriate region.

Request parameters

The request contains the following parameters.

Field Description

type

The request type, which is Alexa.Authorization.Grant.

requestId

The request ID.

timestamp

The timestamp of the request.

body.grant.type

The type of authorization code, which is OAuth2.AuthorizationCode.

body.grant.code

The Alexa authorization code for the user.

Example

The following is an example of a request that provides an authorization code.

{
  "version": "1.0",
  "context": {
    "System": {
      "application": {
        "applicationId": "amzn1.ask.skill.aaa"
      },
      "user": {
        "userId": "amzn1.ask.account.AAA"
      },
      "apiEndpoint": "https://api.amazonalexa.com"
   },
   "request": {
     "type": "Alexa.Authorization.Grant",
     "requestId": "12345-6789-EXAMPLE",
     "timestamp": "2018-01-01T12:00:00Z",
     "body" : {
        "grant": {
           "type": "OAuth2.AuthorizationCode",
           "code": "EXAMPLEAUTHCODE1234"
         }
       }  
     }
  }
}

Step 2: Exchange the authorization code for an access token

The endpoint that receives the authorization code must do the following:

  1. Exchange the provided Alexa authorization code for the Alexa access token. For details about exchanging an authorization code for an access token, see Access Token Request in the Login with Amazon (LWA) documentation.
  2. If the previous step was successful, associate the access token with the userId.
  3. Return one of the following HTTP codes:
    • Return HTTP 200 (OK) if you successfully exchange the authorization code for an access token.
    • Return HTTP 400 (BAD_REQUEST) if something goes wrong when you try to exchange the authorization code for an access token.
    • Return HTTP 500 (INTERNAL_SERVER_ERROR) if anything else goes wrong.