Implement Alexa Skill Connections

With the Skill Connections feature, you can enable an Alexa skill to fulfill a customer request that it can't otherwise handle by forwarding the request to another skill for fulfillment. With a skill connection, the skill that asks Alexa for the fulfillment of a request is called the "requester" and the skill that services this request is called the "provider."

The Skill Connections feature improves the Alexa customer experience by allowing customers to move freely between skills without having to repeat information. For example, a customer who interacts with a recipe skill can say "print this" to print a recipe with a web printing skill. In this case, the recipe skill is the requester, and the web printing skill is the provider. If a skill connection fails, such as if a customer does not have a printer, the skill connection ends, and the connection returns the customer to the original requester skill.

Skill Connections sample code

The following demo in GitHub provides both requester-skill and provider-skill sample implementations. The samples in GitHub and the example code provided later in this section both use the Alexa Skills Kit Node.js SDK.

Make your skill a skill connection requester

A "requester" skill requests a skill connection from a "provider" skill. If possible, the provider skill fulfills the request of the requester skill. If you have an existing skill, you can modify this skill so that it becomes a requester, which means that it can request a skill connection from skills that are providers.

To make your skill a requester for a skill connections task

  1. Implement a handler to return a Connections.StartConnection directive.
  2. Implement a handler to receive the response from a SessionResumedRequest request. When the provider skill finishes with its task, this handler enables the provider skill to return control to the requester skill and return the user to the same place in the original requester skill session.

For more information about the tasks that a provider skill can fulfill, see Supported skill connection tasks.

Implement a handler to return a Connections.StartConnection directive

Your requester skill can send a skill connections request if you set the Connections.StartConnection directive in the response object, as shown in the following example. Your service code must leave the shouldEndSession flag undefined when it returns a Connections.StartConnection directive.

Example code to implement handler to return a Connections.StartConnection directive

The following example shows how to implement a handler to return a Connections.StartConnection directive.

return handlerInput.responseBuilder
        .addDirective({
            'type': 'Connections.StartConnection',
            'uri': 'connection://{task_name}{/version_number}',
            'input': {
                   ...
                }
            },
            'token': '...',
        })
        .getResponse();

Response attributes

AttributeDescription
typeType of the directive, which is Connections.StartConnection in this case.
uriResource that defines the task and the task version.
inputContains the request object for the skill connection request being sent.
tokenToken comes back to the skill as-is in the SessionResumedRequest. It can be used to resume the requester skill after the skill connection request is complete.

Implement a handler to receive a response from a skill connections request

A requester skill must also implement a handler to receive a skill connection response for the original skill connection request. If you don't implement a response handler, your skill will have an unhandled exception, which means that your requester skill cannot take back control from the provider skill.

To implement a handler to receive a skill connection response for a skill connection request

  • Add a SessionResumedRequest handler to the skill, as shown in the following example.

When the requester skill receives a SessionResumedRequest, it restores the previous session of the skill from when the original Connections.StartConnection directive was returned.

Example code to implement a response handler

The following example shows how to implement a handler to receive a response from a skill connections request.

const ConnectionsResponseHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'SessionResumedRequest';
  },
  handle(handlerInput) {
    const statusCode = handlerInput.requestEnvelope.request.cause.status.code;
    const statusMessage = handlerInput.requestEnvelope.request.cause.status.message;
    console.log('SessionResumedRequest received: status code : [' + statusCode + '], message : [' + message + ']');

   // Session attributes and ID are same as previous IntentRequest
   const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();


    // Continue requester skill experience

    return handlerInput.responseBuilder
        .speak("Requester skill received SessionResumedRequest")
        .getResponse();
  },
};

Skill connection requester examples

The following examples show how a skill might request the fulfillment of an Amazon.PrintPDF task.

Example Connections.StartConnection directive

First, a requester skill returns a Connections.StartConnection directive.

