Skill Package API Reference
You can use the Skill Package API to interact with your skill as a single package, rather than by component.
- Skill package
- Use
eTag
to avoid overwriting a skill package - API endpoint and authorization
- Create a new upload URL
- Create a new skill package
- Import a package for an existing skill
- Get the status for a specified importId
- Create an export request for an existing skill
- Get the status for an export request
Skill package
A skill package consists of at least one component:
- Manifest – The skill manifest contains metadata about the skill and configuration, including the display name, skill capabilities (video, smart home, custom), and endpoint for the skill service code (whether AWS Lambda or a separate web endpoint). The name of the skill manifest file is skill.json. Every skill must have a manifest.
The following components of a skill package are optional:
- Image assets – These images are associated with your skill, appearing as icons in the Alexa Skills Store, or your in-skill products.
- In-skill products – These define the in-skill products that users can purchase in your skill. They specify the type of purchase and other details such as pricing.
- Interaction models – These define the voice user interface for your skill which includes the invocation name, intents, slots, and so forth. Only custom skills include interaction models, with one model for each locale that the skill supports. The name of the interaction model is <locale>.json, for example en-US.json. In the skill package format, the interaction models must be in a folder named custom, which itself must be in a folder named interactionModels.
Your skill might also contain account linking information, which is currently not supported by the Skill Package API. You can still use the Skill Package API, but you will also have to use SMAPI to manage account linking.
If you interact with your skill only through the Alexa Skills Kit developer console, these components still exist behind the scenes. If you interact with your skill through the Alexa Skills Kit Command Line Interface (ASK CLI) or the Skill Management API (SMAPI), you see these components as individual files. A skill package combines these components into a single file so that you can work with them as a unit.
Skill package format
A skill package file combines all of the skill components into a zipped file with a .zip extension. The skill package components are organized in the following way:
SkillPackageName.zip
├── assets
│ └── images
│ ├── en-US_largeIcon.png
│ ├── en-US_smallIcon.png
│ ├── isp1
│ │ ├── en-US_largeIcon.png
│ │ └── en-US_smallIcon.png
│ └── isp2
│ ├── en-US_largeIcon.png
│ └── en-US_smallIcon.png
├── interactionModels
│ └── custom
│ └── en-US.json
├── isps
│ ├── isps.json
│ ├── isp1.json
│ └── exampleDirectory
│ └── isp2.json
└── skill.json
To create and import a skill using the skill package format:
- Organize your skill components as shown in the preceding diagram, then zip the top-level folder.
Note: You can optionally skip the following two steps by uploading your skill package to a publicly-accessible URL on the internet.
- Create an upload URL.
- Use the URL that you created in the previous step to upload the .zip file to Amazon S3.
- After you upload the skill package, either to S3 or your own URL, you can:
You can also update an existing skill by exporting it in the skill package format, editing it locally, then using the preceding steps to upload and import it.
Manage in-skill products in a skill package
You can manage in-skill products (ISPs) by including them in your skill package. When you include ISPs in a skill package, you must include a folder named isps which contains a file named isps.json, as shown in the preceding section. This file contains information about ISPs to create or update, and ISPs that are associated (linked) with the skill, as shown in the following example.
{
"isps": {
"Unique ISP Name 1": {
"path": "file://isps/isp1.json"
},
"Unique ISP Name 2": {
"path": "file://isps/exampleDirectory/isp2.json"
}
},
"associations": [
"amzn1.adg.UUID3",
"amzn1.adg.UUID4"
]
}
The following list describes each object in the isps.json file:
isps
- Contains one or more ISPs, each with a unique name that you create. Each ISP contains a
path
that specifies the location of the ISP schema file relative to the skill.json file (you can consider skill.json the package root). You can organize the ISP files in whatever directory structure you want, using each ISP'spath
value to specify the organization. -
Note: The unique name for each ISP can contain only alphanumeric characters (
a-z
,A-Z
,0-9
) and underscores (_
). -
Warning: After you create an ISP's unique name, you should not change the name in the isps.json file. If you do, the Skill Package API creates a new ISP with the new name, leaving the old ISP in place.
associations
- Contains a list of product IDs, which are unique identifiers for an ISP. Each product ID in the list represents an ISP that is associated (linked) with your skill. To get the product ID for an ISP, use the In-Skill Product Management API or the developer console.
When you include ISPs in a skill package that you import into an existing skill, the existence of isps
and associations
in isps.json determines what the Skill Package API does:
- When isps.json contains
isps
orassociations
that are new, the Skill Package API creates or associates the ISPs accordingly. - When isps.json contains updates to
isps
that previously existed in the skill package, the Skill Package API updates them accordingly. - When isps.json omits
associations
that previously existed in the skill package, the Skill Package API disassociates them accordingly. The Skill Package API does not delete ISPs.
If you don't want the Skill Package API to take these actions, you can omit the isps folder from the skill package, and continue to manage ISPs separately.
For more information about ISPs, see In-Skill Purchasing Overview and In-Skill Purchasing Schemas.
Use eTag
to avoid overwriting a skill package
When you use the Skill Package API to import a skill package to an existing skill, the imported skill package overwrites the existing skill's components. In some cases, you might want to avoid overwriting an existing skill. For example, consider the following scenario in which a graphic designer and a developer work on the same skill simultaneously:
- The graphic designer and the developer each use the Skill Package API to export separate copies of the skill to their own laptops.
- The graphic designer adds new images to the skill package, then uses the Skill Package API to upload and import the skill package to the existing skill.
- The developer updates the skill's interaction model and adds a new ISP, then uses the Skill Package API to upload and import the skill package to the existing skill. This import overwrites the changes that the graphic designer made, because the developer did not have these changes in his or her local copy of the skill package.
To avoid this scenario, you can use the skill package's eTag
. You can think of an eTag
as an opaque version identifier for a skill package. You get an eTag
in the body of the response when you:
You can include an eTag
value in the If-Match
HTTP request header when you import a package for an existing skill.
Consider the preceding scenario with the use of eTags:
- The graphic designer and the developer each use the Skill Package API to export separate copies of the skill to their own laptops. They each save the
eTag
value in addition to the skill package .zip file. - The graphic designer adds new images to the skill package, then uses the Skill Package API to upload and import the skill package to the existing skill. The graphic designer's import request includes the
If-Match
HTTP header with theeTag
value, which matches the server-sideeTag
value for the skill package. The import succeeds, which results in a neweTag
value for this latest version of the skill package. - The developer updates the skill's interaction model and adds a new ISP, then uses the Skill Package API to upload and import the skill package to the existing skill. The developer's import request includes the
If-Match
HTTP header with theeTag
value, which does not match the server-sideeTag
value for the skill package, so the import request fails. - The developer exports the skill package to obtain the latest version and the corresponding
eTag
value. This version includes the previous updates that the graphic designer made. - The developer compares his or her local changes to the latest version, and reconciles the differences.
- The developer uses the Skill Package API to upload and import the skill package to the existing skill. The developer's import request includes the
If-Match
HTTP header with theeTag
value, which now matches the server-sideeTag
value for the skill package, so the import request succeeds.
API endpoint and authorization
The API endpoint is https://api.amazonalexa.com
. Each API request must have an Authorization
header whose value is the access token retrieved from Login with Amazon.
Create a new upload URL
Use this API to create a presigned upload URL that you can use to upload a skill package to Amazon S3. To upload a skill package to S3, you can:
- Send an HTTP
PUT
request to the presigned URL that you receive in the response to this API. - Use an AWS SDK. For more information, see Uploading Objects Using Presigned URLs in the Amazon S3 documentation.
You can also bypass this API entirely by uploading your skill package to a publicly-accessible URL on the internet.
After you upload the skill package, either to S3 or your own URL, you can:
- Create a new skill from the uploaded skill package.
- Import the uploaded skill package to an existing skill.
Request
POST /v1/skills/uploads
Response
201 Created
The response body includes the uploadUrl
value and the expiry date, as shown in the following sample.
{
"uploadUrl": "string",
"expiresAt": "2018-10-11T19:28:34.525Z"
}
Errors
Code | Description |
---|---|
401 | The authorization token is invalid, expired, or doesn't have access to the resource. |
429 | Exceeds the permitted request limit. |
500 | Internal Server Error. |
503 | Service Unavailable. |
Create a new skill package
Use this API to submit a request to create a new skill package.
Request
POST /v1/skills/imports
The request body takes the following form:
{
"vendorId": "string",
"location": "string"
}
Response
202 Accepted
The value of the Location
header is a relative URL that should be used to track the status of the import request.
Errors
Code | Description |
---|---|
400 | Server cannot process the request due to a client error. |
401 | The authorization token is invalid, expired, or doesn't have access to the resource. |
413 | Payload Too Large. |
429 | Exceeds the permitted request limit. |
500 | Internal Server Error. |
503 | Service Unavailable. |
Import a package for an existing skill
This API submits a request to import a zipped package file for an existing skill specified by skillId
.
Request
POST /v1/skills/{skillId}/imports
To avoid overwriting a previous update to the skill, you can optionally include the If-Match
HTTP header with an eTag
value. For more information, see Use eTag
to avoid overwriting a skill package.
The request body takes the following form, with the location
value being the presigned URL that you have previously obtained, or a public URL from which the zipped skill package can be downloaded. For more information, see Create upload URL.
{
"location": "string"
}
Response
202 Accepted
The value of the Location
header is the URL that you specified in the request.
Errors
Code | Description |
---|---|
400 | Server cannot process the request due to a client error. |
401 | The authorization token is invalid, expired, or doesn't have access to the resource. |
409 | Conflict. |
413 | Payload Too Large. |
429 | Exceeds the permitted request limit. |
500 | Internal Server Error. |
503 | Service Unavailable. |
Get the status for a specified importId
Obtains the importStatus
for the specified importId
.
Request
GET /v1/skills/imports/{importId}
Response
200 OK
The status
is one of:
FAILED
IN_PROGRESS
SUCCEEDED
The skill.resources
object's status
is one of:
FAILED
IN_PROGRESS
ROLLBACK_FAILED
ROLLBACK_IN_PROGRESS
ROLLBACK_SUCCEEDED
SKIPPED
SUCCEEDED
The skill.resources
object's action
is one of:
ASSOCIATE
CREATE
UPDATE
DISASSOCIATE
Response body
{
"status": "enum",
"errors": [
{
"code": "string",
"message": "string"
}
],
"warnings": [
{
"code": "string",
"message": "string"
}
],
"skill": {
"skillId": "string",
"eTag": "string",
"resources": [
{
"name": "string",
"status": "enum",
"action": "enum",
"errors": [
{
"code": "string",
"message": "string"
}
],
"info": [
{
"message": "string"
}
],
"warnings": [
{
"code": "string",
"message": "string"
}
]
}
]
}
}
Errors
Code | Description |
---|---|
401 | The authorization token is invalid, expired, or doesn't have access to the resource. |
404 | The resource being requested is not found. |
429 | Exceeds the permitted request limit. |
500 | Internal Server Error. |
503 | Service Unavailable. |
Create an export request for an existing skill
Creates an export request for an existing skill. You can then get the status of the export request, including a URL to download the exported skill.
Request
The stage
value must be either live
(for a live, published skill) or development
(for a skill in the development stage).
POST /v1/skills/{skillId}/stages/{stage}/exports
If your skill has been hidden or removed, after previously being published, the stage
value is still live
. For more information, see Hide or remove a skill. You can re-submit a hidden or removed skill for re-certification.
Response
202 Accepted
The response has no body. To get the status of the export request, including a URL to download the exported skill, send a GET
request to the path in the response's Location
header. For more information, see Get the status for an export request.
Errors
Code | Description |
---|---|
401 | The authorization token is invalid, expired, or doesn't have access to the resource. |
404 | The resource being requested is not found. |
409 | The request could not be completed due to a conflict with the current state of the target resource. |
429 | Exceeds the permitted request limit. |
500 | Internal Server Error. |
503 | Service Unavailable. |
Get the status for an export request
Gets the status of an export request that you created previously. When the status of the export request is SUCCEEDED
, the response contains a URL to download a zip archive of the exported skill.
Request
Send a GET
request to the path contained in the Location
header of the response to a previous export request. The exportId
is provided in this path, so you don't need to do anything extra to obtain it.
GET /v1/skills/exports/{exportId}
Response
200 OK
The body of the response contains one of these statuses: FAILED
, IN_PROGRESS
, or SUCCEEDED
. When the status is SUCCEEDED
, the skill.location
value contains a URL that you can use to download a zip archive of the exported skill.
Example response body
{
"skill": {
"expiresAt": "1550521786056",
"location": "URL to download the exported skill",
"eTag": "string"
},
"status": "SUCCEEDED"
}
Errors
Code | Description |
---|---|
401 | The authorization token is invalid, expired, or doesn't have access to the resource. |
404 | The resource being requested is not found. |
429 | Exceeds the permitted request limit. |
500 | Internal Server Error. |
503 | Service Unavailable. |