Data Store REST API Reference


The Data Store REST API provides operations to update the data store on a device. Use this API to push updates to the data store from requests sent to your skill and from outside of a skill session. The data store is an area installed locally to a device that contains data an Alexa Presentation Language (APL) document can access with data binding. Widgets use the data store to display content without sending requests to your skill and waiting on a response.

The API can update the data store for a list of specific devices or for a specific user.

For details about widgets, see About Widgets and Alexa Presentation Language (APL).

API endpoint

Use one of the following endpoints, based on the region for your skill:

  • North America: https://api.amazonalexa.com
  • Europe: https://api.eu.amazonalexa.com
  • Far East: https://api.fe.amazonalexa.com

You call the API with a POST request.

Authentication

You must authenticate your skill with Alexa and retrieve an access token to call the Data Store API. Pass the access token to the API call in the header.

To authenticate your skill and retrieve the access token, complete the following steps:

  1. Obtain the client ID and client secret credentials for your skill.
  2. Use the credentials to call the token endpoint and retrieve an access token.

Obtain the client ID and client secret values

You can use the Alexa Skills Kit (ASK) Command Line Interface (CLI) or the developer console to retrieve these values for your skill.

To get the credentials with the ASK CLI

To get the credentials in the developer console

  1. Sign in to the Alexa developer console, and then open the skill.
  2. In the sidebar, select Tools > Permissions.
  3. Scroll to the bottom of the page, and then copy the value from the Alexa Client ID field.
  4. Click SHOW, and then copy the value from the Alexa Client Secret field.

Use the credentials to retrieve an access token

To get the access token, make a POST call to https://api.amazon.com/auth/o2/token. Access tokens expire. Therefore, your code that calls the Data Store API must retrieve a new token if the previous one has already expired.

To get the access token

  1. Make a POST call to https://api.amazon.com/auth/o2/token.
  2. Set the body of the request to the following syntax, replacing {SkillClientId} and {SkillClientSecret} with the client ID and client secret for your skill.

     grant_type=client_credentials&client_id={SkillClientId}&client_secret={SkillClientSecret}&scope=alexa::datastore
    

    The token endpoint returns a JSON object with the field access_token.

  3. Pass the access_token value to the Authorization header in your calls to the Data Store API.

The following example shows a curl command that retrieves the access token.

curl --location --request POST 'https://api.amazon.com/auth/o2/token' \
--header 'Content-Type: application/x-www-form-urlencoded;charset=UTF-8' \
--data-raw 'grant_type=client_credentials&client_id={SkillClientId}&client_secret={SkillClientSecret}&scope=alexa::datastore'

The following example shows a response from the token endpoint. In this example, the token expires in 3600 seconds, which is one hour.

{
  "access_token": "<access-token-string>",
  "scope": "alexa::datastore",
  "token_type": "bearer",
  "expires_in": 3600
}

Operations

The Data Store API includes the following operations.

Operation HTTP method and URI

Commands

POST /v1/datastore/commands

Queued result query

GET /v1/datastore/queue/<queuedResultId>?maxResults={INTEGER}&nextToken={STRING}

Cancel

POST /v1/datastore/queue/<queuedResultId>/cancel

Commands

Runs the provided set of commands to update the data store for a specified list of devices or users. For details about the commands you can run, see Data store commands, later.

Request

To run the set of commands to update the data store, you make a POST request.

Request path and header example

POST /v1/datastore/commands
Content-Type: application/json
Authorization: Bearer {access_token} 

Request path and header parameters

Parameter Located in Description Type Required

access_token

Header

Access token for your skill. Use your client credentials and the token endpoint to obtain the access token. For details, see Authentication.

String

Yes

Request body example

Copied to clipboard.

{
  "commands": [
    {
      "type": "PUT_OBJECT",
      "namespace": "NamespaceMainPage",
      "key": "keyMainPage",
      "content": {
        "mainPageContent": {
          "lastUpdated": "Sent this update on April 17, 2023."
        }
      }
    }
  ],
  "target": {
    "type": "DEVICES",
    "items": [
      "amzn1.ask.device.1",
      "amzn1.ask.device.2"
    ]
  },
  "attemptDeliveryUntil": "{ISO-8601 Date/time}"
}

Request body properties

Property Description Type Required

commands

Commands to run to update the data store. For details about the format of the commands, see Data store commands.

Array of data store commands

Yes

target

An object that identifies the target for the commands. This object can represent a list of device IDs or a user ID. For details, see Command target.

Target object

Yes

target.type

