Send a Gadget a Custom Directive from a Skill


If you want to trigger gadget behaviors from a custom skill, you can do that by sending one or more custom directives as part of your skill response. By using custom directives, your skill can send your gadget arbitrary payloads that only your gadget can understand.

To support custom directives, you first define a Custom Interface and, in your gadget's firmware, include code that can decode the custom directives that you defined. Then, to send custom directives from your skill code, you use the Custom Interface Controller. This is an interface that you add to your skill when you set it up using the Alexa Skills Kit developer console or the Alexa Skills Kit Command-Line Interface (ASK CLI).

This topic describes how to query the available gadgets and send a custom directive to the available gadgets from a skill. For instructions on how to define your interface and what you need to do on your gadget to support it, see Learn About Custom Interfaces. You can also send custom events from your gadget to a skill, as described in Receive a Custom Event from a Gadget.

Overview

The following figure, and the description below it, provide an overview of the interaction between a skill and a gadget.

Sending a custom directive to an Alexa Gadget.

The steps, which are described in more detail later on this page, are as follows:

  1. Skill launch – After enabling the skill in the Alexa app, a user launches the skill with a phrase such as "Alexa, open [skill invocation name]". This causes Alexa to send the skill a request. This is usually a launch request, although a user may invoke your skill with a specific intent also.
  2. Query for available gadgets – When the skill launches, your skill code needs to query an Alexa service endpoint to find out whether there are gadgets available to the skill. (This is detailed later in this topic.) "Available" means that the gadget is currently connected to the user's Echo device, and the gadget is registered in the developer portal under the same developer account you used to create the skill. The gadget query procedure has three parts:
    1. Get information from Alexa's request – The skill extracts information from the context object that Alexa's request contained.
    2. Call the Endpoint Enumeration API – The skill uses the extracted information to make an HTTPS GET request to the Endpoint Enumeration API. The Endpoint Enumeration API returns the endpoint ID (gadget ID), name, and capabilities for all available gadgets.
    3. Store the endpoint IDs – The skill stores the returned endpoint IDs, if any, in the skill's session attributes so that it can send directives to those gadgets throughout the skill session. It does not need to query for gadgets within this skill session again.
  3. Skill response – The skill responds to Alexa. The contents of the response depend on whether the skill found any available gadgets in the previous step:
    • Gadgets are available – If the gadget query returned one or more gadgets, then throughout the skill session, your skill can respond to any request from Alexa with a custom directive targeted to those gadgets. Alexa then sends the directive to the Echo device.
    • No available gadgets – If the gadget query does not return any gadgets, then the skill code reacts according to its design. For example, if a gadget is not required, the skill might continue. If a gadget is required, the skill might tell the user that they need a gadget, and then exit.
  4. Gadget receives a directive – When a skill sends a custom directive targeted to an endpoint ID retrieved in the query, the Echo device passes the custom directive to the gadget over Bluetooth in binary format described by .proto files. The gadget extracts the payload, which is a string, and reacts accordingly.

Prerequisites

Before you add skill code to send custom directives to your gadget, do the following:

  • Ensure that your Echo device has at least the minimum software version listed in Before you get started. To find the software version of your Echo device, go to the Alexa app under Settings > Device Settings > [device] > About > Device Software Version. You can make sure that your Echo device has the latest software version by doing the following:
    • For Echo devices without a screen – Say "Alexa, update your software."
    • For Echo devices with a screen – On the Echo device, go to Settings > Device Options > Check for Software Updates.
  • Ensure that you defined your interface and that your gadget declares support for it. These aspects are described in Learn About Custom Interfaces.
  • Create a custom skill and add the Custom Interface Controller interface to the skill's supported interfaces, as described in Set up a Skill for a Gadget.

Step 1: Skill launch

A skill session begins when a user invokes your skill. This causes Alexa to send your skill a request. This is usually a launch request, although a user may invoke your skill with a specific intent also. The request contains a context object.

Step 2: Query for available gadgets

This step has three parts: the skill must first get information from Alexa's request, then call the Endpoint Enumeration API, and then store the endpoint IDs that the Endpoint Enumeration API returned.

Get information from Alexa's request

From the context object in Alexa's request, you must get the values of two fields: the apiEndpoint and apiAccessToken.

  • The apiEndpoint is the base URL of the Alexa endpoint, which depends on the geographic location of your skill. For example, the US endpoint is https://api.amazonalexa.com/.
  • The apiAccessToken encapsulates the permissions granted to your skill. It is in the System object, which is nested in the context object.

The following example, which is a LaunchRequest, shows an apiEndpoint and apiAccessToken.

{
    "version": "1.0",
    "session": {
        "new": true,
        "sessionId": "amzn1.echo-api.session.1",
        "application": {
            "applicationId": "amzn1.ask.skill.1"
        },
        "user": {
            "userId": "amzn1.ask.account.1"
        },
        "attributes": {}
    },

    "context": {
        "AudioPlayer": {
            "playerActivity": "IDLE"
        },
        "System": {
            "application": {
                "applicationId": "amzn1.ask.skill.1"
            },
            "user": {
                "userId": "amzn1.ask.account.1"
            },
            "device": {
                "deviceId": "amzn1.ask.device.1",
                "supportedInterfaces": {
                    "AudioPlayer": {}
                }
            },
            "apiEndpoint": "https://api.amazonalexa.com",
            "apiAccessToken": "someToken"
        }
    },

    "request": {
        "type": "LaunchRequest",
        "requestId": "amzn1.echo-api.request.1",
        "timestamp": "2018-05-11T17:33:01Z",
        "locale": "en-US",
        "shouldLinkResultBeReturned": false
    }
}

Call the Endpoint Enumeration API

