Use Skill Connections to Request Tasks

An Alexa skill can use a skill connection to request a task from Amazon or from a provider skill. For example, a recipe skill can request that a printer skill print a recipe. Before you make your skill a requester skill, determine what task you want a provider skill to fulfill, and whether you want to use an Amazon-predefined task, or a custom task that's offered by a provider skill. For an overview of skill connections, see Understand Skill Connections.

Request a task from a provider skill

A requester skill requests a task 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 task 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.

Transition prompt

During the transition from the requester skill to the provider skill, Alexa always renders a forwarding prompt. This prompt cannot be customized.

  • If the provider skill is already enabled by the customer, Alexa renders the following prompt:

    Got it. {requester_skill_name} would like to use the skill {provider_skill_name} to do that. May I send the request to {provider_skill_name}?

  • If the provider skill has not yet been enabled by the customer, Alexa renders the following prompt:

    Got it. {requester_skill_name} would like to use the skill {provider_skill_name} to do that, but it is not enabled. To enable this skill, go to your Alexa app and choose Skills.

During the transition from the provider skill back to the requester skill, Alexa always renders a returning prompt. This prompt cannot be customized.

  • Returning you to {requester_skill_name}.

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: implement handler to return a Connections.StartConnection directive

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

For managed skill connection

Only Amazon predefined tasks are supported in managed skill connection. In the following example, the format for task_name should always be AMAZON.{name}, for example, AMAZON.PrintPDF.

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

For direct skill connection

Both Amazon predefined tasks and custom tasks are supported in direct skill connection. In the following example, there are two different formats for task_name:

  • For Amazon predefined tasks, the format is AMAZON.{name}, for example, AMAZON.PrintPDF
  • For custom tasks, the format is {provider_skill_id}.{name}, for example, amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef.CountDown
return handlerInput.responseBuilder
        .addDirective({
            'type': 'Connections.StartConnection',
            'uri': 'connection://{task_name}/{version_number}?provider={provider_skill_id}',
            'input': {
                   ...
                }
            },
            'token': '...',
        })
        .getResponse();

Response attributes

AttributeDescription
typeRequired. Type of the directive, which is Connections.StartConnection in this case.
uriRequired. Resource that defines the task and the task version.
inputOptional. Contains the request object for the task request being sent.
tokenOptional. Token comes back to the skill as-is in the SessionResumedRequest. It can be used to resume the requester skill after the task 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 task 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 task 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: implement a response handler

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

const SessionResumedRequestHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'SessionResumedRequest';
  },
  handle(handlerInput) {
    const status = handlerInput.requestEnvelope.request.cause.status;
    const code = status.code;
    const message = status.message;
    console.log(`SessionResumedRequest received status code : ${code} and message : ${message}`);

    // The current sessionId is same as the one in previous IntentRequest when the original Connections.StartConnection directive was returned.
    const currentSessionId = handlerInput.requestEnvelope.session.sessionId;

    // Continue requester skill experience. In this example, it renders a speech.

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

Task request examples

The following examples show how a skill might request the fulfillment of an Amazon predefined task AMAZON.PrintPDF and custom task amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef.CountDown when handling an IntentRequest.

Example Connections.StartConnection directive

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

For managed skill connection

const TestIntentRequestHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && request.intent.name === 'TestIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .addDirective({
        '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': '1234'
    })
    .getResponse();
  }
};

For Amazon predefined task direct skill connection

const TestIntentRequestHandler = {
   canHandle(handlerInput) {
     const request = handlerInput.requestEnvelope.request;
     return request.type === 'IntentRequest'
       && request.intent.name === 'TestIntent';
   },
   handle(handlerInput) {
     return handlerInput.responseBuilder
       .addDirective({
         'type': 'Connections.StartConnection',
         'uri': 'connection://AMAZON.PrintPDF/1?provider=amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef',
         'input': {
           '@type': 'PrintPDFRequest',
           '@version': '1',
           'title': 'title',
           'description': 'description',
           'url': 'http://www.example.com/flywheel.pdf'
         },
         'token': '1234'
       })
       .getResponse();
   }
};

For custom task direct skill connection

const TestIntentRequestHandler = {
  canHandle(handlerInput) {
    const request = handlerInput.requestEnvelope.request;
    return request.type === 'IntentRequest'
      && request.intent.name === 'TestIntent';
  },
  handle(handlerInput) {
    return handlerInput.responseBuilder
      .addDirective({
        'type': 'Connections.StartConnection',
        'uri': 'connection://amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef.CountDown/1?provider=amzn1.ask.skill.12345678-90ab-cdef-1234-567890abcdef',
        'input': {
          'upperLimit': 10,
          'lowerLimit': 1
        },
        'token': '1234'
      })
      .getResponse();
  }
};

Example: JSON schema for the SessionResumedRequest request

After the provider skill fulfills the task request, the requester receives a SessionResumedRequest object. The result is defined in the task definition.

{
    "type": "SessionResumedRequest",
    "requestId": "string",
    "timestamp": "string",
    "locale": "string",
    "cause": {
        "type": "ConnectionCompleted",
        "token": "1234",
        "status": {
            "code": "200",
            "message": "OK"
        },
        "result": {
            "key1": "value1",
            "key2": "value2"
        }
    }
}

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) {
        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

For managed skill connection

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

The provider skill that is fulfilling the task 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
    • 400 : Bad request - request was invalid
    • 403 : Requester was not allowed to invoke provider
    • 404 : No providers available at this time
    • 500 : Server error
  • message : Plain string message that describes the outcome of the request. For example, this message might be "Ride has been booked successfully."

For direct skill connection

The requester skill will only receive the following status codes. The provider skill that is fulfilling the task request can only return one of the following status code.

  • status: Status of the request
  • code: status code
    • 200 : Request was successfully fulfilled
    • 400 : Bad request - request was invalid
    • 403 : Requester was not allowed to invoke provider
    • 404 : No providers available at this time
    • 500 : Server error
  • message : Plain string message 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 requester skill, you can test it as you would normally test for other invocations. After your requester skill initiates the task request, Alexa selects a suitable provider for the task request from the list of possible providers, and the Alexa service routes 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 task request. To test how your skill responds when it receives SessionResumedRequest 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.

Example: test how your SessionResumedRequest handler deals with a 404 status code

To test how your SessionResumedRequest handler deals with receiving a 404 status code, your skill should return the following directive:

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

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

{
    "type": "SessionResumedRequest",
    "requestId": "string",
    "timestamp": "string",
    "locale": "string",
    "cause": {
        "type": "ConnectionCompleted",
        "status": {
            "code": "404",
            "message": "Status code testing succeeded"
        }
    }
}

Publish your requester skill

The certification requirements for a requester skill are no different from the requirements for a skill that is not a requester.

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.

For more information about publishing Alexa skills, see Skill Certification and Publication.

Developer support

For inquiries and support, please reach out to the Skill Connections team at skill-connections-v2-beta@amazon.com.