Type of target for the commands. Allowed values: DEVICES or USER.

Enumeration

Yes

target.items

Applies when type is DEVICES. Contains a list of device IDs representing the devices to update. You can provide up to 20 device IDs in this array. The API runs the commands on each specified device.

Array of strings

Yes when type is DEVICES

target.id

Applies when type is USER. Contains a single user ID. The API runs the commands on each device associated with the user.

String

Yes when type is USER.

attemptDeliveryUntil

When provided, Alexa makes additional attempts to deliver the commands if a device is unreachable on the first attempt. Maximum value is 48 hours after sending the request. Inspect the dispatchResults in the response body to determine whether any devices in the request were unreachable.

When not provided, Alexa doesn't attempt to redeliver the commands to unreachable devices.

Timestamp in ISO-8601 format

No

Command target

The Commands operation requires a target object that specifies either a list of device ID values or a single user ID. The following list shows the criteria to publish your updates to devices.

  • To publish your updates to a device or a group of devices, set the target type to DEVICES and provide an array of up to 20 device IDs in the items property. The commands you provide run on each specified device.
  • To publish your updates to the devices associated with a specific user, set the target type to USER and provide a single user ID in the item property. The commands you provide run on each device associated with that user. The operation skips any devices that don't support the data store.

Every request sent to your skill includes properties for deviceId and userId in the context.System.user.userId and context.System.device.deviceId properties. Retrieve these values from the UsagesInstalled request that your skill receives when a user chooses to install your widget and save them in persistent storage to use with the Data Store REST API. These values are unique to your skill. You can't use the deviceId or userId from one skill with a different skill.

For details about the user and device IDs in the skill request, see the System object.

Response

A successful response returns HTTP 200 OK, and an object that provides the results for each device. On error, the response returns an HTTP status code that includes a response body with an error code and message.

Response body example

The following example shows the response body for a commands operation that attempted to update two devices. In this example, Alexa updated the first device, but failed to update the second device because it wasn't available.

{
  "results": [
    {
      "deviceId": "amzn1.ask.device.1",
      "type": "SUCCESS"
    },
    {
      "deviceId": "amzn1.ask.device.2",
      "type": "DEVICE_UNAVAILABLE",
      "message": "AOGS: Send directive failure: Device unreachable"
    }
  ],
  "queuedResultId": "<id-for-this-result>"
}

Response body properties

Property Description Type

results

Array of dispatch result objects containing the results of the call for each target user or device. Each object in this array indicates whether the operation was successful for the device.

The items in the results array depend on the type of target in the request.

  • DEVICES: the number and order of items in the results array is the same as the order of the device IDs in the target.items array.
  • USER: the number and order of items in the results array depends on the number of devices associated with the specified user and therefore can vary.

Array

results[].deviceId

The ID of a device that Alexa attempted to update.

String

results[].type

Value that indicates the result of the attempt to update the device.
Possible values:

  • SUCCESS – The target device received the payload.
  • INVALID_DEVICE – The target device isn't capable of processing the payload. For example, the target device doesn't support the data store.
  • DEVICE_UNAVAILABLE – The dispatch failed because the device is offline. When the commands operation sets the attemptDeliveryUntil property, Alexa attempts to redeliver the commands when the device is back online. You can use the query operation to get the status of this attempted delivery.
  • DEVICE_PERMANENTLY_UNAVAILABLE – The dispatch failed because the device is no longer available. For example, this error occurs when the target device is no longer registered.
  • CONCURRENCY_ERROR – There were multiple, concurrent attempts to update the same data store region. You can use the query operation to get the status of the attempted delivery before you attempt to send a new commands request.
  • INTERNAL_ERROR – The dispatch failed because of an unknown error.
  • PENDING_REQUEST_COUNT_EXCEEDS_LIMIT – The count of pending requests exceeds the limit.

Enumeration

results[].message

Message that describes the error.

String

queuedResultId

Applies when at least one device was offline (DEVICE_UNAVAILABLE). Use this identifier with the query operation to determine the status of the attempts to redeliver the commands. The result is available for query until at least one hour after the attemptDeliveryUntil time specified in the request..

Not provided when no devices in the request were offline.

String

HTTP status codes

If the API returns any status other than 200, this means that the process stopped before Alexa attempted to update the devices.

Status Description

200 OK

The Data Store API parsed and validated the request and attempted to deliver the payload to the provided targets. Results for each device are available as part of the response body in the results array. This response doesn't mean that every device received the commands payload. Inspect the response body to determine the results for each device. For details about the results array, see Response body properties.

