Skill Messaging API Reference
The Skill Messaging API is used to send message requests to skills. For more information, see Skill Events in Alexa Skills, List Events in Alexa Skills and Configure an Application or Service to Send Messages to Your Skill.
- North American (NA) and European (EU) POST commands
- Skill Messaging API usage
- Receive Messages in Your Skill
North American (NA) and European (EU) POST commands
The final POST command, constructed from the apiEndpoint
value, takes the form shown, with the first being the US endpoint, and the second being the EU endpoint.
POST api.amazonalexa.com/v1/skillmessages/users/{userId}
POST api.eu.amazonalexa.com/v1/skillmessages/users/{userId}
For a skill that consumes skill events, the endpoint to use is based on the apiEndpoint
value sent in the events for this user.
Skill Messaging API usage
Use the Skill Messaging API to send a message request to a skill for a specified user.
The Skill Messaging API is asynchronous. A successful response denotes that
the message has been accepted, and will be enqueued to be sent to
the skill. The skill endpoint must be available for an accepted
message to be successfully delivered to the skill. If the skill endpoint
is unavailable, the message will be retried periodically for as long as
the expiresAfterSeconds
field allows (or a default expiry if not provided). A
successful delivery requires the skill to acknowledge the message by
succeeding the context.
If the skill is online, the message will be delivered as it is processed. There is no guaranteed timing or ordering of the delivery of messages. Since the caller also owns the skill being messaged, the caller is responsible for determining whether a message has been delivered to the skill. There is no receipt or confirmation of the delivery mechanism. The caller is also responsible for handling duplicate messages in the skill in case multiple requests are sent.
Obtain the skill messaging token
To retrieve the skill messaging token required to send a message request, you need the ClientId
and ClientSecret
for your skill. You can find this information in the developer console.
-
Open the skills list in the developer console, and click Edit for your skill.
-
On the Build tab, click the Permissions section on the bottom left.
-
Scroll to the Alexa Skill Messaging section at the bottom of the Permissions page.
Note: If you do not see the Alexa Skill Messaging section, then toggle a permission on the page. The Alexa Skill Messaging section then appears. Once you have copied Client Id and Client Secret values, you can then change the permission back if you want. -
Copy the Client Id and Client Secret values for later use.
Alternatively, you can get the credentials by using one of these methods:
- Use the ASK CLI get-skill-credentials smapi subcommand.
- Use the ASK CLI generate-credentials-for-alexa-hosted-skill smapi subcommand.
- Use the ASK CLI v1 get-skill-credentials subcommand.
- Use the Skill Credential API to access the
ClientId
andClientSecret
values.
Now that you have obtained your skill's Client Id and Client Secret values, use the following cURL
command to retrieve a skill messaging token.
SKILL_CLIENT_ID='YOUR_SKILL_CLIENT_ID'
SKILL_CLIENT_SECRET='YOUR_SKILL_CLIENT_SECRET'
API_URL='https://api.amazon.com/auth/O2/token'
curl -k -X POST \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&scope=alexa:skill_messaging&client_id=$SKILL_CLIENT_ID&client_secret=$SKILL_CLIENT_SECRET" \
$API_URL
The response from this cURL
command provides you with an access_token
that begins with Atc|
. This is your skillMessagingToken
for the message request in the following section.
Sample cURL message request for the Skill Messaging API
ALEXA_USER_ID='ReplaceWithUserId'
SKILL_MESSAGING_TOKEN='ReplaceWithToken'
MESSAGE='{"data":{ "sampleMessage": "Sample Message"}, "expiresAfterSeconds": 60}'
API_URL=https://api.amazonalexa.com/v1/skillmessages/users/$ALEXA_USER_ID
curl -v -s -k -X POST \
-H "Authorization: Bearer $SKILL_MESSAGING_TOKEN" \
-H "Content-Type: application/json" \
-d "$MESSAGE" \
$API_URL
Parameters for the Skill Messaging API
Name | Location | Type | Required? | Description |
---|---|---|---|---|
userId |
path | string | Required | The ID of the skill user. This ID is the same as the userId provided in requests sent by Alexa. It must correspond to a valid user for the specified skill. |
skillMessagingToken |
head | string | Required | The token provided from the authorization API. This is a Bearer type token. For example:
Authorization: Bearer Atc|zzzzbbbccc
|
message |
body | object | Required |
The message you want to send to the skill, in the following format:
|
Message object
Parameter | Type | Description |
---|---|---|
data | JSON | Required. The payload data to send with the message. The data must be in the form of JSON-formatted key-value pairs.
Both keys and values must be of type String. The total size of the data cannot be greater than 6KB. For calculation purposes,
this includes keys and values, the quotes that surround them, the ":" character that separates them, the commas that
separate the pairs, and the opening and closing braces around the field. However, any whitespace between key/value pairs is
not included in the calculation of the payload size.
If the message does not include payload data, as in the case of a sync message, you can pass in an empty object, such as
"data":{}
|
expiresAfterSeconds |
integer | Optional. The number of seconds that the message will be retained to retry if message delivery is not successful. Allowed values are from 60 (1 minute) to 86400 (1 day), inclusive. The default is 3600 (1 hour). Multiple retries may occur during this interval.
The retry logic is exponential. The first retry executes after 30 seconds, and this time period doubles on every retry. The retries will end when the total time elapsed since the message was first sent has exceeded the value you provided for expiresAfterSeconds .
Message expiry is rarely a problem if the message handler has been set up correctly. With a correct setup, you will receive the message once promptly. This mechanism for retries is provided as a safeguard in case your skill goes down during a message delivery. |
Response (to a request to the Skill Messaging API)
Code | Description | Headers |
---|---|---|
202 | Message has been successfully accepted, and will be sent to the skill. | X-Amzn-RequestID |
X-Amzn-RequestID object
Name | Type | Description |
---|---|---|
X-Amzn-RequestID | string | A value created that uniquely identifies the request. If you have problems, Amazon can use this value to troubleshoot the problem. |
Error codes
Code | Error | Description |
---|---|---|
400 | Bad request | Data is missing or not valid. |
403 | Forbidden request | The skillmessagingToken is expired or not valid. |
404 | Not found. | The userId does not exist. |
429 | Message rate exceeded. | The requester has exceeded their maximum allowable rate of messages. |
500 | Internal service exception |
Receive Messages in Your Skill
After you enable your skill for permissions and configure the
corresponding application for your skill, make sure that the service for
your skill (AWS Lambda or web service) knows how to handle a message it
receives. Messaging.MessageReceived
is a request type similar to other
requests that skills receive. For details on the standard request
format, see Request Format.
Skill service must send acknowledgments to the Skill Messaging API
For an out-of-session message, the service for your skill (AWS Lambda or web service) must send an acknowledgement to the Skill Messaging API that it received the message. Otherwise, the API continues to send the message until it expires.
If using Node.js, send the acknowledgement by calling
context.succeed();
after you handle the message. If using another language, send an empty success message as an acknowledgment.
When you are making other API calls upon receiving messages, it is important to succeed the context after those API requests synchronously return. For more information, see The Context Object (Node.js) in the AWS Lambda documentation.
Messaging.MessageReceived request type
The Messaging.MessageReceived
request type should be handled by the skill endpoint (whether that is AWS Lambda or web service). The request is a type of intent, so your skill will
require an additional handling method for this type of request.
See Request
Format.
Request | MessageRequest |
---|---|
Interface | Messaging |
Definition |
|
Attributes | message: A message blob provided by a third-party application back end. The message blob has a limit of 6 KB within our system. |
Consent token in permissions object in requests
The Messaging.MessageReceived
request example uses a consentToken
in the permissions
object. For out-of-session messaging requests, a consentToken
, which contains the user's consent, is provided to the skill, if the user has provided that consent.
See Context
Object.
A consent token is valid for 60 minutes, and should not be persisted. A consent token is refreshed automatically every time the Skill Messaging API receives a new in-session request or out-of-session request.
Each userId
lasts for the lifetime of the skill enablement for the skill user. If a user disables and re-enables a skill, the userId
will change. Thus, when this user next uses the skill, the user will be seen as a new user. As with a new user, the userId
must be noted in-session so that it can be used to send a message out-of-session. If the Skill Messaging API is used to call the skill messaging endpoint (/skillmessages/users/{userId}
), and a 404 error (userId not found) occurs, then the userId
is no longer valid in the system.
Include Permissions field in each Messaging.MessageReceived
request
If you have Permissions enabled in the developer console, the permissions
field is included in each Messaging.MessageReceived
request. If the user has not consented to permissions, this field will not include a nested consentToken
field. However, if the skill requires a consent token, the skill must prompt the user to accept permissions by throwing a permissions card, as discussed in New Permissions Card for Requesting Customer Consent.
The permissions
field is shown in the Messaging.MessageReceived
request example.
Example Messaging.MessageReceived request
The IDs have been altered and truncated in this example.
{
"version": "1.0",
"context": {
"System": {
"application": {
"applicationId": "amzn1.echo-sdk-ams.app.b4277435"
},
"user": {
"userId": "amzn1.ask.account.AGQ3PQ",
"permissions": {
"consentToken": "ZZZZZZZ..."
}
},
"apiAccessToken": "AxThk...",
"request": {
"type": "Messaging.MessageReceived",
"requestId": "amzn1.echo-api.request.0000000-0000-0000-0000-00000000000",
"timestamp": "2015-05-13T12:34:56Z",
"message": {
"notice": "<< text of message >>"
}
}
}
}
}
apiEndpoint value in context object in requests
The IntentRequest
request example uses an apiEndpoint
value in the System
object. The value varies depending on the location of the user. See Context
Object.
North American (NA) user | European (EU) user |
---|---|
https://api.amazonalexa.com | https://api.eu.amazonalexa.com |
Example IntentRequest with permission support
{
"version": "1.0",
"session": {
"new": false,
"sessionId": "amzn1.echo-api.session.0000000-0000-0000-0000-00000000000",
"application": {
"applicationId": "amzn1.echo-sdk-ams.app.000000-d0ed-0000-ad00-000000d00ebe"
},
"attributes": {
"supportedHoroscopePeriods": {
"daily": true,
"weekly": false,
"monthly": false
}
},
"user": {
"userId": "amzn1.account.AM3B00000000000000000000000"
}
},
"context": {
"System": {
"application": {
"applicationId": "amzn1.echo-sdk-ams.app.000000-d0ed-0000-ad00-000000d00ebe"
},
"user": {
"userId": "amzn1.account.AM3B00000000000000000000000"
},
"apiAccessToken": "AxThk...",
"apiEndpoint": "https://api.amazonalexa.com"
}
},
"request": {
"type": "IntentRequest",
"requestId": " amzn1.echo-api.request.0000000-0000-0000-0000-00000000000",
"timestamp": "2015-05-13T12:34:56Z",
"intent": {
"name": "GetZodiacHoroscopeIntent",
"slots": {
"ZodiacSign": {
"name": "ZodiacSign",
"value": "virgo"
}
}
}
}
}
Permissions Card to request customer consent
The apiAccessToken
is included on all requests to your skill, regardless of whether the user granted your skill the permissions needed to fulfill the request. Therefore, the token may not contain the right set of permissions for your skill to fulfill the request. Your skill can display a special permissions card to ask customers for consent dynamically.
New Card | AskForPermissionsConsentCard |
---|---|
Interface | CardRenderer |
Definition |
|
Attributes | permissions : this contains a list of scope strings that maps to Alexa permissions. Include only those Alexa permissions that are both needed by your skill and that are declared in your skill metadata on the Amazon Developer Portal. |
Because apiAccessToken
is included in all skill requests, you cannot use the presence of apiAccessToken
to determine whether or not you have the needed permissions. Instead, call the API and check the response code. A 403 Forbidden
response indicates that your skill does not have the permissions, so at that point you can include the AskForPermissionsConsent
card in your response to Alexa.
Sample response with permissions card
An in-session interaction can return a response that includes the new
AskForPermissionsConsent
card. Here is a typical response for a card with a request for write permissions.
{
"version": "1.0",
"response": {
"card": {
"type": "AskForPermissionsConsent",
"permissions": [
"write::alexa:household:list"
]
}
}
}
The permissions
value will always match the scope that you declared for the skill on the Build > Permissions page in the developer console.