Now that it has the apiEndpoint and apiAccessToken, the skill can query for available gadgets. For a gadget to be available to the skill, the gadget must meet the following conditions:

To get a list of all the gadgets that meet these conditions, you call the Endpoint Enumeration API with the apiEndpoint and apiAccessToken that you retrieved in the previous step. You only need to call the Endpoint Enumeration API once per skill session, because the endpoint IDs are valid for the entirety of the session. Normally, the endpoint ID for a given gadget will remain consistent across skill sessions also; however, there are situations where the endpoint ID for a gadget may change (for example, if a user disables and re-enables your skill).

To call the Endpoint Enumeration API, you can use the Endpoint Enumeration Service client in an Alexa Skills Kit SDK or make an HTTPS GET request to the <apiEndpoint>/v1/endpoints endpoint, where <apiEndpoint> is the apiEndpoint that you retrieved from Alexa's request. The format of the GET request is as follows:

GET <apiEndpoint>/v1/endpoints HTTP/1.1 Authorization: Bearer <apiAccessToken>

For example, if apiEndpoint is https://api.amazonalexa.com/ and apiAccessToken is abcde12345, your skill's request to the Endpoint Enumeration API would look similar to the following:

GET https://api.amazonalexa.com/v1/endpoints HTTP/1.1 Authorization: Bearer abcde12345

If Alexa is able to process the request, Alexa returns a response with an HTTP 200 status code that contains a list of available endpoints (gadgets) that your skill can send directives to. Each endpoint has an ID, name, and a list of capabilities that the gadget defined in its Alexa.Discovery.Discover.Response event. Endpoints are in the following format.

{
  "endpoints": [
    {
      "endpointId": "amzn1.ask.endpoint.ABC123",
      "friendlyName": "Gadget123",
      "capabilities": [
          {
              "type":"AlexaInterface",
              "interface":"Custom.CustomInterface1",
              "version":"1.0"
          }
       ]
    },
    {
      "endpointId": "amzn1.ask.endpoint.XYZ789",
      "friendlyName": "Gadget789",
      "capabilities": [
          {
              "type":"AlexaInterface",
              "interface":"Custom.CustomInterface1",
              "version":"1.0"
          }
       ]
    }
  ]
}

The following are the fields of a /v1/endpoints response for a gadget.

Field Description Type
endpointId A unique identifier for the gadget. string
friendlyName The name of the gadget. Because this name might be changed by the user or the platform, it might be different than the Bluetooth friendly name. string
capabilities The list of capabilities that the gadget supports. array
capabilities.type The type of capability interface. This is usually AlexaInterface. string
capabilities.interface The name of the capability interface. string
capabilities.version The version of the capability interface that the gadget supports. string

If the user's Echo device is not connected to any available gadgets, the list of endpoints will be empty.

Store the endpoint IDs

Store the endpoint IDs (gadget IDs) in the skill's session attributes. The endpoint IDs are valid for the entirety of the skill session; you do not need to query for them again.

Step 3: Respond to Alexa with a directive targeted to a gadget

Now that you have a list of gadgets, you can send a gadget a directive. To do so, you include a CustomInterfaceController.SendDirective directive in your response to Alexa's request. Note that:

  • Although the Endpoint Enumeration API returns all capabilities that the gadget supports, skills can only send gadgets directives that belong to Custom Interfaces (that is, interfaces that begin with Custom.).
  • Each directive is targeted to one gadget (that is, one endpoint ID), so if you want to send the same directive to multiple gadgets, include one directive for each gadget (within the same response). That is, include multiple directives into a single response.
  • The maximum size of the skill's response is 24 KB. This limit encompasses all directives and speech in the response.
  • The payload of a CustomInterfaceController.SendDirective directive cannot exceed 1000 bytes.

The following is an example of a response that sends the Custom.Robot.Spin directive to two gadgets.

{
  "version": "1.0",
  "sessionAttributes": {},
  "response": {
    "outputSpeech": {},
    "card": {},
    "reprompt": {},
    "shouldEndSession": true,
    "directives": [
      {
        "type": "CustomInterfaceController.SendDirective",
        "endpoint": {
          "endpointId": "amzn1.ask.endpoint.ABC123"
        },
        "header": {
          "namespace": "Custom.Robot",
          "name": "Spin"
        },
        "payload": { 
          "direction": "clockwise",
          "times": 5
        }
      },
      {
        "type": "CustomInterfaceController.SendDirective",
        "endpoint": {
          "endpointId": "amzn1.ask.endpoint.XYZ789"
        },
        "header": {
          "namespace": "Custom.Robot",
          "name": "Spin"
        },
        "payload": { 
          "color": "clockwise",
          "times": 5
        }
      }      
    ]
  }
}

For the full response format, see Response Format in the Request and Response JSON Reference.

The following are the fields of a CustomInterfaceController.SendDirective directive.

Field Description Type Required
type CustomInterfaceController.SendDirective string yes
endpoint The gadget to send the directive to. Each directive is targeted to one gadget (that is, one endpoint ID). If you want to send the same directive to multiple gadgets, include one directive for each gadget in the response. Object yes
endpoint.endpointId The ID of the gadget to send this directive to. string yes
header The object that contains the header of the directive. Object yes
header.namespace The name of the interface that you defined. string yes
header.name The name of the directive that you defined. string yes
payload The free-form JSON object to send to the gadget. Object yes

Step 4: Decode the directive on the gadget

After your skill includes a custom directive in its response to Alexa, Alexa passes the directive to the Echo device, which passes the directive to the gadget over Bluetooth. As with the Alexa Gadgets Toolkit directives, your gadget receives the directive in a binary format described by .proto files. Your gadget must then decode and process the directive. For more information, see Write code to handle the directive on your gadget.


Was this page helpful?

Last updated: Feb 14, 2022