Understand State and Change Reporting

When you create an Alexa skill that interacts with a smart home device, you can include support for state and change reporting. Alexa notifies users about the state of their devices by voice response or in the Alexa app. For example, in the Alexa app users can see a list of their smart plugs, and whether each plug is on or off.

You report state to Alexa in StateReport events, ChangeReport events, and Response events.

Identify support for state and change reporting during discovery

During device discovery, you indicate which Alexa interfaces you support in your skill. You indicate your support for state and change reporting for each interface. You specify state and change reporting by using the following properties in the json for your discover response event:

  • Retrievable — The retrievable property controls state reporting. When you set retrievable = true for an interface, Alexa can query your skill for the current state of the properties of that interface. Alexa sends a ReportState directive to your skill, and you respond with a StateReport event. The default value is false.

  • ProactivelyReported — The proactively reported property controls change reporting. When you set proactivelyReported = true for an interface, your skill sends a ChangeReport event to Alexa when any property of that interface changes. The default value is false.

Discover response example

The following example shows a Discover.Response message for an oven supports the Alexa.Cooking, Alexa.Cooking.TemperatureSensor, and Alexa.Cooking.TemperatureController interfaces. For more example discovery code, see the documentation for each interface that you support in your Alexa skill.

{
  "event": {
    "header": {
      "namespace": "Alexa.Discovery",
      "name": "Discover.Response",
      "payloadVersion": "3",
      "messageId": "<message id>"
    },
    "payload": {
      "endpoints": [
        {
          "endpointId": "<unique ID of the endpoint>",
          "manufacturerName": "Smart Cooking Device Company",
          "description": "Brand XYZ oven",
          "friendlyName": "Oven",
          "displayCategories": ["OVEN"],
          "additionalAttributes":  {
            "manufacturer" : "Smart Cooking Device Company",
            "model" : "Sample Model",
            "serialNumber": "U11112233456",
            "firmwareVersion" : "1.24.2546",
            "softwareVersion": "1.036",
            "customIdentifier": "Sample custom ID"
          },
          "cookie": {},
          "capabilities": [
            {
              "type": "AlexaInterface",
              "interface": "Alexa.Cooking",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "cookingMode"
                  },
                  {
                    "name": "foodItem"
                  },
                  {
                    "name": "cookingTimeInterval"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              },
              "configuration": {
                "supportedCookingModes": ["REHEAT", "DEFROST", "OFF"]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa.Cooking.TemperatureSensor",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "cookingTemperature"
                  }
                ],
                "proactivelyReported": false,
                "retrievable": true
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa.Cooking.TemperatureController",
              "version": "3",
              "properties": {
                "supported": [
                  {
                    "name": "targetCookingTemperature"
                  },
                  {
                    "name": "preheatTimeInterval"
                  }
                ],
                "proactivelyReported": true,
                "retrievable": true
              },
              "configuration": {
                "supportsRemoteStart": false,
                "supportedCookingModes": ["BAKE", "ROAST"]
              }
            },
            {
              "type": "AlexaInterface",
              "interface": "Alexa",
              "version": "3"
            }
          ]
        }
      ]
    }
  }
}

Report state in a StateReport

When Alexa sends a ReportState directive to request the state of an endpoint, you send a StateReport event in response. This response contains the current state of all the properties that are retrievable.

For example, a customer might check the Alexa app for the status of a light on a different floor of their house. Alexa sends a ReportState directive for the light. You send a response that includes the state of all the retrievable properties for the light, and the app reports the state to the customer.

If you poll your endpoints periodically, you can send cached values for the properties in your response. If the endpoint is currently unreachable, but all property values are cached, then return the StateReport and include all the property values. However, specify the value of the connectivity property of EndpointHealth as UNREACHABLE. If you can't report the state of all the properties because the endpoint is unreachable and you haven't cached the values, send an ErrorResponse of type BRIDGE_UNREACHABLE or ENDPOINT_UNREACHABLE.

ReportState directive

Example ReportState directive

The following example shows a ReportState directive that Alexa sends to your skill.

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

StateReport event

Example StateReport response event

The following example shows a StateReport event that your skill sends to Alexa. For more example StateReport code, see the documentation for each interface that you support in your Alexa skill.

{
  "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>",
      "cookie": {}
    },
    "payload": {}
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.ThermostatController",
        "name": "targetSetpoint",
        "value": {
          "value": 25.0,
          "scale": "CELSIUS"
        },
        "timeOfSample": "2017-02-03T16:20:50Z",
        "uncertaintyInMilliseconds": 6000
      },
      {
        "namespace": "Alexa.ThermostatController",
        "name": "thermostatMode",
        "value": "HEAT",
        "timeOfSample": "2017-02-03T16:20:50Z",
        "uncertaintyInMilliseconds": 6000
      },
      {
        "namespace": "Alexa.EndpointHealth",
        "name": "connectivity",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}

Report state in a ChangeReport