PrintPDFSkillConnectionsRequestDispatcher = {
    speechText: 'Requester sending Skill Connections request to print PDF',
    directive: {
        'type': 'Connections.StartConnection',
        'uri': 'connection://AMAZON.PrintPDF/1',
        'input': {
         '@type': 'PrintPDFRequest',
         '@version': '1',
         'title': 'title',
         'description': 'description',
         'url': 'http://www.example.com/flywheel.pdf'
        },
        'token': 'none'
    }

Example JSON schema for the SessionResumedRequest request

After the provider skill fulfills the skill connection request, the requester receives a SessionResumedRequest object.

{
    "type": "SessionResumedRequest",
    "requestId": "string",
    "timestamp": "string",
    "locale": "string",
    "originIpAddress": "string",
    "cause": {
        "type": "ConnectionCompleted",
        "token": "1234",
        "status": {
            "code": "200",
            "message": "OK"
        },
        "result": null
    }
}

Example code for handler to receive SessionResumedRequest

The requester skill has a handler to receive the SessionResumedRequest object.

const SessionResumedRequestHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return request.type === 'SessionResumedRequest';
    },
    handle(handlerInput) {
        console.log("Requester skill received SessionResumedRequest");
        const sessionAttributes = handlerInput.attributesManager.getSessionAttributes();
        const status = handlerInput.requestEnvelope.request.cause.status;
        const code = status.code;
        const message = status.message;

        const speechText = `status code is ${code}, message is ${message}`;

        return handlerInput.responseBuilder
            .speak(speechText)
            .getResponse();
    },
};

Status code attributes

Alexa can return any of the following status codes on a skill connection request call.

The provider skill that is fulfilling the skill connection request can return any valid HTTP code.

  • status: Status of the request
  • code: status code
    • 200 : Request was successfully fulfilled
    • 204 : User denied to use the Connection
    • 227 : Provider was not account linked
    • 404 : No providers available at this time
    • 400 : Bad request - request was invalid
    • 500 : Server error
  • message : Plain string message, which is spoken by Alexa, that describes the outcome of the request. For example, this message might be "Ride has been booked successfully."

For more information, see Handle Requests Sent by Alexa.

Test your requester skill

After you make your skill a connection requester, you can test your skill as you would normally test for other invocations. After your requester skill initiates the skill connection request, Alexa resolves a suitable provider for the skill connection request from the list of possible providers, and the Alexa service routs the request to the selected live provider skill.

Additionally, you should test how your requester skill handles various status codes that might be returned to the requester skill during the handling of a skill connection request. To test how your skill responds when it receives a skill connection response with a specific status code, alter your requester skill to return a Connections.StartConnection directive with the AMAZON.TestStatusCode task defined. In the return body of this directive, the input includes the status code you want to test. For example, to test how your SessionResumedRequest handler deals with receiving a 502 status code, your skill should return the following directive:

return handlerInput.responseBuilder
        .addDirective({
            'type': 'Connections.StartConnection',
            'uri': 'connection://AMAZON.TestStatusCode/1',
            'input': {
                'code': '502'
            }
        })
        .getResponse();

The requester skill then receives a SessionResumedRequest object that contains the status code defined in the input.

Publish your requester skill

If you have not already published your requester skill, complete the testing and skill submission requirements as usual, and submit your skill for certification. When Amazon certifies your skill, they make it publicly available, and your skill can then function as a requester skill. If Amazon has already certified your skill, and you later make changes to make your skill a requester skill, you make those changes publicly available when you publish them.

Make your skill a skill connection provider

If you want your skill to handle skill connection tasks from requester skills, you should make your skill a provider skill.

Update your skill to become a provider for a skill connection task

  1. Update the skill manifest to register the skill as a provider for a skill connection task.
  2. Implement a handler to fulfill a skill connection task.

In addition, your skill must be approved as a provider during the certification process.

Update the skill manifest to register your skill as a provider for a skill connection task

To add Skill Connections support to your skill, add the tasks field to your skill manifest as shown in the following example.

The field name is the name of the task that your skill is able to fulfill and the field version is the version of that task. This example manifest indicates that this skill is registered to be a provider for version 1 of the AMAZON.PrintPDF task.

