Alexa.SecurityPanelController Interface

Implement the Alexa.SecurityPanelController interface in your Alexa skill so that users can arm and disarm security systems, and so that you can report alarm conditions to your users. For more information about security skills, see Smart Home Security Overview.

If your security system uses contact and motion sensors, you can also implement the Alexa.ContactSensor and Alexa.MotionSensor interfaces for a unified user experience.

For the list of languages that the SecurityPanelController interface supports, see List of Alexa Interfaces and Supported Languages.

Utterances

When you use the Alexa.SecurityPanelController interface, the voice interaction model is already built for you. The following examples show some user utterances, where "my home" is the name that the user assigned to their security system device:

Alexa, arm my home in away mode.
Alexa, arm my home.
Alexa, disarm my home.
Alexa, is my home armed?

After the user says one of these utterances, Alexa sends a corresponding directive or state request to your skill.

Properties

The armState property

The Alexa.SecurityPanelController interface uses the armState property as the primary property. You identify the arm states that you support in your discovery response. At a minimum, we recommend that you support DISARMED and at least one ARMED state.

ArmState property example

Copied to clipboard.

{
    "namespace": "Alexa.SecurityPanelController",
    "name": "armState",
    "value": "DISARMED"
}

You can use the following values for armState. The values are strings.

Value Description
ARMED_AWAY The security system is active and the occupants are away.
ARMED_STAY The security system is active and the occupants are present.
ARMED_NIGHT The security system is active and the occupants are sleeping.
DISARMED The security system is not active.

The alarm properties

The Alexa.SecurityPanelController interface uses alarm properties to represent different types of alarms and the current status of each. Use these alarm properties in the context object when you respond to directives or report state to Alexa. Use ALARM as the property value to indicate that an alarm condition is happening.

Support for alarms is optional. You identify the alarms that you support in your discovery response.

Burglary alarm example

Copied to clipboard.

{
    "name": "burglaryAlarm",
    "value": {
        "value": "OK"
    }
}

You can use the following alarms.

Property Description Type
burglaryAlarm The current state of a burglary alarm; OK or ALARM. Object
carbonMonoxideAlarm The current state of a carbon monoxide alarm; OK or ALARM. Object
fireAlarm The current state of a fire alarm; OK or ALARM. Object
waterAlarm The current state of a water alarm; OK or ALARM. Object

Security system considerations

Arming a security system

If the armed state of a security system is ARMED_AWAY, meaning that the occupants are away, the user must disarm the security system before changing to another armed state. For example, if the user is away, comes home, and wants to change the armed state to ARMED_NIGHT, the user must disable the security system first, and then set the new armed state. If you receive an arm directive that violates this rule, respond with an error type AUTHORIZATION_REQUIRED error. For more information, see Alexa.SecurityPanelController.ErrorResponse.

Bypass by voice option

When a user tries to arm their security system, you might not be able to satisfy the request. For example, when a user tries to arm their system, but a window that has a contact sensor is open. An open sensor represents an error that the user must correct or bypass before you can arm the security system. In that case you reject the request to arm the system, and send an Alexa.SecurityPanelController.ErrorResponse with type BYPASS_NEEDED.

If you want users to bypass errors by using voice commands, include a list of the endpoints that need bypassing in the payload of your BYPASS_NEEDED response. After Alexa receives a BYPASS_NEEDED response with a list of endpoints in the payload, Alexa prompts the user to bypass the errors. For more information, see bypass needed example.

The following example shows a sample conversation when you include a list of the endpoints that need bypassing in the payload of your BYPASS_NEEDED response. "My home" is the name that the user assigned to their security system device.

Alexa, arm my home in away mode.
Hmm, side window, kitchen window, and one more sensor need bypassing. Do you want to arm your system anyway?
Yes
Okay. My home is armed in away mode. Side window, kitchen window, and one more sensor were bypassed. You have 60 seconds to exit.

If the user says "No", Alexa tells the user "Okay, I won’t arm the security system." If you don't include a list of endpoints in the payload of your BYPASS_NEEDED error response, Alexa tells the user "One or more sensors need bypassing. Please see your security system's panel or smartphone app for more details."

Disarming a security system

Users must opt in to the disarm by voice feature. Users do this in the Alexa app when they connect their device to Alexa. When a user opts-in, Alexa sends Disarm directives to your skill, otherwise it does not. When a user opts in, they set up a voice code in one of the following ways:

  • If your skill does not support existing PIN codes, the user must set up a new voice code.
  • If your skill supports existing PIN codes, the user can set up a new voice code or use their four-digit PIN codes that are already associated with the security system.

For users who set up a new voice code, the Alexa service stores the voice code securely and asks for it whenever the user disarms the security system with a voice request. Alexa validates the voice code and then, only when the voice code is correct, sends a Disarm directive to your skill.

For users who use existing PIN codes, Alexa asks for a PIN code whenever the user disarms the security system with a voice request. Your backend systems must validate the PIN code before you disarm the security system. When the PIN code is not valid, your skill must respond with an error of type UNAUTHORIZED. For more information, see

PIN code support