When the state of an endpoint changes for any reason, you report that change to Alexa in a ChangeReport event. Alexa can then provide that status change to the customer. In the change report, specify the state of any changed properties in the payload object. For example, if a customer manually turns on a light, send a change report event that indicates the powerState property of the Alexa.PowerController interface has changed its value to ON.

If a property is specified as proactivelyReported during discovery, you must send Alexa a ChangeReport event whenever that property value changes.

If a state change happens because of a directive from Alexa, you send both a directive response and a change report event. For more information, see Report state in response to a directive.

  • Use the payload of the ChangeReport to provide the new property value and the reason for the change.
  • You use the context of a ChangeReport to report the state of any additional properties.
  • If multiple properties have changed, you can send Alexa multiple change report events containing a payload with a single property, or a single change report event that contains a payload with multiple property values.
  • Make sure to identify the customer and the endpoint for the change report in the endpoint object.

In the context object, specify the state of all the other properties of the endpoint that didn't change, to help improve the customer experience.

ChangeReport event

Example ChangeReport event

The following example shows a ChangeReport event for an endpoint that implements the Alexa.PowerController and Alexa.BrightnessController interfaces. The event reports that the endpoint changed its brightness value to 85% due to a physical interaction with the device. The event specifies the new brightness value in the payload, and it specifies the powerState property in the context object because the value didn't change. For more example ChangeReport code, see the documentation for each interface that you support in your Alexa skill.

{
  "event": {
    "header": {
      "namespace": "Alexa",
      "name": "ChangeReport",
      "messageId": "<message id>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>",
      "cookie": {
        "path": "path/for/this/endpoint"
      }
    },
    "payload": {
      "change": {
        "cause": {
          "type": "PHYSICAL_INTERACTION"
        },
        "properties": [
          {
            "namespace": "Alexa.BrightnessController",
            "name": "brightness",
            "value": 85,
            "timeOfSample": "2017-02-03T16:20:50Z",
            "uncertaintyInMilliseconds": 0
          }
        ]
      }
    }
  },
  "context": {
    "properties": [
      {
        "namespace": "Alexa.PowerController",
        "name": "powerState",
        "value": "ON",
        "timeOfSample": "2017-02-03T16:20:50Z",
        "uncertaintyInMilliseconds": 60000
      },
      {
        "namespace": "Alexa.EndpointHealth",
        "name": "connectivity",
        "value": {
          "value": "OK"
        },
        "timeOfSample": "2017-02-03T16:20:50Z",
        "uncertaintyInMilliseconds": 0
      }
    ]
  }
}

Cause Object

When you send a ChangeReport event use the cause attribute to describe the cause of property value changes. The following table describes the cause values.

Cause Type Description
APP_INTERACTION Customer interaction with an app. For example, a customer switches on a light or locks a door by using the Alexa app or an app provided by a device vendor.
PERIODIC_POLL Periodic poll of an endpoint. For example, you might poll a temperature sensor every hour and send the updated temperature to Alexa.
PHYSICAL_INTERACTION Physical interaction with an endpoint. For example, the user turned on a light or locked a door lock manually.
RULE_TRIGGER A device rule. For example, a user configures a rule to switch on a light if a motion sensor detects motion. In this case, Alexa receives an event from the motion sensor, and another event from the light to indicate that its state change was caused by the rule.
VOICE_INTERACTION Voice interaction. For example, a user turns on a light by speaking to their Echo device.

Report state in a directive Response

If Alexa sends a directive to change the state of a property, and you handle the directive successfully, send a Response events. In the response, specify the state of any changed properties in the context object. For example, if Alexa sends an Alexa.PowerController.TurnOn directive, you send a response event that includes the powerState property, with its new value ON, in the context.

We recommend that you specify the state of all the properties of the endpoint, including the properties that didn't change, to help improve the customer experience.

You can send response events synchronously from your skill's Lambda function or asynchronously to the event gateway.

Example directive

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

{
  "directive": {
    "header": {
      "namespace": "Alexa.PercentageController",
      "name": "AdjustPercentage",
      "messageId": "<message id>",
      "correlationToken": "<an opaque correlation token>",
      "payloadVersion": "3"
    },
    "endpoint": {
      "scope": {
        "type": "BearerToken",
        "token": "<an OAuth2 bearer token>"
      },
      "endpointId": "<endpoint id>",
      "cookie": {}
    },
    "payload": {
      "percentageDelta": -20
    }
  }
}

Example response containing property state

The following example shows a response that your skill sends to Alexa.

{
  "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.PercentageController",
        "name": "percentage",
        "value": 54,
        "timeOfSample": "2017-02-03T16:20:50.52Z",
        "uncertaintyInMilliseconds": 500
      }
    ]
  }
}

Example response for a property that is not retrievable

After your skill successfully handles a directive for an endpoint with properties that aren't retrievable, the skill must send a response event that doesn't include the properties in the context.

The following example shows a Response event that indicates to Alexa that you handled the TurnOn directive successfully. The empty properties array in the event context indicates that you can't determine the property state after the change.

{
  "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": []
  }
}