Manage Skill Sessions and Session Attributes


Your skill can keep the skill session open to conduct a back-and-forth interaction with the user. While the session is open, the user doesn't need to use your invocation name to talk to your skill. To save data during the session, you can use session attributes.

Lifecycle of a skill session

The following steps show the lifecycle of a skill session.

  1. A skill session begins when a user invokes your skill and Alexa sends your skill a request. The request contains a Session object with a Boolean property called new to indicate that this request is for a new session.

  2. Your skill receives the request and returns a response for Alexa to speak to the user.

  3. What happens next depends on the value of the shouldEndSession parameter in your skill response:

    • true – After Alexa speaks the outputSpeech content, the session ends. Alexa, not the skill, handles any further speech from the user. If the user re-invokes the skill, Alexa creates a new session. Refer back to step 1.

    • false or null – After Alexa speaks the outputSpeech content, the session stays open, and Alexa opens the microphone to indicate that the skill expects the user to respond. If the user's response maps to your interaction model, Alexa sends a new intent to the skill and the process goes back to step 2.

      However, if a few seconds elapse without a response from the user, Alexa closes the microphone. If the skill specified a reprompt, Alexa reprompts the user to speak and opens the microphone for a few more seconds. If the user still doesn't respond, the session ends. For more details, see Support session ended.

      The session might remain open for a short time with the microphone closed if the user uses the skill on an Alexa-enabled device with a screen. For more details, see How devices with screens affect the skill session.

    • undefined (not set) – The session behavior depends on the type of Echo device.
      If the device has a screen and the skill response includes screen content, the session stays open for up to 30 more seconds, without opening the microphone to prompt the user for input. For more details, see How devices with screens affect the skill session. If the user speaks and precedes their request with the wake word (such as "Alexa,") Alexa sends the request to the skill. Otherwise, Alexa ignores the user's speech. If an Alexa Gadgets event handler is active, the session continues to stay open until the skill calls CustomInterfaceController.StopEventHandler or the event handler expires.

One exception overrides the shouldEndSession value. When you use skill connections to request a task from Amazon or another provider skill, you hand over control to the requested task and the session ends. Depending on the task, Alexa can hand control back to your skill. For example, the directives to start the purchase flow task for in-skill purchasing and paid skills automatically end the session, regardless of the shouldEndSession value. After the purchase flow completes, you use saved session attributes to resume the skill. For details, see Skill Connections.

Example session interactions

The following example shows a skill session where the skill responds to the user, and then closes the session. The skill doesn't prompt the user for input.

User: Alexa, open Quick Trivia and tell me the trivia of the day.

Quick Trivia: On 21 July 1969, American astronaut Neil Armstrong became the first person to walk on the Moon.
The skill closes the session with shouldEndSession=true.

The following example shows a skill session where the skill responds to the user, and then keeps the session open. The skill prompts the user for input.

User: Alexa, play Quick Trivia.

Quick Trivia: Who was the first astronaut to walk on the Moon?
The skill keeps the session open with shouldEndSession=false.
User: Neil Armstrong!

Quick Trivia: That's right! Do you want another question?
The skill keeps the session open with shouldEndSession=false.
User: No.

Quick Trivia: OK. Come back soon!
The skill closes the session with shouldEndSession=true.

How devices with screens affect the skill session

When the user invokes a skill on an Alexa-enabled device with a screen, the session can remain open for up to 30 additional seconds with the microphone closed. The user continues to see content related to the skill on the screen. To continue interacting with the skill, the user can use the wake word to speak to Alexa, followed by an utterance that maps to the interaction model for the skill.

This extended session occurs when all the following conditions are true:

  • The user invokes the skill with a device with a screen (such as an Echo Show).
  • The skill configuration supports devices with screens. This means that one of these options on the Build > Interfaces page in the developer console is enabled:
    • Alexa Presentation Language
    • Display Interface (deprecated)
  • The skill response includes content to display on the screen. The visual content can be one of the following items:
    • An Alexa Presentation Language (APL) document, displayed when you return the Alexa.Presentation.APL.RenderDocument directive.
    • An Alexa app card, displayed when you include a card object. Although cards are intended for the Alexa app, screen devices display card content when you don't provide any other screen content.
  • The shouldEndSession value in the response is either false or undefined (not set).
    • When undefined, the extended session remains open for approximately 30 seconds.
    • When false, the extended session occurs after the user fails to respond to the reprompt. Here, the session remains open for between 20 and 30 seconds.