400 Invalid Request

The request validation failed. Possible errors:

  • COMMANDS_PAYLOAD_EXCEEDS_LIMIT – The total size of commands can't exceed 16Kb in UTF-encoding.
  • NO_TARGET_DEFINED – No target device is defined. Applies when target.type is DEVICES.
  • TOO_MANY_TARGETS – Number of targets in the request exceeds the limits of 20 devices values or one user ID.
  • INVALID_REQUEST – Request payload doesn't comply with the JSON schema, or a command violates a field restriction.

401 Unauthorized

INVALID_ACCESS_TOKEN – Access token is expired or invalid.

403 Forbidden

DATA_STORE_SUPPORT_REQUIRED – The skill isn't configured with support for the Alexa.DataStore interface. Update your skill to support the required interfaces. For details, see Enable the interfaces for widgets

429 Too many requests

TOO_MANY_REQUESTS – The request was throttled because the skill exceeded the maximum allowed transactions per second.

500

DATASTORE_UNAVAILABLE – An unexpected internal service error occurred.

Queued result query

Query the status of command deliveries to offline devices.

Request

To get the status of deliveries to offline devices, you make a GET request.

Request path and header example

GET /v1/datastore/queue/<queuedResultId>?maxResults={INTEGER}&nextToken={STRING}
Content-Type: application/json
Authorization: Bearer {access_token} 

Request path and header parameters

Parameter Located in Description Type Required

access_token

Header

Access token for your skill. Use your client credentials and the token endpoint to obtain the access token. For details, see Authentication.

String

Yes

queuedResultId

Path

A unique identifier that identifies the request with offline devices. Retrieve this identifier from the dispatch results object returned from the commands operation.

String

Yes

maxResults

Query

Maximum number of dispatch result items to return in each page. Defaults to 20. Use the paginationContext.nextToken property in the response to page through the results when needed. Allowed values: integer between 1 and 100

Integer

No

nextToken

Query

The value of nextToken in the response to fetch next page. If not specified, the request fetches the first page of results.

String

No

Request body example

The request has no body

Request body properties

The request has no body

Response

A successful response returns HTTP 200 OK, and an object that provides an array of dispatch results that weren't delivered. On error, the response returns an HTTP status code that includes a response body with an error code and message.

Response body example

{
  "items": [
    {
        "deviceId": "amzn1.ask.device.2",
        "type": "DEVICE_UNAVAILABLE",
        "message": "AOGS: Send directive failure: Device unreachable"
    },
    {
        "deviceId": "amzn1.ask.device.3",
        "type": "DEVICE_UNAVAILABLE",
        "message": "AOGS: Send directive failure: Device unreachable"
    }
  ],  
  "paginationContext": {
     "totalCount": 227,
     "nextToken": "token-for-next-page",
     "previousToken": "token-for-previous-page"
   }
}

Response body properties

Property Description Type

items

Unordered array of dispatch result objects. Contains results from the earlier commands request in which the operation was unsuccessful. This means any results where the type wasn't SUCCESS.

Array

items[].deviceId

The ID of a device that Alexa was unable to update.

String

items[].type

Value that indicates the result of the attempt to update the device.
Possible values:

  • DEVICE_UNAVAILABLE – Alexa continues to attempt to deliver the commands to the device until the current time exceeds the attemptDeliveryUntil time.
  • DEVICE_PERMANENTLY_UNAVAILABLE – Delivery attempts to this device are stopped. Your skill should stop attempting to push updates to the device.
  • CONCURRENCY_ERROR – There were multiple, concurrent attempts to update the same data store region.

Enumeration

items[].message

Message that describes the error.

String

paginationContext

An object containing pagination details when the query returns many items. Use the properties of this object to paginate through the results.

Object

paginationContext.totalCount

The total number of results at the time of current response.

Integer

paginationContext.previousToken

The token for the previous page of results. Not provided when the request returns the initial page of results.

String

paginationContext.nextToken

The token for the next page of results. Not provided when the request returns the last page of results.

String

HTTP status codes

If the API returns any status other than 200, this means that the API call failed.

Status Description

200 OK

The call was successful. See the response body for the results provided in the items array. For details, see Response body properties.

400 Bad Request

The request validation failed. Possible errors:

  • INVALID_REQUEST – Request payload doesn't comply with the JSON schema, or a command violates a field restriction.

401 Unauthorized

INVALID_ACCESS_TOKEN – Access token is expired or invalid.

403 Forbidden