Example skill manifest for a provider skill

The following example shows how to update the skill manifest to register your skill as a provider for a skill connection task.

{
   "manifest": {
       "publishingInformation": {
           "locales": { ... }
        },
       "apis": {
           "custom": {
               "endpoint": {
                   "uri": "..."
                },
               "interfaces": [],
               "tasks" : [
                    {
                     "name": "AMAZON.PrintPDF",
                     "version": "1"
                    }
                ]
            }
        },
       "manifestVersion": "..."
    }
}

Implement a handler to fulfill a skill connection task

A provider skill must implement a handler to receive a skill connection request. If you do not implement a request handler, your skill will have an unhandled exception and that will break the customer experience.

The provider skill receives a LaunchRequest object in the request sent from the requester skill.

After handling the task, the provider must send a Tasks.CompleteTask directive in response to return control back to the requester. When your provider skill returns a Tasks.CompleteTask directive, the shouldSessionEnd attribute must be defined as true.

Example code for handler that fulfills a skill connection task

The following example shows how to implement a handler to fulfill a skill connection task.

const ConnectionsRequestHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return request.type === 'LaunchRequest'
            && request.task.name == "AMAZON.RequestType";
    },
    handle(handlerInput) {
        console.log("Handling AMAZON.RequestType task.");

        // Business Logic

        let speechText = "OK, your request has been received";

        return handlerInput.responseBuilder
            .speak(speechText)
            .addDirective({
                "type": "Tasks.CompleteTask",
                "status": {
                    "code": "200",
                    "message": "return as desired",
                }
            })
            .withShouldEndSession(true)
            .getResponse();
    },
};

Response attributes

typeType of the directive. In this case, Tasks.CompleteTask is used to complete a skill connection request.
statusContains code and message. Code can be any valid HTTP code.

Skill connection provider examples

The requester skill sends a skill connection request by sending a LaunchRequest that includes task information to the provider skill. The provider skill connection request handler receives this LaunchRequest.

Example LaunchRequest that the requester skill sends to the provider skill

{
    "type": "LaunchRequest",
    "requestId": "string",
    "timestamp": "string",
    "locale": "string",
    "originIpAddress": "string",
    "task": {
        "name": "AMAZON.PrintPDF",
        "version": "1",
        "input": {
            "@type": "PrintPDFRequest",
            "@version": "1",
            "title": "Flywheel",
            "description": "Flywheel",
            "url": "http://www.example.com/flywheel.pdf"
        }
    }
}

Example of a provider skill receiving an Amazon.PrintPDF skill connection task request

When the provider skill receives a skill connection task, it must handle it. This example code shows how a provider skill might handle receiving an Amazon.PrintPDF skill connection task request.

const PrintPDFTaskHandler = {
    canHandle(handlerInput) {
        const request = handlerInput.requestEnvelope.request;
        return request.type === 'LaunchRequest'
            && request.task.name == "AMAZON.PrintPDF";
    },
    handle(handlerInput) {
        console.log("Handling AMAZON.PrintPDF task.");

        // Logic to print PDF

        let speechText = "OK, your print is confirmed";

        return handlerInput.responseBuilder
            .speak(speechText)
            .addDirective({
                "type": "Tasks.CompleteTask",
                "status": {
                    "code": "200",
                    "message": "return as desired",
                }
            })
            .withShouldEndSession(true)
            .getResponse();
    },
};

Test your provider skill