For example, a skill configured to support screen devices and display content on the screen might have the following interaction on a device with a screen.

User: Alexa, open Quick Trivia.

The skill gets a LaunchRequest, and then responds with a prompt and shouldEndSession = false.

Quick Trivia: Welcome to Quick Trivia. I know facts about space, how long it takes to travel between two planets and I even know a joke. What do you want to know?
Alexa speaks the prompt.
The screen displays content related to Quick Trivia, such as an APL document sent by means of the RenderDocument directive.

User: ….

User says nothing. A few seconds elapse.
Quick Trivia: Try asking me to tell you something about space.
Alexa speaks the reprompt provided with the response.

User: Um….

More time passes.
Microphone closes, but the session remains open. Content about Quick Trivia continues to display onscreen.
User: Alexa, tell me about Mars.

User interacts with the skill without using the invocation name, since the skill session is still active.
Alexa sends the skill a PlanetFacts intent. The request shows that this is a continuing session, not a new session.

Quick Trivia: On Mars….

Save data during the session

To retain data during the session, use session attributes. Create a map of key-value pairs with the data you need to save. Include this map in the sessionAttributes property of your response. When Alexa sends the next request as part of the same session, the request includes the same map in the session.attributes property. Use the keys that you defined to retrieve the data from the map.

The following example shows an example skill session where the skill saves an attribute in the response and retrieves it in the request.

…earlier utterances to start this interaction.

User: My favorite color is blue

Alexa sends the skill the FavoriteColorIntent with the favoriteColor slot set to "blue". The skill responds with text to speak and a session attribute with the key favoriteColor and the value "blue".

Skill: I now know your favorite color is blue. What do you want to know?
User: What was that color again?

Alexa sends the skill the WhatsMyColorIntent intent. The request includes the favoriteColor session attribute. The skill retrieves this attribute to build the response.
Skill: Your favorite color is blue.

Session attributes are useful for several situations:

  • Keep track of state data to handle different skill states, such as a state attribute to indicate whether the user is already in a game or ready to start a new game. Use the attribute as criteria in the code that determines whether a handler can handle a particular request. This can be especially useful if your skill asks the user multiple yes/no questions, since the response "yes" or "no" may have a different meaning depending on skill state.
  • Keep track of game scores and counters.
  • Save slot values that the user has provided as you continue to prompt for additional values. Note that as an alternative, you can use a dialog model and delegate the dialog to accomplish this without session attributes. See Delegate the Dialog to Alexa.

Store session attributes

The Alexa Skills Kit SDKs provide an AttributesManager to add session attributes to your response, and then retrieve the attributes from an incoming request.

The following example shows how an intent handler can save data into the session attributes. In this example, the FavoriteColorIntent has a single, required slot called favoriteColor. The intent is configured with auto-delegation, so Alexa prompts the user to fill the slot if the user doesn't provide a value initially.

Copied to clipboard.

This code example uses the Alexa Skills Kit SDK for Node.js (v2).

const FavoriteColorIntentHandler = {
  canHandle(handlerInput) {
    getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
    && getIntentName(handlerInput.requestEnvelope) === 'FavoriteColorIntent'
    && getDialogState(handlerInput.requestEnvelope) === 'COMPLETED';
  },
  handle(handlerInput) {
    const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
    const favoriteColor = getSlotValue(handlerInput.requestEnvelope, 'favoriteColor')
    sessionAttributes.favoriteColor = favoriteColor;
    handlerInput.attributesManager.setSessionAttributes(sessionAttributes);
 
    const speechText = `I saved the value ${favoriteColor} in the session attributes.
    Ask me for your favorite color to demonstrate retrieving the attributes.`;
    const repromptText = `You can ask me, what's my favorite color?`;
 
    return handlerInput.responseBuilder
      .speak(speechText)
      .reprompt(repromptText)
      .getResponse();
  }
};

