Use Location Services for Alexa Skills


With location services, your skill can ask a user's permission to obtain the real-time location of their Alexa-enabled device, specifically at the time of the user's request to Alexa, so that the skill can provide enhanced services. When a user enables a skill that requests to use location services, the user is prompted in the Alexa app to consent to the location data being shared with the skill. Users can visit the Alexa Privacy Settings page in the Alexa app at any time to manage their skill permissions.

If you want to enable the user to verbally consent to share their location information with your skill, see Use Voice-Forward Consent in Your Alexa Skill.

How location services work

This figure shows how the location services features works to coordinate between Alexa, the customer device, and the skill.

Coordination of location information
Coordination of location information


Conditions for location services

Any skill that uses location information must meet the requirements below. If Amazon determines that your skill violates any of these requirements, we may reject or suspend your submission and notify you using the email address associated with your developer account.

  • You must include a link to the Privacy Policy that applies to your skill on the Distribution page of the developer console.
  • Your skill must not be a child-directed skill. See here for more information on child-directed skills.
  • You may request permission to receive location information only when required to support the features and services provided by your skill. You may use any personal information you request only as permitted by the user and in accordance with your privacy notice and applicable law.
  • You may not use location information, or other customer information, to link the customer's account in the background. That is, you may not associate an Alexa customer to a customer in your account pool with the same location information. Customers' Amazon account information is not verified and may be outdated.
  • The skill must obtain the latest location information every time the customer invokes the skill with a request that needs this information, and the skill must overwrite the prior location data it had from the customer's previous request (that is, store only the most recent data).

"Current device location" is represented by geo-coordinates (including latitude, longitude, altitude, and so forth), which may be used as proxies for location for mobile devices like a smartphone or an in-car navigation system.

Device address as compared to geo-coordinates

Device address, such as "585 Broadway", is not the same as device geo-coordinates. Mobile devices can move around, so a mobile device's current location likely varies considerably from its registered device address. For stationary devices like the Amazon Echo, Alexa can provide you the device's physical address with the Device Address API. Stationary devices do not provide geo-coordinate data through location services.

For mobile devices, your skill should use location services instead of the Device Address API for the device's current location, with a few exceptions. For a pizza delivery skill, you may want to use the actual device address, not geo-coordinates, so that you can deliver the pizza to a precise location. For local search or navigation skills, geo-coordinates will be more useful than device address, because the customer's current location may be different than their home address.

Configure your skill to use location services

Configure your skill to use location services, as follows:

  • Step 1–Enable Location Services permissions
  • Step 2–Modify your skill service logic to handle location services data
  • Step 3–Test your skill to ensure location services works as expected.