The ASK development team has provided a test requester skill that can send valid skill connection requests to your provider skill. Follow these steps so that your provider skill can interact with this test requester skill. Make sure that you enter each of these commands on a single line.

  1. Make sure that you have enabled testing in your provider skill. For more information, see Test your skill.
  2. In the developer console, open your provider skill, and then select the Test tab.
  3. To test with a valid skill connection request, enter:
    open connection tester and send valid connection request with parameters <skill-id>--<task-name>
    For <skill-id>, substitute your provider skill's skillId. For <task-name>, substitute a valid task name such as PrintPDF. This command sends a request with a valid schema to your provider skill's development stage. For example, if you want to test how your provider skill handles the PrintPDF task, type:
    open connection tester and send valid connection request with parameters amzn1.ask.skill.abcdef-0dff-4a56-a83c-9783ea111a11--PrintPDF
  4. To test with an invalid skill connection request, type:
    open connection tester and send invalid connection request with parameters <skill-id>--<task-name>
    This command sends a request with an invalid schema to your provider skill's development stage. For example, if you want to test how your provider skill handles the PrintPDF task with an invalid schema, type:
    open connection tester and send invalid connection request with parameters amzn1.ask.skill.abcdef-0dff-4a56-a83c-9783ea111a11--PrintPDF

Publish your provider skill for certification

When you finish testing your provider skill, you can publish your skill for certification. After Amazon certifies your skill, it becomes publicly available. When a requester sends a skill connection request for the task that your skill provides, Alexa considers your provider skill as an option to fulfill the request.

To have your provider skill certified, it should meet the following behavioral requirements. These help ensure a good customer experience.

  • Your provider skill must fulfill the functionality related to the skill connection task that the requester skill invoked. For example, if your provider skill is supposed to print a web page, it must be able to do that when requested from the requester skill.
  • Your provider skill must gracefully handle an invalid or empty payload received from the requester skill. For example, if your provider skill is printing an image, and the URL provided for the image is invalid, the provider skill should inform the customer that the URL was invalid. If the payload is empty or invalid, your skill should handle this error gracefully with a user-friendly voice prompt.
  • • The customer can cancel any actions that your provider skill fulfills on behalf of the requester skill by invoking the provider skill with the provider skill's example phrases or invocation name. The customer can do so just as if the customer had interacted with the skill directly. For example, with a ride-sharing provider skill, if the customer says "Alexa, cancel my ride", that utterance should lead to the same cancellation dialog as if the customer had ordered the ride directly from the skill.

Supported skill connection tasks

Skill Connections support the following tasks. Each task has a unique schema for its payload.

To provide a consistent user experience, each skill connection task has its own voice design guidelines, which are included with the description of each task. These guidelines indicate the prompts used by the requester skill, the provider skill, and Alexa during the fulfillment of a skill connection request.

AMAZON.PrintImage

With the AMAZON.PrintImage task, your requester skill can request to send an image to a printing skill. This task can be used for printing photos, coloring pages, puzzles, origami templates, and so forth.

Parameters

Name Required? Type Description
title Yes String Title of what is being printed.
description No String Description of the file.
url Yes String URL of the image.
imageType Yes Enum Type of image. One of: JPG, JPEG

Example response with input

{
  "type": "Connections.StartConnection",
  "uri": "connection://AMAZON.PrintImage/1",
  "input": {
         "@type": "PrintImageRequest",
         "@version": "1",
         "title": "Flywheel Document",
         "description": "Flywheel",
         "imageType": "JPEG",
         "url": "http://www.example.com/flywheel.jpeg"
  }
}

Voice design guidelines

This example demonstrates an expected customer experience for the AMAZON.PrintImage task.

Alexa (as determined by requester skill developer): Today's crossword puzzle is available!
Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?
User: Sure.
Alexa (as determined by provider skill developer): Today's crossword puzzle is now printing.
Alexa (as determined by Alexa): Returning you to {requester_skill_name}.

Customer has never used provider. Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?
Customer has used provider. Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?

When the session transitions from the provider skill back to the requester skill, Alexa renders a prompt to indicate this.

Alexa (as determined by Alexa): Returning you to {requester_skill_name}.

When your skill surfaces a piece of content that the customer might like to print, your skill should return a response that includes:

  • A prompt that tells the customer that the content is available.
  • A Connections.StartConnection directive with the relevant payload parameters.

AMAZON.PrintPDF