Copied to clipboard.

This code example uses the Alexa Skills Kit SDK for Python.

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.utils import is_intent_name, get_dialog_state, get_slot_value
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model import Response, DialogState
 
 
class FavoriteColorIntentHandler(AbstractRequestHandler):
    """Handler for FavoriteColorIntent."""
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return is_intent_name("FavoriteColorIntent")(
            handler_input) and get_dialog_state(
            handler_input=handler_input) == DialogState.COMPLETED
 
    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
 
        # Get any existing attributes from the incoming request
        session_attr = handler_input.attributes_manager.session_attributes
 
        # Get the slot value from the request and add it to the session 
        # attributes dictionary. Because of the dialog model and dialog 
        # delegation, this code only ever runs when the favoriteColor slot 
        # contains a value, so a null check is not necessary.
        fav_color = get_slot_value("favoriteColor")
        session_attr["favoriteColor"] = fav_color
 
        # The SDK automatically saves the attributes to the session, 
        # so that the value is available to the next intent
 
        speech_text = ("I saved the value {} in the session attributes. "
                       "Ask me for your favorite color to demonstrate "
                       "retrieving the attributes.").format(fav_color)
 
        reprompt_text = "You can ask me, what's my favorite color?"
 
        return handler_input.response_builder.speak(speech_text).ask(
            reprompt_text).response

Copied to clipboard.

This code example uses the Alexa Skills Kit SDK for Java.

package handlers;

import static com.amazon.ask.request.Predicates.intentName;

import java.util.Map;
import java.util.Optional;

import com.amazon.ask.attributes.AttributesManager;
import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.dispatcher.request.handler.impl.IntentRequestHandler;
import com.amazon.ask.model.DialogState;
import com.amazon.ask.model.IntentRequest;
import com.amazon.ask.model.Response;
import com.amazon.ask.request.RequestHelper;

public class FavoriteColorIntentHandler implements IntentRequestHandler {
    @Override
    public boolean canHandle(HandlerInput handlerInput, IntentRequest intentRequest) {
        // This intent is configured with required slots and auto-delegation,
        // so the handler only needs to handle completed dialogs.
        return handlerInput.matches(intentName("FavoriteColorIntent"))
                && intentRequest.getDialogState() == DialogState.COMPLETED;        
    }

    @Override
    public Optional<Response> handle(HandlerInput handlerInput, IntentRequest intentRequest) {

        RequestHelper requestHelper = RequestHelper.forHandlerInput(handlerInput);

        // Get any existing attributes from the incoming request
        AttributesManager attributesManager = handlerInput.getAttributesManager();
        Map<String,Object> attributes = attributesManager.getSessionAttributes();
        
        // Get the slot value from the request and add to a map for the attributes.
        // Because of the dialog model and dialog delegation, this code only ever
        // runs when the favoriteColor slot contains a value, so a null check
        // is not necessary.
        Optional<String> favoriteColor = requestHelper.getSlotValue("favoriteColor");                
        attributes.put("favoriteColor", favoriteColor.get());
        
        // This saves the attributes to the session, so the value is available
        // to the next intent.
        attributesManager.setSessionAttributes(attributes);

        // Include a reprompt in the response to automatically set 
        // shouldEndSession to false.
        return handlerInput.getResponseBuilder()
                .withSpeech("I saved the value " + favoriteColor.get() + 
                    " in the session attributes. Ask me for your favorite color" +
                    " to demonstrate retrieving the attributes." )
                .withReprompt("You can ask me, what's my favorite color?")
                .build();
    }
}

Copied to clipboard.

The following code example shows the JSON response sent by the FavoriteColorIntentHandler. You can see that the sessionAttributes object includes the favoriteColor property.