Step 1–Enable Location Services permissions

  • Go to the developer console at (https://developer.amazon.com/alexa), sign in if you have not already, and click Skills at the upper right.

  • Click Edit for your skill page in the developer console to open your skill.

  • Select Build > Permissions and enable the Location Services button. Without doing so, your skill cannot ask the customer for permissions to use location information.

Location Services permissions enabled in the developer console
Location Services permissions enabled in the developer console

This configuration informs Alexa that your skill wants to use dynamic customer location. If your skill is configured for Location Services, and the customer's permissions allow, Alexa will pass on the customer location inside the Service Provider Interface (SPI). If the Location Services button is not turned on, your skill will not receive customer location data.

Step 2–Modify your skill service logic to handle location services data

Inside your skill function, customer location data can be found in the custom skills context, which is a JSON object that is sent to your AWS Lambda function or to your web service.

Specifically, the data is contained in the "Geolocation" section of the context object, at context.Geolocation.

The following code sample prints out geo-coordinates of the customer's device. Remember, only those customers who are using an Alexa-enabled device with its own location services can share their geo-coordinates with your skill, assuming the proper permissions have been granted. To determine whether the customer's device can share location, check whether the context.System.device.supportedInterfaces object has a Geolocation field. If the Geolocation field does not exist, then the customer's device is unable to provide any location data, which is the case for stationary devices like the Amazon Echo. In that case, your skill should provide a customer experience that does not require knowing the customer's location like prompting the user that you are unable to receive customer's real-time location.

var isGeoSupported = context.System.device.supportedInterfaces.Geolocation;
var geoObject = context.Geolocation;
if (isGeoSupported) {
	var ACCURACY_THRESHOLD = 100; // accuracy of 100 meters required
                if (geoObject && geoObject.coordinate && geoObject.coordinate.accuracyInMeters < ACCURACY_THRESHOLD ) { 
                         console.log(geoObject);  // Print the geo-coordinates object if accuracy is within 100 meters
                }
}

A sample payload is shown below. A coordinate object must contain latitudeInDegrees, longitudeInDegrees, and accuracyInMeters, whereas altitude, heading, and speed are optional objects for the device to share with Alexa, and thus these optional fields may not be available to skills. For a more detailed description of each field, refer to Full Description of Geolocation Interface.

     "Geolocation":{ 
        "locationServices": { 
            "access": "ENABLED",
            "status": "RUNNING",   
        },
        "timestamp": "2018-03-25T00:00:00Z+00:00",
        "coordinate": {
            "latitudeInDegrees": 38.2,
            "longitudeInDegrees": 28.3,
            "accuracyInMeters": 12.1 
        },
        "altitude": {
            "altitudeInMeters": 120.1,
            "accuracyInMeters": 30.1
        },
        "heading": { 
            "directionInDegrees": 180.0,
            "accuracyInDegrees": 5.0  
        },
        "speed": { 
            "speedInMetersPerSecond": 10.0,
            "accuracyInMetresPerSecond": 1.1
        }       
      }
   }

Step 3–Test your skill

Once your skill logic is written to handle geo-coordinates, you can start testing with a mobile device like the Alexa app.

User location (if available) is passed to your skill with each user utterance. In the following exchange, for example, user location is sent twice to the Alexa. If the user is in-motion, each utterance may contain different user location data. Location services does not support real-time streams of location data.

Here is a sample test dialog:

User: Alexa, take me to the nearest coffee shop.

Geo Test: Providing directions to Example Coffee Shop at 2008 Pine Street.
User: Alexa, where's the nearest movie theater?

The nearest movie theater is at 1100 Pike St.:

The geo-coordinate information ultimately comes from the hardware device, which uses its own location services to obtain this data. Alexa does not control the source of this data, such as whether it comes from GPS or is IP-derived. Thus, Alexa does not control the granularity nor the accuracy of user location data that is sent to a skill. However, a mobile device with Alexa must provide accuracy metrics (in the form of accuracy in meters, context.Geolocation.coordinates.accuracyInMeters) so that skills can decide whether the level of accuracy is sufficient for the desired use within the skill.

Geolocation interface properties

At least one of the locationServices object or the coordinate object must be present in the payload.

Parameter Description Type Valid Values Optional?
locationServices Indicates whether location sharing is turned on in the user device. object Yes
locationServices.access Indicates whether location sharing access is enabled or disabled. Enum string One of: "ENABLED", "DISABLED" No, if locationServices is present
locationServices.status If locationServices.access is set to "ENABLED", and locationServices.status is set to "RUNNING", then location sharing access is enabled and running. Enum string One of: "RUNNING", "STOPPED" No, if locationServices is present
timestamp Device time when GPS data was updated in the device string
Example:
2016-09-09T21:28:45+00:00
ISO 8601
(Preferably RFC 3339)
No
coordinate Provides coordinates of device object No, if locationServices is not present
coordinate.latitudeInDegrees Degrees from equator double [-90.0, 90.0] No, if coordinate is present
coordinate.longitudeInDegrees Degrees from prime meridian double [-180.0, 180] No, if coordinate is present
coordinate.accuracyInMeters Uncertainty in the latitude and longitude in meters double [0, MAX_INTEGER] No, if coordinate is present
altitude Indicates altitude of the device object Yes
altitude.altitudeInMeters Meters above sea level within GPS limits double [-6350, 18000] Yes
altitude.accuracyInMeters Uncertainty in the altitude in meters double [0, MAX_INTEGER] Yes
heading Indicates heading of the device object Yes
heading.directionInDegrees Degrees from true north double (0.0, 360.0] Yes
heading.accuracyInDegrees Optional accuracy parameter for direction double [0, MAX_INTEGER] Yes
speed Indicates speed of the device object Yes
speed.speedInMetersPerSecond Meters per second within GPS limits double [0, 1900] Yes, except for automotive (via contract)
speed.accuracyInMetersPerSecond Optional accuracy parameter for speed double [0, MAX_INTEGER] Yes