When your skill controls a security system that already uses four-digit PIN codes, and your backend system can validate PIN codes, your skill can allow users to disarm the security system by voice using their existing PIN codes.

Discovery

You describe endpoints that support Alexa.SecurityPanelController using the standard discovery mechanism described in Alexa.Discovery.

Set retrievable to true for the properties that you report when Alexa sends your skill a state report request. Set proactivelyReported to true for properties that you proactively report to Alexa in a change report. You should proactively report alarm conditions.

Identify the alarms that you support, such as burglary alarm and fire alarm, in the supported properties field. Support for alarms is optional. For more information, see alarm properties.

Use SECURITY_PANEL for the display category. For the full list of display categories, see display categories.

In addition to the usual discovery response fields, for SecurityPanelController, include a configuration object that contains the following fields.

Field Description Type Required
supportedAuthorizationTypes The authorization types that your security panel uses. Currently, the only valid type is FOUR_DIGIT_PIN. Include this field only when your skill controls a security system that supports four digit PIN codes and your backend systems can validate those PIN codes. An array of objects. No
supportedArmStates The states that the security system supports. If you don't include this field, Alexa assumes that the security system supports all states. An array of armState property values. No

Discover response example

The following example shows a Discover.Response message for a security panel that supports the Alexa.SecurityPanelController interface.

Copied to clipboard.

{
  "event": {
    "header": {
      "namespace": "Alexa.Discovery",
      "name": "Discover.Response",
      "payloadVersion": "3",
      "messageId": "<message id>"
    },
    "payload": {
      "endpoints": [
        {
          "endpointId": "<unique ID of the endpoint>",
          "manufacturerName": "<the manufacturer name of the endpoint>",
          "description": "<a description that is shown in the Alexa app>",
          "friendlyName": "<security panel name, displayed in the Alexa app>",
          "displayCategories": ["SECURITY_PANEL"],
          "cookie": {},
          "capabilities": [
            {
              "type": "AlexaInterface",
              "interface": "Alexa.SecurityPanelController",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "armState"
                  },
                  {
                    "name": "burglaryAlarm"
                  },
                  {
                    "name": "fireAlarm"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              },
              "configuration": {
                "supportedArmStates": [
                  {
                    "value": "ARMED_AWAY"
                  },
                  {
                    "value": "ARMED_STAY"
                  },
                  {
                    "value": "DISARMED"
                  }
                ],
                "supportedAuthorizationTypes": [
                  {
                    "type": "FOUR_DIGIT_PIN"
                  }
                ]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa.EndpointHealth",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name":"connectivity"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa",
              "version": "3"
            }
          ]
        }
      ]
    }
  }
}

Directives

Arm directive

Support the Arm directive so that users can arm their security system. If you receive an Arm directive, and the new armState matches the current armState, respond with a success response, not an error response. However, there are strict requirements for changing armState. For more information, see Security system considerations.

The following example shows a user utterance:

Alexa, arm my home in away mode.

Arm directive payload details

Field Description Type
armState The arm state to set for the endpoint. An armState value.
bypassType The type of bypass; currently BYPASS_ALL is the only possible value. This field is only included if applicable. For more information, see bypass by voice option. String

Arm directive example

The following example illustrates an Arm directive that Alexa sends to your skill.

{
  "directive": {
    "header": {
      "namespace": "Alexa.SecurityPanelController",
      "name": "Arm",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>",
      "cookie": {}
    },
    "payload": {
      "armState": "ARMED_AWAY"
    }
  }
}

Arm directive example with bypass

The following example illustrates an Arm directive that Alexa sends to your skill and includes a request to bypass.

{
  "directive": {
    "header": {
      "namespace": "Alexa.SecurityPanelController",
      "name": "Arm",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>",
      "cookie": {}
    },
    "payload": {
      "armState": "ARMED_AWAY",
      "bypassType": "BYPASS_ALL"
    }
  }
}

Arm response event

If you handle an Arm directive successfully, respond with an Arm.Response event. In the context object, include the values of all relevant properties, and any alarms that are active.

Arm.Response event payload details

Field Description Type Required
exitDelayInSeconds The number of seconds that the security system waits to allow the occupants to exit before it arms. For no delay, set this value to 0. An integer between 0 and 255. No
bypassedEndpoints The endpoints that were bypassed. Only include this field if the Arm directive included a bypass request. Include the endpointId for sensors that implement the Alexa.ContactSensor and Alexa.MotionSensor interfaces. For more information, see bypass by voice option. An array of endpoints. No

Arm.Response event example

Copied to clipboard.