{
  "version": "1.0",
  "sessionAttributes": {
    "favoriteColor": "blue"
  },
  "response": {
    "outputSpeech": {
      "type": "SSML",
      "ssml": "<speak>I saved the value blue in the session attributes. Ask me for your favorite color to demonstrate retrieving the attributes.</speak>"
    },
    "reprompt": {
      "outputSpeech": {
        "type": "SSML",
        "ssml": "<speak>You can ask me, what's my favorite color?</speak>"
      }
    },
    "shouldEndSession": false
  }
}

Access session attributes

The following example shows how an intent handler can access data from the session attributes. In this example, the WhatsMyColorIntent has no slots. It retrieves previously set data from the session attributes to respond. If the data doesn't yet exist (because the user invoked this intent before invoking FavoriteColorIntent), the handler uses the Dialog.ElicitSlot directive to invoke FavoriteColorIntent and prompt for the missing data.

Copied to clipboard.

This code example uses the Alexa Skills Kit SDK for Node.js (v2).

const WhatsMyColorIntentHandler = {
  canHandle(handlerInput) {
    getRequestType(handlerInput.requestEnvelope) === 'IntentRequest'
    && getIntentName(handlerInput.requestEnvelope) === 'WhatsMyColorIntent';
  },
  handle(handlerInput) {
    const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
    if (sessionAttributes.favoriteColor) {
      return handlerInput.responseBuilder
        .speak(`Your favorite color is ${sessionAttributes.favoriteColor}`)
        .getResponse();
    } else {
      return handlerInput.responseBuilder
        .speak('You need to tell me your favorite color first.')
        .reprompt('Please tell me your favorite color.')
        .addElicitSlotDirective('favoriteColor')
        .getResponse();
    }
  }
}

Copied to clipboard.

This code example uses the Alexa Skills Kit SDK for Python.

from ask_sdk_core.dispatch_components import AbstractRequestHandler
from ask_sdk_core.utils import is_intent_name, get_slot_value
from ask_sdk_core.handler_input import HandlerInput
from ask_sdk_model import Response, Intent
from ask_sdk_model.dialog import ElicitSlotDirective
 
 
class WhatsMyColorIntentHandler(AbstractRequestHandler):
    """Handler for WhatsMyColorIntent."""
    def can_handle(self, handler_input):
        # type: (HandlerInput) -> bool
        return is_intent_name("WhatsMyColorIntent")(handler_input)
 
    def handle(self, handler_input):
        # type: (HandlerInput) -> Response
 
        session_attr = handler_input.attributes_manager.session_attributes
 
        # The user could invoke this intent before they set their favorite 
        # color, so check for the session attribute first.
        if "favoriteColor" in session_attr:
            fav_color = session_attr["favoriteColor"]
 
            return handler_input.response_builder.speak(
                "Your favorite color is {}. Goodbye".format(
                    fav_color)).set_should_end_session(True).response
        else:
            # The user must have invoked this intent before they set their color. 
            # Trigger the FavoriteColorIntent and ask the user to fill in the 
            # favoriteColor slot. Note that the skill must have a *dialog model* 
            # to use the ElicitSlot Directive.
 
            return handler_input.response_builder.speak(
                "You need to tell me your favorite color first.").ask(
                "please tell me your favorite color.").add_directive(
                directive=ElicitSlotDirective(
                    updated_intent=Intent(
                        name="FavoriteColorIntent"), 
                    slot_to_elicit="favoriteColor")).response

Copied to clipboard.

This code example uses the Alexa Skills Kit SDK for Java.

package handlers;

import static com.amazon.ask.request.Predicates.intentName;

import java.util.Map;
import java.util.Optional;

import com.amazon.ask.attributes.AttributesManager;
import com.amazon.ask.dispatcher.request.handler.HandlerInput;
import com.amazon.ask.dispatcher.request.handler.impl.IntentRequestHandler;
import com.amazon.ask.model.Intent;
import com.amazon.ask.model.IntentRequest;
import com.amazon.ask.model.Response;

public class WhatsMyColorIntentHandler implements IntentRequestHandler {
    @Override
    public boolean canHandle(HandlerInput handlerInput, IntentRequest intentRequest) {
        return handlerInput.matches(intentName("WhatsMyColorIntent"));
    }