Check freshness and accuracy of data

It is important to check both the freshness and accuracy of the location data prior to using this data in the skill. Customer location can change quickly, such as when a customer is driving, which would make 10-minute-old GPS data highly imprecise.

To check for freshness, look at the difference between Geolocation.timestamp and the timestamp of your IntentRequest (request.timestamp). If this difference is small, the data is fresh. The Geolocation.timestamp value is the time when the customer location was measured inside the device. The request.timestamp value is roughly the current time when your skill is invoked.

By combining the freshness and accuracy check, you can create logic to determine whether the location data is usable. Suppose you want data with a desired accuracy of 100 meters and freshness of 1 minute, as shown in the following sample code:

var isGeoSupported = context.System.device.supportedInterfaces.Geolocation;
var geoObject = context.Geolocation;
if (isGeoSupported) {
	var freshness = ( new Date(request.timestamp) - new Date(geoObject.timestamp) ) / 1000; // freshness in seconds
	var ACCURACY_THRESHOLD = 100; // accuracy of 100 meters required
                if ( geoObject && geoObject.coordinate && geoObject.coordinate.accuracyInMeters < ACCURACY_THRESHOLD && freshness < 60 ) {
                          //  your code here
                }
}

Your skill payload may be missing geo-coordinates data, which you can check by testing to see if context.Geolocation is null. If so, context.Geolocation can be null due to three reasons, assuming you have enabled Location Services in the developer console.

  • Case 1: The customer's device is stationary, such as an Amazon Echo, or it is not set up to send its location to Alexa. In this case, the device's coordinates are unavailable by default, because it is not a valid mobile device.

  • Case 2: The customer has not opted in to share location with your skill. In this case, you may consider resolving this issue by asking the customer for permissions using the AskForPermissionsConsent card.

  • Case 3: The customer's hardware has location sharing turned off or the customer has not opted to share location with Alexa. For example, the location services on the customer's device, such as a mobile phone, may be turned off. In this case, you may consider asking the customer to turn on location sharing with Alexa.

In addition, two or more of the cases may apply at the same time. For example, the customer may not have granted location sharing permissions for your skill, and the device's location sharing may also be turned off as well.

To see if Case 1 applies, check the context.System.device.supportedInterfaces.Geolocation field to see if it is set to true, as shown in the previous code sample. If Case 1 does not apply, proceed to test Case 2.

For Case 2, ask for the customer to provide permissions to obtain location information for Alexa or your skill. To ask the customer, return the AskForPermissionsConsent card as a response. This card sends an instruction card to the customer's Alexa app, and the card contains instructions which tell how to turn on location sharing for Alexa or for your skill.

Card to request locations permissions
Card to request locations permissions

This sample code returns a response that generates an AskForPermissionsConsent card for a hypothetical skill called FindMyWayHome. We recommend the use of the Alexa Skills Kit SDK for Node.js to simplify the response creation, as shown here.

var isGeolocationSupported = context.System.device.supportedInterfaces.Geolocation;
if ( isGeolocationSupported ) {   //  does the device support location based features? 
        var geoObject = context.Geolocation;
        if ( ! geoObject || ! geoObject.coordinate ) {
          return responseBuilder
            .speak('FindMyWayHome would like to use your location. To turn on location sharing, please go to your Alexa app, and follow the instructions.')
            .withAskForPermissionsConsentCard(['alexa::devices:all:geolocation:read'])
            .getResponse();
        } else {
          // use location data
        }
}