With the AMAZON.PrintPDF task, your requester skill can request to send a PDF document to a printing skill. The possible uses for this task are broad, and include printing documents, coloring pages, puzzles, origami templates, and so forth.

Parameters

Name Required? Type Description
title Yes String Title of what is being printed.
description No String Description of the PDF file.
url Yes String Location of the PDF file.

Example response with input

{
 "type": "Connections.StartConnection",
 "uri": "connection://AMAZON.PrintPDF/1",
 "input": {
         "@type": "PrintPDFRequest",
         "@version": "1",
         "title": "title",
         "description": "description",
         "url": "http://www.example.com/flywheel.pdf"
  }
}

Voice design guidelines

This example demonstrates an expected customer experience for the AMAZON.PrintPDF task.

Alexa (as determined by requester skill developer): Today's crossword puzzle is available!
Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?
User: Sure.
Alexa (as determined by provider skill developer): Today's crossword puzzle is now printing.
Alexa (as determined by Alexa): Returning you to {requester_skill_name}.

Customer has never used provider. Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?
Customer has used provider. Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?

When the session transitions from the provider skill back to the requester skill, Alexa renders a prompt to indicate this.

Alexa (as determined by Alexa): Returning you to {requester_skill_name}.

When your skill surfaces a piece of content that the customer might like to print, your skill should return a response that includes:

  • A prompt that tells the customer that the content is available.
  • A Connections.StartConnection directive with the relevant payload parameters.

AMAZON.PrintWebPage

With the AMAZON.PrintWebPage task, your requester skill can request to send a web page to a printing skill. The possible uses for this task are broad, and include printing documents, coloring pages, puzzles, origami templates, and so forth.

Name Required? Type Description
title Yes String Title of what is being printed.
description No String Description of the web page.
url Yes String Location of the web page.

Example response with input

{
 "type": "Connections.StartConnection",
 "uri": "connection://AMAZON.PrintWebPage/1",
 "input": {
       "@type": "PrintWebPageRequest",
       "@version": "1",
       "title": "title",
       "description": "description",
       "url": "http://www.example.com/flywheel.html"
    }
}

Voice design guidelines

This example demonstrates an expected customer experience for the AMAZON.PrintWebPage task.

Alexa (as determined by requester skill developer): Today's crossword puzzle is available!
Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?
User: Sure.
Alexa (as determined by provider skill developer): Today's crossword puzzle is now printing.
Alexa (as determined by Alexa): Returning you to {requester_skill_name}.

Customer has never used provider. Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?
Customer has used provider. Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?

When the session transitions from the provider skill back to the requester skill, Alexa renders a prompt to indicate this.

Alexa (as determined by Alexa): Returning you to {requester_skill_name}.

When your requester skill surfaces a piece of content that the customer might like to print, your skill should return a response that includes:

  • A prompt that tells the customer that the content is available.
  • A Connections.StartConnection directive with the relevant payload parameters.

AMAZON.ScheduleTaxiReservation

With the AMAZON.ScheduleTaxiReservation task, your requester skill can request to have the provider skill help the customer book a ride. This task enables a skill to use the customer's preferred method of scheduling rides, thus making the requester skill more useful, and driving business to the customer's preferred provider.

Name Required? Type Description
partySize No Integer Number of people in the reservation
pickupLocation Yes/No PostalAddress Optional only when dropoffLocation is provided. Location where the customer wants to be picked up.
pickupTime No DateTime Time at which the customer wants to be picked up.
dropoffLocation Yes/No PostalAddress Optional only when pickupLocation is provided. Location where the customer wants to be dropped off.

PostalAddress Parameters

Name Required? Type Description
streetAddress Yes String Street address.
locality Yes String Typically a town or city or equivalent.
region Yes String Typically a state or province or equivalent.
postalCode Yes String Postal code, which is a zip code in the United States.
country No String Country.

Example response with input

