Learn About Custom Interfaces
To enable communication between a gadget and an Alexa skill, you can create Custom Interfaces. Custom Interfaces enable a skill to trigger gadget behaviors, and enable the skill to act on information it receives from a gadget.
Note that the interfaces that the Alexa Gadgets Toolkit provides enable you to trigger gadget behaviors in reaction to Alexa's native capabilities, such as notifications and wake word detection. Unlike Custom Interfaces, these interfaces cannot be accessed from an Alexa skill.
This topic describes ways that you can use a Custom Interface, how to define a Custom Interface, and what your gadget needs to do to support that interface. The directives and events that you create under a Custom Interface can only be used through a custom skill. To do this, you first define a Custom Interface as described in this topic. You then access the interface from your skill by using the Custom Interface Controller as described in Send a Gadget a Custom Directive from a Skill and Receive a Custom Event from a Gadget.
Custom gadgets that provide smart home functionality will not pass certification.
Overview
Your Custom Interface can include custom directives, custom events, or both. Custom directives and custom events are separate; you do not need to use one to use the other.
-
Custom directives – These are sent from the skill to the gadget. You might use custom directives to:
Use of custom directives Example Trigger device behavior based on skill content
A game board that flashes light animations at the opening of a skill or a windmill gadget that changes its speed based on the report from a wind skill. Support implicit commands from the user
Alexa says, "How about a game of battleship?" A user response of "yes" would set the mode of the game to battleship mode. Support explicit, but more complex commands from the user
A user says, "Alexa, ask my robot to rotate three times." -
Custom events – These are sent from a gadget to a skill. Custom events enable your skill to process and act on information from the gadget. For example, you might create custom events that:
Use of custom events Example Trigger an immediate skill response such as voice or audio
Inform the skill that a robot has completed its spin. Alexa responds "Your robot is warmed up and ready to go! Let's start the game!" Report a gadget's status
After a race challenge, have Alexa summarize key aspects of the race, such as, "your car drove for 35 seconds, went up an incline of 15%, and rotated three times." Collect and apply business logic to one or a set of events
Inform the skill of the order in which a user pressed lighted buttons on a board during a sequence game, so that the skill can determine if the buttons were pressed in the correct order.
Because gadgets do not connect directly to the Alexa cloud, they use an Echo device to handle communication with the skill. The following figure shows how a gadget and a skill exchange directives and events.