{
  "event": {
    "header": {
      "namespace": "Alexa.SecurityPanelController",
      "name": "Arm.Response",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {
      "exitDelayInSeconds": 60
    }
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "armState",
        "value": "ARMED_AWAY",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.EndpointHealth",
        "name": "connectivity",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}

Arm.Response event example with active ALARM

Copied to clipboard.

{
  "event": {
    "header": {
      "namespace": "Alexa.SecurityPanelController",
      "name": "Arm.Response",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {
      "exitDelayInSeconds": 60
    }
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "burglaryAlarm",
        "value": {
          "value": "ALARM"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "armState",
        "value": "ARMED_AWAY",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.EndpointHealth",
        "name": "connectivity",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}

Arm.Response event example with bypassed endpoints

Copied to clipboard.

{
  "event": {
    "header": {
      "namespace": "Alexa.SecurityPanelController",
      "name": "Arm.Response",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {
      "exitDelayInSeconds": 60,
      "bypassedEndpoints": [
        {
          "friendlyName": "side window sensor", 
          "endpointId": "<endpoint id>"
        },
        {
          "friendlyName": "front door sensor", 
          "endpointId": "<endpoint id>"
        },
        {
          "friendlyName": "water sensor"
        }
      ]
    }
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "armState",
        "value": "ARMED_AWAY",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.EndpointHealth",
        "name": "connectivity",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}

Arm directive error handling

If you can't handle an Arm directive successfully, respond with an Alexa.SecurityPanelController.ErrorResponse event. If you can't handle an Arm directive successfully because one or more sensors is open, and you want users to be able to bypass the errors by voice, see bypass by voice option.

Disarm directive

Support the Disarm directive so that users can disarm their security system. If you receive a Disarm directive, and the system is already disarmed, respond with a success response, not an error response.

Alexa only sends Disarm directives to your skill if the user opts in to the disarm feature. For more information, see Security system considerations.

The following example shows a user utterance:

Alexa, disarm my home.

Disarm directive payload details

Field Description Type
authorization This property is only included when your skill supports existing PIN codes and the user chooses to use existing pin codes. You must validate the PIN before you disarm the security system. When the user disarms with an Alexa voice code, this property is not present. Object

Disarm directive example

The following example illustrates a Disarm directive that Alexa sends to your skill.

{
  "directive": {
    "header": {
      "namespace": "Alexa.SecurityPanelController",
      "name": "Disarm",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
          "type": "BearerToken",
          "token": "<an OAuth2 bearer token>"
        },
        "endpointId": "<endpoint id>",
      "cookie": {}
    },
    "payload": {
      "authorization": {
        "type": "FOUR_DIGIT_PIN",
        "value": "1234"
      }
    }
  }
}

Disarm response event

If you handle a Disarm directive successfully, respond with an Alexa.Response event. In the context object, include the values of all relevant properties, and any alarms that are active.

Disarm response event example

Copied to clipboard.

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "Response",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {}
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "armState",
        "value": "DISARMED",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.EndpointHealth",
        "name": "connectivity",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}

Disarm response event example with active ALARM

Copied to clipboard.

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "Response",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {}
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "burglaryAlarm",
        "value": {
          "value": "ALARM"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "armState",
        "value": "ARMED_AWAY",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.EndpointHealth",
        "name": "connectivity",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}

Disarm directive error handling

If you can't handle a Disarm directive successfully, respond with an Alexa.SecurityPanelController.ErrorResponse event.

State reporting

Support the ReportState directive so that users can ask about the status of their security panel.

The following examples show user utterances:

Alexa, is my home armed?

Alexa sends a ReportState directive to request information about the state of an endpoint. When Alexa sends a ReportState directive, you send a StateReport event in response. The response contains the current state of all retrievable properties in the context object. You identify your retrievable properties in your discovery response. For details about state reports, see Understand State and Change Reporting.

StateReport response event example

Copied to clipboard.

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "StateReport",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {}
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "armState",
        "value": "ARMED_AWAY",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "burglaryAlarm",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "fireAlarm",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.EndpointHealth",
        "name": "connectivity",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}

Change reporting

You send a ChangeReport event to proactively report changes in the state of an endpoint. You identify the properties that you proactively report in your discovery response. For details about change reports, see Understand State and Change Reporting.

You should proactively report alarm conditions for the alarms that you support.

ChangeReport event example

Copied to clipboard.

{  
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "ChangeReport",
      "messageId": "<message id>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {
      "change": {
        "cause": {
          "type": "PHYSICAL_INTERACTION"
        },
        "properties": [
          {
            "namespace": "Alexa.SecurityPanelController",
            "name": "armState",
            "value": "DISARMED",
            "timeOfSample": "2017-02-03T16:20:50.52Z",
            "uncertaintyInMilliseconds": 0
          }
        ]
      }
    }
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "burglaryAlarm",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "fireAlarm",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.EndpointHealth",
        "name": "connectivity",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}

ChangeReport event example with active ALARM

Copied to clipboard.

{  
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "ChangeReport",
      "messageId": "<message id>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>"
    },
    "payload": {
      "change": {
        "cause": {
          "type": "RULE_TRIGGER"
        },
        "properties": [
          {
            "namespace": "Alexa.SecurityPanelController",
            "name": "burglaryAlarm",
            "value": {
              "value": "ALARM"
            },
            "timeOfSample": "2017-02-03T16:20:50.52Z",
            "uncertaintyInMilliseconds": 0
          }
        ]
      }
    }
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "armState",
        "value": "ARMED_AWAY",
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.SecurityPanelController",
        "name": "fireAlarm",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      },
      {
        "namespace": "Alexa.EndpointHealth",
        "name": "connectivity",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}