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 overview

A skill package must contain the following component:

  • Skill 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 (ISPs) – 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 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 the skill components into a zipped file with a .zip extension. The skill package has the following organization.

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 by using the skill package format, take the following steps.

To create and import a skill by using the skill package format

  1. Organize your skill components as shown in the preceding diagram, and then zip the top-level folder.
  2. Create an upload URL.
  3. Use the URL that you created in the previous step to upload the .zip file to Amazon S3.
  4. 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, and then using the preceding steps to upload and import it.

Use the skill package

The following sections contain information about how to avoid overwriting an existing skill, and how to manage in-skill products.

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. Sometimes, 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:

  1. The graphic designer and the developer each use the Skill Package API to export separate copies of the skill to their own laptops.
  2. The graphic designer adds new images to the skill package, and then uses the Skill Package API to upload and import the skill package to the existing skill.
  3. The developer updates the skill's interaction model, adds a new ISP, and 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 didn't have these changes in their 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 call the Skill Package API for one of the following operations:

You can include an eTag value in the If-Match HTTP request header when you import a package for an existing skill.

The following example shows how eTags prevent overwriting:

  1. 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.
  2. The graphic designer adds new images to the skill package, and 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 the eTag value, which matches the server-side eTag value for the skill package. The import succeeds, which results in a new eTag value for this latest version of the skill package.
  3. The developer updates the skill's interaction model, adds a new ISP, and 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 the eTag value, which does not match the server-side eTag value for the skill package, so the import request fails.
  4. 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.
  5. The developer compares their local changes to the latest version, and reconciles the differences.
  6. 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 the eTag value, which now matches the server-side eTag value for the skill package, so the import request succeeds.

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. The isps folder 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's path value to specify the organization.
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 or associations 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 details about ISPs, see In-Skill Purchasing Overview and In-Skill Purchasing Schemas.

API operations

The endpoint for the Skill Package API is https://api.amazonalexa.com. Each API request must have an Authorization header whose value is the access token retrieved from Login with Amazon. For details about how to get the access token, see Get an Access Token for SMAPI.

The following table lists the Skill Package API operations.

Description HTTP method and path

Create a new upload URL

POST /v1/skills/uploads

Create a new skill package

POST /v1/skills/imports

Import a package for an existing skill

POST /v1/skills/{skillId}/imports

Get the status for a specified import ID

GET /v1/skills/imports/{importId}

Create an export request for an existing skill

POST /v1/skills/{skillId}/stages/{stage}/exports

Get the status for an export request

GET /v1/skills/exports/{exportId}

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. You can upload a skill package to S3 by using one of the following methods:

  • Send an HTTP PUT request to the presigned URL that you receive in the response to this API.
  • Use an AWS SDK. For details, 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 do one of the following operations:

Request

POST /v1/skills/uploads

Response

A successful request returns 201 Created.

Response body structure
{
  "uploadUrl": "string",
  "expiresAt": "2018-10-11T19:28:34.525Z"
}
Response fields
Field Location Description Type

uploadUrl

Response body

A URL you can use to upload a skill package.

String

expiresAt

Response body

The expiration time of the URL.

String

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
Request body structure
{
  "vendorId": "string",
  "location": "string"
}
Request parameters
Field Location Description Type Required

vendorId

Request body

The ID of the vendor that owns the skill.

String

No

location

Request body

The URL for the skill package.

String

Yes

Response

A successful request returns 202 Accepted.

The value of the Location header is a relative URL that you use 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
Request body structure
{
  "location": "string"
}

To avoid overwriting a previous update to the skill, you can optionally include the If-Match HTTP header with an eTag value. For details, see Use eTag to avoid overwriting a skill package.

Request parameters
Field Location Description Type Required

skillId

Request path

The ID of the skill for which to import the skill package.

String

Yes

location

Request body

The presigned URL that you previously obtained, or a publicly accessible URL from which the zipped skill package can be downloaded. For details, see Create upload URL.

String

Yes

Response

A successful request returns 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

Gets the status for the specified importId.

Request

GET /v1/skills/imports/{importId}
Request parameters
Field Location Description Type Required

importId

Request path

The skill package import for which to get the status.

String

Yes

Response

A successful request returns 200 OK.

Response body structure
{
  "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"
          }
        ]
      }
    ]
  }
}
Response fields
Field Location Description Type

status

Response body

The status of the import. One of the following values:

  • FAILED
  • IN_PROGRESS
  • SUCCEEDED

Enum

errors

Response body

Errors related to the last modification request of the skill package.

Array

warnings

Response body

Warnings related to the last modification request of the skill package.

Array

skill.skillId

Response body

The ID of the skill.

String

skill.eTag

Response body

An opaque version identifier for the skill package. For details, see Use eTag to avoid overwriting a skill package.

String

skill.resources

Response body

List of skill resources.

The status is one of the following values:

  • FAILED
  • IN_PROGRESS
  • ROLLBACK_FAILED
  • ROLLBACK_IN_PROGRESS
  • ROLLBACK_SUCCEEDED
  • SKIPPED
  • SUCCEEDED

The action is one of the following values:

  • ASSOCIATE
  • CREATE
  • UPDATE
  • DISASSOCIATE

Array

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 that you can use to download the exported skill.

Request

POST /v1/skills/{skillId}/stages/{stage}/exports
Request parameters
Field Location Description Type Required

skillId

Request path

The ID of the skill for which to export the skill package.

String

Yes

stage

Request path

The stage value must be either live (for a live, published skill) or development (for a skill in the development stage).

If your skill is hidden or removed after previously being published, the stage value is still live. For details, see Hide or remove a skill. You can re-submit a hidden or removed skill for re-certification.

String

Yes

Response

A successful request returns 202 Accepted.

The response has no body. To get the status of the export request, including a URL that you can use to download the exported skill, send a GET request to the path in the response's Location header. For details, 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 that you can use to download a zip archive of the exported skill.

Send a GET request to the path contained in the Location header of the response to a previous export request. The exportId is in this path, so you don't need to do anything extra to obtain it.

Request

GET /v1/skills/exports/{exportId}
Request parameters
Field Location Description Type Required

exportId

Request path

The skill package export request for which you want to get the status.

String

Yes

Response

A successful request returns 200 OK.

Response body structure
{
  "skill": {
    "expiresAt": "1550521786056",
    "location": "URL to download the exported skill",
    "eTag": "string"
  },
  "status": "SUCCEEDED"
}
Response fields
Field Location Description Type

skill.expiresAt

Response body

The expiration time of the URL.

String

skill.location

Response body

When the status is SUCCEEDED, the skill.location contains a URL that you can use to download a zip archive of the exported skill.

String

skill.eTag

Response body

An opaque version identifier for the skill package. For details, see Use eTag to avoid overwriting a skill package.

String

status

Response body

The status of the export. One of the following values:

  • FAILED
  • IN_PROGRESS
  • SUCCEEDED

Enum

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.