Data format
Your gadget sends and receives custom events and directives, respectively, using the following format:
- Custom directives – The skill sends the directive to the Alexa cloud in JSON using the same response format that other custom skills use. The Alexa cloud passes it to the Echo device, which sends the directive to the gadget encoded as UTF-8 in a binary data format based on protocol buffers.
- Custom events – The gadget encodes the string into a binary data format based on protocol buffers, and sends it to the Echo device. The Echo device sends the event to the Alexa cloud, which passes it to the skill in JSON, using the same request format that other custom skills use.
Limits
Limits related to Custom Interfaces are as follows:
Description | Limit |
---|---|
Custom directive size |
1 KB (1,000 bytes) |
Custom event size |
1 KB (1,000 bytes) |
Custom event maximum rate |
5 events per second |
Namespace |
|
Custom directive and event names |
|
Event handler duration |
Minimum: 1 second (1,000 ms) |
How to define and use a Custom Interface on your gadget
The steps to defining and using a Custom Interface on a gadget are as follows:
- Step 1: Name your interface, directives, and events
- Step 2: Declare support for the interface
- Step 3: Handle directives on your gadget
- Step 4: Send events from your gadget
Step 1: Name your interface, directives, and events
When you define a Custom Interface for your gadget, you must choose:
- A name for the interface. This will be the namespace for the interface, and must start with
Custom.
Namespaces must conform to the limits described in Limits. - A name for any custom directive(s) that you want the interface to include. Custom directive names must conform to the limits described in Limits.
- A name for any custom event(s) that you want the interface to include. Custom event names must conform to the limits described in Limits.
You can define a namespace for each directive and event, or you can include multiple directives and events in a single namespace.
For example, if your gadget is a robot that spins around, you might create a Custom.Robot
namespace and define a directive called Spin
that instructs the robot to spin, and an event called SpinStatus
for the robot to send when it has completed its spin.
Step 2: Declare support for the interface
Your gadget must declare support for the interface within the Alexa.Discovery.Discover.Response
event that it sends the Echo device in response to the Alexa.Discovery.Discover
directive.
Continuing the previous example, to indicate that your gadget supports the Custom.Robot
interface and all the directives and events declared under it, your gadget's Alexa.Discovery.Discover.Response
event must include the Custom.Robot
interface in its array of Capabilities
as follows:
{
"type": "AlexaInterface",
"interface": "Custom.Robot",
"version": "1.0"
}
Step 3: Handle directives on your gadget
If your Custom Interface includes directives, your gadget code should decode and take action on the directives that the skill sends it. Although your gadget receives custom directives in a data format similar to the directives included in the Alexa Gadgets Toolkit, there are a few differences. For custom directives, the payload is a string, in bytes, encoded as UTF-8. To decode the payload, you first extract the payload from the overall directive, which is encoded using protocol buffers. You then simply parse the fields of the payload string. The code to deserialize the directive would look similar to the following:
#include <stdio.h>
#include "pb.h"
#include "pb_decode.h"
#include "pb_encode.h"
#include "directiveHeader.pb.h"
#include "directiveParser.pb.h"
typedef unsigned char uint8_t;
typedef unsigned char BOOL;
void parse_directive_proto(uint8_t* buffer, int len)
{
pb_istream_t stream = pb_istream_from_buffer(buffer, len);
directive_DirectiveParserProto envelope = directive_DirectiveParserProto_init_default;
pb_decode(&stream, directive_DirectiveParserProto_fields, &envelope);
printf("name=%s, namespace=%s, payload=%s\n",
envelope.directive.header.name,
envelope.directive.header.namespace,
envelope.directive.payload.bytes);
}
The deserialized directive would look similar to the following:
{
"directive": {
"header": {
"namespace": "Custom.Robot",
"name": "Spin"
},
"payload": "{\"direction\":\"clockwise\",\"times\":5}"
}
}
Step 4: Send events from your gadget
First, put your event in a JSON-formatted string, including the outer braces. For example, the robot gadget described previously might assemble a Custom.Robot.SpinStatus
event payload such as {"finished":"yes", "remainingBatteryPercent":80}
.
Then, before sending the event to the Echo device, your gadget must put the event into a binary data format based on protocol buffers. The format of the event will be similar to the Alexa.Discovery.Discover.Response
event.
The following is an example of a protocol buffer file that you can use to encode event data before sending it to the Echo device. The Echo device sends the event to Alexa, which sends it to the skill.
syntax = "proto3";
import "eventHeader.proto";
message CustomEventProto {
Event event = 1;
message Event {
header.EventHeaderProto header = 1;
string payload = 2;
}
}
The following is an example of the accompanying options file. In this example, the options file sets the maximum payload size to the maximum allowable value, which is 1,000 bytes.
CustomEventProto.Event.payload max_size:1000
The following code provides an example of how to encode an event.
#include "customEvent.pb.h"
void encode_custom_event(uint8_t* buffer, size_t len, char *namespace, char *name, char *payload)
{
pb_ostream_t stream = pb_ostream_from_buffer(buffer, len);
CustomEventProto custom_event_envelope =
CustomEventProto_init_default;
strcpy(custom_event_envelope.event.header.namespace, namespace);
strcpy(custom_event_envelope.event.header.name, name);
strcpy(custom_event_envelope.event.payload, payload);
BOOL status = pb_encode(&stream, CustomEventProto_fields, &custom_event_envelope);
if (!status)
{
printf("%s: Error encoding message\n", __FUNCTION__);
return;
}
}
For example, to send the custom event SpinStatus
from your robot gadget, you might encode the data as follows:
size_t len = 256;
uint8_t payload[len];
char* namespace = "Custom.Robot";
char* name = "SpinStatus";
char* payload = "{\"finished\":\"yes\", \"remainingBatteryPercent\" : 80}";
encode_custom_event(payload, len, namespace, name, payload);
The gadget can then send the encoded custom event to the Echo device in the same way that it sends the Alexa.Discovery.Discover.Response
event.
Last updated: Feb 14, 2022