{
 "type": "Connections.StartConnection", 
 "uri": "connection://AMAZON.ScheduleTaxiReservation/1",
 "input": {
       "@type": "ScheduleTaxiReservationRequest",
       "@version": "1",
       "partySize": 4,
       "pickupLocation": {
           "@type": "PostalAddress",
           "@version": "1",
           "streetAddress": "415 106th Ave NE",
           "locality": "Bellevue",
           "region": "WA",
           "postalCode": "98004",
           "country": "US"
        },
       "pickupTime": null,
       "dropoffLocation": {
           "@type": "PostalAddress",
           "@version": "v",
           "streetAddress": "2031 6th Ave.",
           "locality": "Seattle",
           "region": "WA",
           "postalCode": "98121",
           "country": "US"
        }
    }
}

Voice design guidelines

The following dialog depicts the expected customer experience for the AMAZON.ScheduleTaxiReservation task.

Alexa (as determined by requester skill developer): Your tickets have been booked.
Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?
User: Sure.
Alexa (as determined by provider skill developer): {ride_fulfilling_skill}
Alexa (as determined by Alexa): Returning you to {requester_skill_name}.

Customer has never used provider. Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?
Customer has used provider. Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?

When the session transitions from the provider skill back to the requester skill, Alexa renders a prompt to indicate this.

Alexa (as determined by Alexa): Returning you to {requester_skill_name}.

When your customer has completed something and you believe that ordering a ride would be relevant, your requester skill should return a response that includes:

  • A prompt that tells the customer they have completed something.
  • A Connections.StartConnection directive with the relevant input parameters.

AMAZON.ScheduleFoodEstablishmentReservation

With the AMAZON.ScheduleFoodEstablishmentReservation task, your requester skill can request a provider skill to help customers get reservations. This task enables a skill to use the customer's preferred method of scheduling restaurant reservations, thus making the requester skill more useful, and driving business to the restaurant.

Name Required? Type Description
startTime No DateTime Time of the reservation.
partySize No Integer Number of people in the reservation.
restaurant Yes Restaurant Restaurant where reservation is placed.

Restaurant Parameters

Name Required? Type Description
name Yes String Name of the restaurant.
location Yes PostalAddress Address of the restaurant.

PostalAddress Parameters

Name Required? Type Description
streetAddress Yes String Street address.
locality Yes String Typically a town or city or equivalent.
region Yes String Typically a state or province or equivalent.
postalCode Yes String Postal code, which is a zip code in the United States.
country No String Country.

Example response with input

{
 "type": "Connections.StartConnection",
 "uri": "connection://AMAZON.ScheduleFoodEstablishmentReservation/1",
 "input": {
       "@type": "ScheduleFoodEstablishmentReservationRequest",
       "@version": "1",
       "startTime": "2018-04-08T01:15:46Z",
       "partySize": 2,
       "restaurant": {
           "@type": "Restaurant",
           "@version": "1",
           "name": "Amazon Day 1 Restaurant",
           "location": {
               "@type": "PostalAddress",
               "@version": "1",
               "streetAddress": "2121 7th Avenue",
               "locality": "Seattle",
               "region": "WA",
               "postalCode": "98121",
               "country": "US"
            }
        }
    }
}

Voice design guidelines

This example demonstrates an expected customer experience for the AMAZON.ScheduleFoodEstablishmentReservation task.

Alexa (as determined by requester skill developer): Amazon Day 1 Restaurant has the best hip cocktails near you.
Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?
User: Sure.
Alexa (as determined by provider skill developer): {provider_skill}
Alexa (as determined by Alexa): Returning you to {requester_skill_name}.

Customer has never used provider. Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?
Customer has used provider. Alexa (as determined by Alexa): Do you want to give {provider_skill_name} a try?

When the session transitions from the provider skill back to the requester skill, Alexa renders a prompt to indicate this.

Alexa (as determined by Alexa): Returning you to {requester_skill_name}.

After a customer has prompted your requester skill for restaurant information, and if you would like your requester skill to provide restaurant information and connect to a provider skill to reserve a table, your requester skill should return a response that includes:

  • A prompt that tells the customer about the restaurant.
  • A Connections.StartConnection directive with the relevant input parameters.