DATA_STORE_SUPPORT_REQUIRED – The skill isn't configured with support for the Alexa.DataStore interface. Update your skill to support the required interfaces. For details, see Enable the interfaces for widgets

429 Too many requests

TOO_MANY_REQUESTS – The request was throttled because the skill exceeded the maximum allowed transactions per second.

500

DATASTORE_UNAVAILABLE – An unexpected internal service error occurred.

Cancel

Cancels a pending request for a specified queued result.

Request

To get cancel a pending request, you make a POST request.

Request path and header example

POST /v1/datastore/queue/<queuedResultId>/cancel
Content-Type: application/json
Authorization: Bearer {access_token} 

Request path and header parameters

Parameter Located in Description Type Required

access_token

Header

Access token for your skill. Use your client credentials and the token endpoint to obtain the access token. For details, see Authentication.

String

Yes

queuedResultId

Path

A unique identifier that identifies the request with pending updates. Retrieve this identifier from the dispatch results object returned from the commands operation.

String

Yes

Request body example

The request has no body.

Request body properties

The request has no body.

Response

A successful response returns HTTP 204 No Content with no response body.

Response body example

The response has no body for a successful result.

Response body properties

The response has no body for a successful result.

HTTP status codes

If the API returns any status other than 204 No Content, this means that the API call failed. The body of the request contains an object with the type and message for the error.

Status Description

204 No Content

The call was successful and the pending request has been canceled.

400 Invalid Request

The request validation failed. Possible errors:

  • COMMANDS_DELIVERED – The pending commands have been delivered.
  • CONCURRENCY_ERROR – There are concurrent attempts to deliver the pending commands.

401 Unauthorized

INVALID_ACCESS_TOKEN – Access token is expired or invalid.

403 Forbidden

DATA_STORE_SUPPORT_REQUIRED – The skill isn't configured with support for the Alexa.DataStore interface. Update your skill to support the required interfaces. For details, see Enable the interfaces for widgets

404 Not Found

NOT_FOUND – Unable to find a pending request for the provided queuedResultId.

429 Too many requests

TOO_MANY_REQUESTS – The request was throttled because the skill exceeded the maximum allowed transactions per second.

500

DATASTORE_UNAVAILABLE – An unexpected internal service error occurred.

Data store commands

Use the Commands operation to run these commands.

Data store organization

The data store on a device is organized by region, namespace, and key. A region can contain multiple namespaces, and a namespace can contain multiple keys. Each key contains an object with the data.

Each data store command has properties to specify the namespace and key as needed. The REST API automatically determines the region for your skill based on the skill ID. Your skill can't access the data store for any other skills.

Data store limits

The data store imposes the following limitations:

  • A skill can store up to 1 MB of data on a device. This limit is per skill and is shared across all the widgets associated with the skill. Each item in the region, including the namespace and key names, contributes to storage consumed by the skill.
  • Your skill can't exceed 25 transactions per second (TPS) when it writes data to the data store.

PUT_NAMESPACE

Creates new namespace in the region with the provided namespace name. Ignored if the namespace already exists in the region.

Command properties

Property Type Required Description

type

String

Yes

Type of command to run. Set to PUT_NAMESPACE.

namespace

String

Yes

Identifier for the namespace to create. Must be unique within the region for your skill. The namespace must be a be a non-empty string that meets the follow requirements:

  • Fewer than 512 bytes
  • Doesn't begin with the string "sqlite_"
  • Doesn't match any SQLite reserved keywords
  • Doesn't start with an underscore (_)
  • Allowed character set: [_ - . a-z A-Z 0-9]

The namespace name contributes to the data store storage allocated to your skill. For details about limits, see Data store limits.

PUT_OBJECT

Adds the object provided in content to the specified key within the specified namespace. This command creates the namespace if the specified namespace doesn't exist in the region.

If the specified key contains an existing object, the PUT_OBJECT command overwrites the existing object.

If the specified key contains an existing array, the PUT_OBJECT command replaces the array in the data store with the array provided in the command. The command doesn't attempt to merge the two arrays.

Command properties

Property Type Required Description

type

String

Yes

Type of command to run. Set to PUT_OBJECT.

namespace

String

Yes

Unique identifier for the namespace to update with the provided content. Must be unique within the region for your skill. The namespace must be a be a non-empty string that meets the follow requirements:

  • Fewer than 512 bytes
  • Doesn't begin with the string "sqlite_"
  • Doesn't match any SQLite reserved keywords
  • Doesn't start with an underscore (_)
  • Allowed character set: [_ - . a-z A-Z 0-9]