    @Override
    public Optional<Response> handle(HandlerInput handlerInput, IntentRequest intentRequest) {

        AttributesManager attributesManager = handlerInput.getAttributesManager();
        Map <String,Object> attributes = attributesManager.getSessionAttributes();

        // The user could invoke this intent before they set their favorite
        // color, so check for the session attribute first.
        if (attributes.containsKey("favoriteColor")){
            String favoriteColor = attributes.get("favoriteColor").toString();

            return handlerInput.getResponseBuilder()
                    .withSpeech("Your favorite color is " + favoriteColor + ". Goodbye")
                    .withShouldEndSession(true)
                    .build();
        } else {
            // The user must have invoked this intent before they set their color.
            // Trigger the FavoriteColorIntent and ask the user to fill in the 
            // favoriteColor slot. Note that the skill must have a *dialog model*
            // to use the ElicitSlot directive.

            // Create the intent.
            Intent intent = Intent.builder()
                .withName("FavoriteColorIntent")
                .build();

            return handlerInput.getResponseBuilder()
                    .withSpeech("You need to tell me your favorite color first.")
                    .withReprompt("Please tell me your favorite color.")
                    .addElicitSlotDirective("favoriteColor", intent)
                    .build();
        }

    }
}

Copied to clipboard.

The following JSON example shows the incoming IntentRequest when the user provides the name of a color. You can see the color in the session.attributes property.

{
  "version": "1.0",
  "session": {
    "new": false,
    "sessionId": "amzn1.echo-api.session.1",
    "application": {
      "applicationId": "amzn1.ask.skill.1"
    },
    "attributes": {
      "favoriteColor": "blue"
    },
    "user": {
      "userId": "amzn1.ask.account.1"
    }
  },
  "context": {},
  "request": {
    "type": "IntentRequest",
    "requestId": "amzn1.echo-api.request.1",
    "timestamp": "2019-02-13T04:22:36Z",
    "locale": "en-US",
    "intent": {
      "name": "WhatsMyColorIntent",
      "confirmationStatus": "NONE"
    }
  }
}

Structure of session attributes

You can pass along more complex data in the session attributes if necessary, as long as you can structure the data into a key/value map. For example, a quiz game skill might need attributes to keep track of the current state of the game, the user's current score, and the correct answer to the question that was just asked.

In the following example, the quizitem attribute represents the correct answers to the current question.

  {
  "sessionAttributes": {
    "quizscore": 0,
    "quizproperty": "STATEHOOD_YEAR",
    "response": "OK.  I will ask you 10 questions about the United States. ",
    "state": "_QUIZ",
    "counter": 1,
    "quizitem": {
      "name": "Nevada",
      "abbreviation": "NV",
      "capital": "Carson City",
      "statehoodYear": "1864",
      "statehoodOrder": "36"
    }
  }
}

Save data between sessions

Session attributes exist while the session is open. After the session ends, any attributes associated with that session are lost. If your skill needs to remember data across multiple sessions, you need to save that data in persistent storage, such as Amazon DynamoDB or Amazon S3.

You can use the userId provided in each request to identify the user. The userId for a given user is generated when the user enables your skill in the Alexa app. Every subsequent request from that user to your skill contains the same userId unless the user disables the skill.

Persisting attributes between skill sessions is built in to the ASK SDKs for Node.js, Java, and Python. For details, see Managing Attributes.

Support session ended

When your skill sets shouldEndSession=true, Alexa doesn't send any further requests to your skill session. However, there are cases when your skill might leave the session open, but the session ends unexpectedly. A session ends when one of the following happens:

  • The user explicitly ends the session.
  • An error occurs that causes the session to end.
  • The user either doesn't respond or responds with an utterance that doesn't match any intents defined in your custom voice interface model.

To notify your skill that the session ended, Alexa sends a SessionEndedRequest. Although your skill can't return a response with speech, a card, or directives after you receive a SessionEndedRequest, your SessionEndedRequest handler is a good place to put your cleanup logic.

Sample code

The following sample code demonstrates how to persist session attributes:

The following sample code demonstrates how to store more complex session attributes for game state:


Was this page helpful?

Last updated: Mar 13, 2024