Notice that the response has two sections: card and outputSpeech. The card's type is AskForPermissionsConsent, which tells Alexa what kind of instructions card to send to the customer. This card allows you to specify a list of permissions scopes inside the permissions list. For location permissions, the skill must pass alexa::devices:all:geolocation:read as part of the list of permissions.

Along with sending this instruction card, the skill must specify what Alexa will say to the customer, such as "FindMyWayHome would like to use your location. To turn on location sharing, please go to your Alexa app, and follow the instructions". Place your speech in the outputSpeech section of the response. Without verbal cues, the customer will likely assume your skill is in an error state.

Once this response is returned, the following sequence of events will occur.

1. The customer hears "FindMyWayHome would like to use your location. To turn on location sharing, please go to your Alexa app, and follow the instructions".

2. Alexa independently verifies whether there are missing permissions for location sharing to happen.

3. Alexa sends a home card with instructions for turning on location sharing, and the session terminates.

Depending on which permissions are missing, Alexa will send different instructional cards to the customer's Alexa app. If your skill has permission to use the customer's location, but Alexa does not, then the content of the card differs from when the skill does not have permission to use the customer's location.

Card to request locations permissions
Card to request locations permissions

If, however, neither Alexa nor your skill has the customer's permission, then the following instructional card is created.

Location permissions requested by skill
Location permissions requested by skill

4. After the customer takes the actions instructed in the card and retries using your skill, the context.Geolocation object should contain a valid coordinates object.

Amazon can receive
device location?
Skill can receive location
from Amazon?
Skill location access Developer action
TRUE TRUE YES None
TRUE FALSE NO Permission card to request location permissions
FALSE TRUE NO Ask the customer to turn on location sharing to Alexa
FALSE FALSE NO Permission card to request location permissions

Detect which specific permissions are needed

As described, you can determine whether your skill and Alexa each has permissions to access device location. Your skill can use this information to further customize your speech when the AskForPermissionsConsent card is returned.

To determine whether your skill has permissions to read location, check the value in context.System.user. This object contains metadata about the current user, including the permissions.scopes object, which tracks the set of permissions the user has granted to your skill. You can inspect the values for each individual scope, such as scopes['alexa::devices:all:geolocation:read'].status, which should be "GRANTED" if your skill has permissions.

Thus, if you want your skill to throw the instructions card only when your skill is lacking permissions, use code similar to the following:

if ( isGeolocationSupported ) {   //  does the device support location based features? 
	var geoObject = context.Geolocation;
	if ( ! geoObject || ! geoObject.coordinate ) {
var skillPermissionGranted = context.System.user.permissions.scopes['alexa::devices:all:geolocation:read'].status === "GRANTED";
if ( !skillPermissionGranted) { 
			// return the AskForPermissionsConsent card here
	...

If the skill permissions are present, but geolocation data is not available in the request, then your skill should re-prompt the user.

Detect if location sharing is off on the mobile device

If Case 1 and Case 2 do not apply, consider Case 3, where your skill is having trouble obtaining device location despite no permissions issues with Alexa or your skill. In this case, check whether the customer's device has location sharing turned on, or if there are some other technical issues. For example, the customer might be driving inside a tunnel, leading to loss of GPS reception.

To check whether the device has location services turned on, inspect the locationServices object inside context.Geolocation. The purpose of this object, if it exists, is to tell you whether the device is sharing location or not. However, note that the locationServices object may not be available if the customer device did not provide it.

If context.Geolocation.locationServices.access is "ENABLED" and context.Geolocation.locationServices.status is "RUNNING", then the device is sharing location. Otherwise, the device is not set up to share location.

If location sharing is turned on, but your skill does not receive device location, you should let the customer know about that, with a message like "FindMyWayHome is having trouble accessing your location. Please wait a moment, and try again later."

If location sharing is turned off, however, your skill can request the user to turn on location sharing on his or her device, with a message like "FindMyWayHome is having trouble accessing your location. Please go to your device's settings to turn on location sharing, and try again."


Last updated: Oct 15, 2021