The namespace name contributes to the data store storage allocated to your skill. For details about limits, see Data store limits.

key

String

Yes

Unique identifier for the object to update with the provided content. The key must be a non-empty string that meets the following requirements:

  • Fewer than 512 bytes
  • Doesn't start with an underscore (_)
  • Allowed character set: [_ - . a-z A-Z 0-9]

The key name contributes to the data store storage allocated to your skill. For details about limits, see Data store limits.

content

Object or Array

Yes

The content to add or update at the specified namespace and key. The PUT_OBJECT command doesn't inspect or validate this payload.

Make sure that the data you provide in this property matches the dataType defined for the specified namespace and key. For example, if you configured the data store extension to store an ARRAY at a specified namespace and key, then you must provide an ARRAY in the content property of the PUT_OBJECT command. For examples, see Example: update an object in the data store and Example: Update an array in the data store.

Example: update an object in the data store

The following example shows an APL document that configures the data store to store an object at the key called mainPage. The dataType is set to OBJECT. For details about the data store settings in a document, see APL Data Store Extension.

{
  "type": "APL",
  "version": "2023.3",
  "extensions": [
    {
      "uri": "alexaext:datastore:10",
      "name": "DataStore"
    }
  ],
  "settings": {
    "DataStore": {
      "dataBindings": [
        {
          "namespace": "objectDataStoreExample",
          "key": "mainPage",
          "dataBindingName": "dsMainPage",
          "dataType": "OBJECT"
        }
      ]
    }
  },
  "mainTemplate": {}
}

To update the object at the mainPage key, use the following PUT_OBJECT command. Note that the content property in the command must contain an object because the dataType of the data stored at this key is OBJECT. In this example, the new object for the mainPage key has four properties.

{
  "type": "PUT_OBJECT",
  "namespace": "objectDataStoreExample",
  "key": "mainPage",
  "content": {
    "headerTitle": "This is the header title from the data store",
    "primaryText": "This is the primaryText from the data store",
    "secondaryText": "Secondary text from the data store",
    "tertiaryText": "Tertiary text from the data store"
  }
}

Example: Update an array in the data store

The following example shows an APL document that configures the data store to store an array at the key called mainList. The dataType is set to ARRAY. For details about the data store settings in a document, see APL Data Store Extension.

{
  "type": "APL",
  "version": "2023.3",
  "extensions": [
    {
      "uri": "alexaext:datastore:10",
      "name": "DataStore"
    }
  ],
  "settings": {
    "DataStore": {
      "dataBindings": [
        {
          "namespace": "arrayDataStoreExample",
          "key": "mainList",
          "dataBindingName": "dsListItemsToShow",
          "dataType": "ARRAY"
        }
      ]
    }
  },
  "mainTemplate": {}
}

To update the array at the mainList key, use the following PUT_OBJECT command. Note that the content property in the command must contain an array because the dataType of the data stored at this key is ARRAY. In this example, the new array for the mainList key contains four items.

{
  "type": "PUT_OBJECT",
  "namespace": "arrayDataStoreExample",
  "key": "mainList",
  "content": [
    {
      "primaryText": "The first list item."
    },
    {
      "primaryText": "The second list item."
    },
    {
      "primaryText": "The third list item."
    },
    {
      "primaryText": "The fourth list item."
    }
  ]
}

REMOVE_NAMESPACE

Deletes the specified namespace from the region. Ignored if the provided namespace doesn't exist.

Command parameters

Property Type Required Description

type

String

Yes

Type of command to run. Set to REMOVE_NAMESPACE.

namespace

String

Yes

Identifier for the namespace to remove.

REMOVE_OBJECT

Deletes the object stored at the specified namespace and key. Ignored if the object doesn't exist.

Command properties

Property Type Required Description

type

String

Yes

Type of command to run. Set to REMOVE_OBJECT.

namespace

String

Yes

Unique identifier for the namespace that contains the object to remove.

key

String

Yes

Unique identifier for the object to remove.

CLEAR

Deletes the region for your skill. Ignored if your skill doesn't have a region on the device.

Deleting a region deletes all namespaces and objects stored within that region. Data stored in the region isn't recoverable. The next PUT_NAMESPACE or PUT_OBJECT command recreates the region with the data specified in those commands, but doesn't restore any of the deleted data.

Command properties

Property Type Required Description

type

String

Yes

Type of command to run. Set to CLEAR.


Was this page helpful?

Last updated: Nov 03, 2023