

# AWS IoT Device Shadow service
<a name="iot-device-shadows"></a>

 The AWS IoT Device Shadow service adds shadows to AWS IoT thing objects. Shadows can make a device’s state available to apps and other services whether the device is connected to AWS IoT or not. AWS IoT thing objects can have multiple named shadows so that your IoT solution has more options for connecting your devices to other apps and services. 

AWS IoT thing objects don't have any shadows until they are created explicitly. Shadows can be created, updated, and deleted by using the AWS IoT console. Devices, other web clients, and services can create, update, and delete shadows by using MQTT and the [reserved MQTT topics](reserved-topics.md#reserved-topics-shadow), HTTP using the [Device Shadow REST API](device-shadow-rest-api.md), and the [AWS CLI for AWS IoT](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iot-data/index.html). Because shadows are stored by AWS in the cloud, they can collect and report device state data from apps and other cloud services whether the device is connected or not.

## Using shadows
<a name="device-shadow-using"></a>

Shadows provide a reliable data store for devices, apps, and other cloud services to share data. They enable devices, apps, and other cloud services to connect and disconnect without losing a device's state. 

While devices, apps, and other cloud services are connected to AWS IoT, they can access and control the current state of a device through its shadows. For example, an app can request a change in a device's state by updating a shadow. AWS IoT publishes a message that indicates the change to the device. The device receives this message, updates its state to match, and publishes a message with its updated state. The Device Shadow service reflects this updated state in the corresponding shadow. The app can subscribe to the shadow's update or it can query the shadow for its current state. 

When a device goes offline, an app can still communicate with AWS IoT and the device's shadows. When the device reconnects, it receives the current state of its shadows so that it can update its state to match that of its shadows, and then publish a message with its updated state. Likewise, when an app goes offline and the device state changes while it's offline, the device keeps the shadow updated so the app can query the shadows for its current state when it reconnects.

If your devices are frequently offline and you would like to configure your devices to receive delta messages after they reconnect, you can use the persistent session feature. For more information about the persistent session expiry period, see [Persistent session expiry period](https://docs.aws.amazon.com//general/latest/gr/iot-core.html#message-broker-limits). 

### Choosing to use named or unnamed shadows
<a name="iot-device-shadow-named"></a>

The Device Shadow service supports named and unnamed, or classic, shadows. A thing object can have multiple named shadows, and no more than one unnamed shadow. The thing object can also have a reserved named shadow, which operates similarly to a named shadow except that you can't update its name. For more information, see [Reserved named shadow](https://docs.aws.amazon.com/iot/latest/developerguide/preparing-to-use-software-package-catalog.html#reserved-named-shadow).

A thing object can have both named and unnamed shadows at the same time; however, the API used to access each is slightly different, so it might be more efficient to decide which type of shadow would work best for your solution and use that type only. For more information about the API to access the shadows, see [Shadow topics](reserved-topics.md#reserved-topics-shadow). 

With named shadows, you can create different views of a thing object’s state. For example, you could divide a thing object with many properties into shadows with logical groups of properties, each identified by its shadow name. You could also limit access to properties by grouping them into different shadows and using policies to control access. For more information about policies to use with device shadows, see [Actions, resources, and condition keys for AWS IoT](https://docs.aws.amazon.com//service-authorization/latest/reference/list_awsiot.html) and [AWS IoT Core policies](https://docs.aws.amazon.com//iot/latest/developerguide/iot-policies.html).

The classic, unnamed shadows are simpler, but somewhat more limited than the named shadows. Each AWS IoT thing object can have only one unnamed shadow. If you expect your IoT solution to have a limited need for shadow data, this might be how you want to get started using shadows. However, if you think you might want to add additional shadows in the future, consider using named shadows from the start.

Fleet indexing supports unnamed shadows and named shadows differently. For more information, see [Manage fleet indexing](managing-fleet-index.md).

### Accessing shadows
<a name="device-shadow-using-access"></a>

Every shadow has a reserved [MQTT topic](reserved-topics.md#reserved-topics-shadow) and [HTTP URL](device-shadow-rest-api.md) that supports the `get`, `update`, and `delete` actions on the shadow.

Shadows use [JSON shadow documents](device-shadow-document.md) to store and retrieve data. A shadow’s document contains a state property that describes these aspects of the device’s state:
+ `desired`

  Apps specify the desired states of device properties by updating the `desired` object.
+ `reported`

  Devices report their current state in the `reported` object.
+ `delta`

  AWS IoT reports differences between the desired and the reported state in the `delta` object.

The data stored in a shadow is determined by the state property of the update action's message body. Subsequent update actions can modify the values of an existing data object, and also add and delete keys and other elements in the shadow’s state object. For more information about accessing shadows, see [Using shadows in devices](device-shadow-comms-device.md) and [Using shadows in apps and services](device-shadow-comms-app.md).

**Important**  
Permission to make update requests should be limited to trusted apps and devices. This prevents the shadow's state property from being changed unexpectedly; otherwise, the devices and apps that use the shadow should be designed to expect the keys in the state property to change.

### Using shadows in devices, apps, and other cloud services
<a name="device-shadow-implementing"></a>

Using shadows in devices, apps, and other cloud services requires consistency and coordination between all of these. The AWS IoT Device Shadow service stores the shadow state, sends messages when the shadow state changes, and responds to messages that change its state. The devices, apps, and other cloud services in your IoT solution must manage their state and keep it consistent with the device shadow's state.

The shadow state data is dynamic and can be altered by the devices, apps, and other cloud services with permission to access the shadow. For this reason, it is important to consider how each device, app, and other cloud service will interact with the shadow. For example:
+ *Devices* should write only to the `reported` property of the shadow state when communicating state data to the shadow.
+ *Apps and other cloud services* should write only to the `desired` property when communicating state change requests to the device through the shadow.

**Important**  
The data contained in a shadow data object is independent from that of other shadows and other thing object properties, such as a thing’s attributes and the content of MQTT messages that a thing object's device might publish. A device can, however, report the same data in different MQTT topics and shadows if necessary.  
A device that supports multiple shadows must maintain the consistency of the data that it reports in the different shadows.

### Message order
<a name="message-ordering"></a>

There is no guarantee that messages from the AWS IoT service will arrive at the device in any specific order. The following scenario shows what happens in this case.

Initial state document:

```
{
  "state": {
    "reported": {
      "color": "blue"
    }
  },
  "version": 9,
  "timestamp": 123456776
}
```

Update 1:

```
{
  "state": {
    "desired": {
      "color": "RED"
    }
  },
  "version": 10,
  "timestamp": 123456777
}
```

Update 2:

```
{
  "state": {
    "desired": {
      "color": "GREEN"
    }
  },
  "version": 11,
  "timestamp": 123456778
}
```

Final state document:

```
{
  "state": {
    "reported": {
      "color": "GREEN"
    }
  },
  "version": 12,
  "timestamp": 123456779
}
```

This results in two delta messages:

```
{
  "state": {
    "color": "RED"
  },
  "version": 11,
  "timestamp": 123456778
}
```

```
{
  "state": {
    "color": "GREEN"
  },
  "version": 12,
  "timestamp": 123456779
}
```

The device might receive these messages out of order. Because the state in these messages is cumulative, a device can safely discard any messages that contain a version number older than the one it is tracking. If the device receives the delta for version 12 before version 11, it can safely discard the version 11 message.

### Trim shadow messages
<a name="device-shadow-trim-messages"></a>

To reduce the size of shadow messages sent to your device, define a rule that selects only the fields your device needs then republishes the message on an MQTT topic to which your device is listening.

The rule is specified in JSON and should look like the following: 

```
{
  "sql": "SELECT state, version FROM '$aws/things/+/shadow/update/delta'",
  "ruleDisabled": false,
  "actions": [
    {
      "republish": {
        "topic": "${topic(3)}/delta",
        "roleArn": "arn:aws:iam:123456789012:role/my-iot-role"
      }
    }
  ]
}
```

The SELECT statement determines which fields from the message will be republished to the specified topic. A "\$1" wild card is used to match all shadow names. The rule specifies that all matching messages should be republished to the specified topic. In this case, the `"topic()"` function is used to specify the topic on which to republish. `topic(3)` evaluates to the thing name in the original topic. For more information about creating rules, see [Rules for AWS IoT](iot-rules.md).

# Using shadows in devices
<a name="device-shadow-comms-device"></a>

This section describes device communications with shadows using MQTT messages, the preferred method for devices to communicate with the AWS IoT Device Shadow service.

Shadow communications emulate a request/response model using the publish/subscribe communication model of MQTT. Every shadow action consists of a request topic, a successful response topic (`accepted`), and an error response topic (`rejected`). 

If you want apps and services to be able to determine whether a device is connected, see [Detecting if a device is connected](device-shadow-comms-app.md#thing-connection).

**Important**  
Because MQTT uses a publish/subscribe communication model, you should subscribe to the response topics *before* you publish a request topic. If you don't, you might not receive the response to the request that you publish.   
If you use an [AWS IoT Device SDK](iot-sdks.md) to call the Device Shadow service APIs, this is handled for you.

The examples in this section use an abbreviated form of the topic where the *ShadowTopicPrefix* can refer to either a named or an unnamed shadow, as described in this table.

Shadows can be named or unnamed (classic). The topics used by each differ only in the topic prefix. This table shows the topic prefix used by each shadow type.


| *ShadowTopicPrefix* value | Shadow type | 
| --- | --- | 
| \$1aws/things/thingName/shadow | Unnamed (classic) shadow | 
| \$1aws/things/thingName/shadow/name/shadowName | Named shadow | 

**Important**  
Make sure that your app's or service's use of the shadows is consistent and supported by the corresponding implementations in your devices. For example, consider how shadows are created, updated, and deleted. Also consider how updates are handled in the device and the apps or services that access the device through a shadow. Your design should be clear about how the device's state is updated and reported and how your apps and services interact with the device and its shadows.

To create a complete topic, select the `ShadowTopicPrefix` for the type of shadow to which you want to refer, replace `thingName`, and `shadowName` if applicable, with their corresponding values, and then append that with the topic stub as shown in the following table. Remember that topics are case sensitive.

See [Shadow topics](reserved-topics.md#reserved-topics-shadow) for more information about the reserved topics for shadows.

## Initializing the device on first connection to AWS IoT
<a name="device-shadow-comms-device-first-connect"></a>

After a device registers with AWS IoT, it should subscribe to these MQTT messages for the shadows that it supports.


| Topic | Meaning | Action a device should take when this topic is received | 
| --- | --- | --- | 
|  `ShadowTopicPrefix/delete/accepted`  |  The `delete` request was accepted and AWS IoT deleted the shadow.   |  The actions necessary to accommodate the deleted shadow, such as stop publishing updates.  | 
|  `ShadowTopicPrefix/delete/rejected`  |  The `delete` request was rejected by AWS IoT and the shadow was not deleted. The message body contains the error information.   |  Respond to the error message in the message body.  | 
|  `ShadowTopicPrefix/get/accepted`  |  The `get` request was accepted by AWS IoT, and the message body contains the current shadow document.   |  The actions necessary to process the state document in the message body.  | 
|  `ShadowTopicPrefix/get/rejected`  |  The `get` request was rejected by AWS IoT, and the message body contains the error information.   |  Respond to the error message in the message body.  | 
|  `ShadowTopicPrefix/update/accepted`  |  The `update` request was accepted by AWS IoT, and the message body contains the current shadow document.   |  Confirm the updated data in the message body matches the device state.  | 
|  `ShadowTopicPrefix/update/rejected`  |  The `update` request was rejected by AWS IoT, and the message body contains the error information.   |  Respond to the error message in the message body.  | 
|  `ShadowTopicPrefix/update/delta`  |  The shadow document was updated by a request to AWS IoT, and the message body contains the changes requested.   |  Update the device's state to match the desired state in the message body.  | 
|  `ShadowTopicPrefix/update/documents`  |  An update to the shadow was recently completed, and the message body contains the current shadow document.   |  Confirm the updated state in the message body matches the device's state.  | 

After subscribing to the messages in the preceding table for each shadow, the device should test to see if the shadows that it supports have already been created by publishing a `/get` topic to each shadow. If a `/get/accepted` message is received, the message body contains the shadow document, which the device can use to initialize its state. If a `/get/rejected` message is received, the shadow should be created by publishing an `/update` message with the current device state.

For example, suppose you have a thing `My_IoT_Thing` which doesn't have any classic or named shadows. If you now publish a `/get` request on the reserved topic `$aws/things/My_IoT_Thing/shadow/get`, it returns an error on the `$aws/things/My_IoT_Thing/shadow/get/rejected` topic because the thing doesn't have any shadows. To resolve this error, first publish an `/update` message by using the `$aws/things/My_IoT_Thing/shadow/update` topic with the current device state such as the following payload.

```
{
	"state": {
		"reported": {
			"welcome": "aws-iot",
			"color": "yellow"
		}
	}
}
```

A classic shadow is now created for the thing and the message is published to the `$aws/things/My_IoT_Thing/shadow/update/accepted` topic. If you publish to the topic `$aws/things/My_IoT_Thing/shadow/get`, it returns a response to the `$aws/things/My_IoT_Thing/shadow/get/accepted` topic with the device state.

For named shadows, you must first create the named shadow or publish an update with the shadow name before using the get request. For example, to create a named shadow `namedShadow1`, first publish the device state information to the topic `$aws/things/My_IoT_Thing/shadow/name/namedShadow1/update`. To retrieve the state information, use the `/get` request for the named shadow, `$aws/things/My_IoT_Thing/shadow/name/namedShadow1/get`.

## Processing messages while the device is connected to AWS IoT
<a name="device-shadow-comms-device-while-connected"></a>

While a device is connected to AWS IoT, it can receive **/update/delta** messages and should keep the device state matched to the changes in its shadows by:

1. Reading all **/update/delta** messages received and synchronizing the device state to match.

1. Publishing an **/update** message with a `reported` message body that has the device’s current state, whenever the device's state changes.

While a device is connected, it should publish these messages when indicated.


| Indication | Topic | Payload | 
| --- | --- | --- | 
|  The device's state has changed.  |  `ShadowTopicPrefix/update`  |  A shadow document with the `reported` property.  | 
| The device might not be synchronized with the shadow. |  `ShadowTopicPrefix/get`  | (empty) | 
|  An action on the device indicates that a shadow will no longer be supported by the device, such as when the device is being removed or replaced.  |  `ShadowTopicPrefix/delete`  | (empty) | 

## Processing messages when the device reconnects to AWS IoT
<a name="device-shadow-comms-device-reconnect"></a>

When a device with one or more shadows connects to AWS IoT, it should synchronize its state with that of all the shadows that it supports by:

1. Reading all **/update/delta** messages received and synchronizing the device state to match.

1. Publishing an **/update** message with a `reported` message body that has the device’s current state.

# Using shadows in apps and services
<a name="device-shadow-comms-app"></a>

This section describes how an app or service interacts with the AWS IoT Device Shadow service. This example assumes the app or service is interacting only with the shadow and, through the shadow, the device. This example doesn't include any management actions, such as creating or deleting shadows. 

This example uses the AWS IoT Device Shadow service's REST API to interact with shadows. Unlike the example used in [Using shadows in devices](device-shadow-comms-device.md), which uses a publish/subscribe communications model, this example uses the request/response communications model of the REST API. This means the app or service must make a request before it can receive a response from AWS IoT. A disadvantage of this model, however, is that it does not support notifications. If your app or service requires timely notifications of device state changes, consider the MQTT or MQTT over WSS protocols, which support the publish/subscribe communication model, as described in [Using shadows in devices](device-shadow-comms-device.md).

**Important**  
Make sure that your app's or service's use of the shadows is consistent with and supported by the corresponding implementations in your devices. Consider, for example, how shadows are created, updated, and deleted, and how updates are handled in the device and the apps or services that access the shadow. Your design should clearly specify how the device's state is updated and reported, and how your apps and services interact with the device and its shadows.

The REST API's URL for a named shadows is:

```
https://endpoint/things/thingName/shadow?name=shadowName
```

and for an unnamed shadow:

```
https://endpoint/things/thingName/shadow
```

where:

endpoint  
The endpoint returned by the CLI command:  

```
aws iot describe-endpoint --endpoint-type IOT:Data-ATS
```

thingName  
The name of the thing object to which the shadow belongs

shadowName  
The name of the named shadow. This parameter is not used with unnamed shadows.

## Initializing the app or service on connection to AWS IoT
<a name="device-shadow-comms-app-first-connect"></a>

When the app first connects to AWS IoT, it should send an HTTP GET request to the URLs of the shadows it uses to get the current state of the shadows it's using. This allows it to sync the app or service to the shadow.

## Processing state changes while the app or service is connected to AWS IoT
<a name="device-shadow-comms-app-while-connected"></a>

While the app or service is connected to AWS IoT, it can query the current state periodically by sending an HTTP GET request on the URLs of the shadows it uses.

When an end user interacts with the app or service to change the state of the device, the app or service can send an HTTP POST request to the URLs of the shadows it uses to update the `desired` state of the shadow. This request returns the change that was accepted, but you might have to poll the shadow by making HTTP GET requests until the device has updated the shadow with its new state.

## Detecting if a device is connected
<a name="thing-connection"></a>

To determine if a device is currently connected, include a `connected` property in the shadow document and use an MQTT Last Will and Testament (LWT) message to set the `connected` property to `false` if a device is disconnected due to an error.

**Note**  
MQTT LWT messages sent to AWS IoT reserved topics (topics that begin with \$1) are ignored by the AWS IoT Device Shadow service. However, they are processed by subscribed clients and by the AWS IoT rules engine, so you will need to create an LWT message that is sent to a non-reserved topic and a rule that republishes the MQTT LWT message as a shadow update message to the shadow's reserved update topic, `ShadowTopicPrefix/update`. 

**To send the Device Shadow service an LWT message**

1. Create a rule that republishes the MQTT LWT message on the reserved topic. The following example is a rule that listens for messages on the `my/things/myLightBulb/update` topic and republishes it to `$aws/things/myLightBulb/shadow/update`.

   ```
   {
       "rule": {
       "ruleDisabled": false,
       "sql": "SELECT * FROM 'my/things/myLightBulb/update'",
       "description": "Turn my/things/ into $aws/things/",
       "actions": [
           {
           "republish": {
               "topic": "$$aws/things/myLightBulb/shadow/update",
               "roleArn": "arn:aws:iam:123456789012:role/aws_iot_republish"
               }
           }
        ]
      }
   }
   ```

1. When the device connects to AWS IoT, it registers an LWT message to a non-reserved topic for the republish rule to recognize. In this example, that topic is `my/things/myLightBulb/update` and it sets the connected property to `false`.

   ```
   {
       "state": {        
           "reported": {
               "connected":"false"
           }
       }
   }
   ```

1. After connecting, the device publishes a message on its shadow update topic, `$aws/things/myLightBulb/shadow/update`, to report its current state, which includes setting its `connected` property to `true`.

   ```
   {
        "state": {        
           "reported": {
               "connected":"true"
           }
       }
   }
   ```

1. Before the device disconnects gracefully, it publishes a message on its shadow update topic, `$aws/things/myLightBulb/shadow/update`, to report its latest state, which include setting its `connected` property to `false`.

   ```
   {
       "state": {        
           "reported": {
               "connected":"false"
           }
       }
   }
   ```

1. If the device disconnects due to an error, the AWS IoT message broker publishes the device's LWT message on behalf of the device. The republish rule detects this message and publishes the shadow update message to update the `connected` property of the device shadow.

**Note**  
Due to the asynchronous nature of disconnect processing, LWT messages are not guaranteed to be dispatched in order during reconnection. We recommend that you use [lifecycle events](life-cycle-events.md) to improve the accuracy of connectivity state detection, as these events provide attributes to manage out-of-order events.

# Simulating Device Shadow service communications
<a name="using-device-shadows"></a>

This topic demonstrates how the Device Shadow service acts as an intermediary and allows devices and apps to use a shadow to update, store, and retrieve a device's state.

To demonstrate the interaction described in this topic, and to explore it further, you'll need an AWS account and a system on which you can run the AWS CLI. If you don't have these, you can still see the interaction in the code examples.

In this example, the AWS IoT console represents the device. The AWS CLI represents the app or service that accesses the device by way of the shadow. The AWS CLI interface is very similar to the API that an app might use to communicate with AWS IoT. The device in this example is a smart light bulb and the app displays the light bulb's state and can change the light bulb's state.

## Setting up the simulation
<a name="using-device-shadows-setup"></a>

These procedures initialize the simulation by opening the [AWS IoT console](https://console.aws.amazon.com/iot/home), which simulates your device, and the command line window that simulates your app.

**To set up your simulation environment**

1. You'll need an AWS account to run the examples from this topic on your own. If you don't have an AWS account, create one, as described in [Set up AWS account](setting-up.md).

1. Open the [AWS IoT console](https://console.aws.amazon.com/iot/home), and in the left menu, choose **Test** to open the **MQTT client**.

1. In another window, open a terminal window on a system that has the AWS CLI installed on it.

You should have two windows open: one with the AWS IoT console on the **Test** page, and one with a command line prompt.

## Initialize the device
<a name="using-device-shadows-init-device"></a>

In this simulation, we'll be working with a thing object named, *mySimulatedThing*, and its shadow named, *simShadow1*. 

**Create thing object and its IoT policy**  
To create a thing object, in the **AWS IoT Console**:

1. Choose **Manage** and then choose **Things**. 

1. Click the **Create** button if things are listed otherwise click **Register a single thing** to create a single AWS IoT thing. 

1. Enter the name `mySimulatedThing`, leave other settings to default, and then click **Next**.

1. Use one-click certificate creation to generate the certificates that will authenticate the device's connection to AWS IoT. Click **Activate** to activate the certificate.

1. You can attach the policy `My_IoT_Policy` that would give the device permission to publish and subscribe to the MQTT reserved topics. For more detailed steps about how to create an AWS IoT thing and how to create this policy, see [Create a thing object](create-iot-resources.md#create-aws-thing).

**Create named shadow for the thing object**  
You can create a named shadow for a thing by publishing an update request to the topic `$aws/things/mySimulatedThing/shadow/name/simShadow1/update` as described below.

Or, to create a named shadow:

1. In the **AWS IoT Console**, choose your thing object in the list of things displayed and then choose **Shadows**.

1. Choose **Add a shadow**, enter the name `simShadow1`, and then choose **Create** to add the named shadow.

**Subscribe and publish to reserved MQTT topics**  
In the console, subscribe to the reserved MQTT shadow topics. These topics are the responses to the `get`, `update`, and `delete` actions so that your device will be ready to receive the responses after it publishes an action. 

**To subscribe to an MQTT topic in the **MQTT client****

1. In the **MQTT client**, choose **Subscribe to a topic**.

1. Enter the `get`, `update`, and `delete` topics to subscribe to. Copy one topic at a time from the following list, paste it in the **Topic filter** field, and then click **Subscribe**. You should see the topics appear under **Subscriptions**.
   + `$aws/things/mySimulatedThing/shadow/name/simShadow1/delete/accepted`
   + `$aws/things/mySimulatedThing/shadow/name/simShadow1/delete/rejected`
   + `$aws/things/mySimulatedThing/shadow/name/simShadow1/get/accepted`
   + `$aws/things/mySimulatedThing/shadow/name/simShadow1/get/rejected`
   + `$aws/things/mySimulatedThing/shadow/name/simShadow1/update/accepted`
   + `$aws/things/mySimulatedThing/shadow/name/simShadow1/update/rejected`
   + `$aws/things/mySimulatedThing/shadow/name/simShadow1/update/delta`
   + `$aws/things/mySimulatedThing/shadow/name/simShadow1/update/documents`

   At this point, your simulated device is ready to receive the topics as they are published by AWS IoT.

**To publish to an MQTT topic in the **MQTT client****  
After a device has initialized itself and subscribed to the response topics, it should query for the shadows it supports. This simulation supports only one shadow, the shadow that supports a thing object named, *mySimulatedThing*, named, *simShadow1*.

**To get the current shadow state from the **MQTT client****

1. In the **MQTT client**, choose **Publish to a topic**.

1. Under **Publish**, enter the following topic and delete any content from the message body window below where you entered the topic to get. You can then choose **Publish to topic** to publish the request. `$aws/things/mySimulatedThing/shadow/name/simShadow1/get`.

   If you haven't created the named shadow, `simShadow1`, you receive a message in the `$aws/things/mySimulatedThing/shadow/name/simShadow1/get/rejected` topic and the `code` is `404`, such as in this example as the shadow has not been created, so we'll create it next.

   ```
   {
     "code": 404,
     "message": "No shadow exists with name: 'simShadow1'"
   }
   ```

**To create a shadow with the current status of the device**

1. In the **MQTT client**, choose **Publish to a topic** and enter this topic:

   ```
   $aws/things/mySimulatedThing/shadow/name/simShadow1/update
   ```

1. In the message body window below where you entered the topic, enter this shadow document to show the device is reporting its ID and its current color in RGB values. Choose **Publish** to publish the request.

   ```
   {
     "state": {
       "reported": {
         "ID": "SmartLamp21",
         "ColorRGB": [
           128,
           128,
           128
         ]
       }
     },
     "clientToken": "426bfd96-e720-46d3-95cd-014e3ef12bb6"
   }
   ```

If you receive a message in the topic: 
+ `$aws/things/mySimulatedThing/shadow/name/simShadow1/update/accepted`: It means that the shadow was created and the message body contains the current shadow document.
+ `$aws/things/mySimulatedThing/shadow/name/simShadow1/update/rejected`: Review the error in the message body.
+ `$aws/things/mySimulatedThing/shadow/name/simShadow1/get/accepted`: The shadow already exists and the message body has the current shadow state, such as in this example. With this, you could set your device or confirm that it matches the shadow state.

  ```
  {
    "state": {
      "reported": {
        "ID": "SmartLamp21",
        "ColorRGB": [
          128,
          128,
          128
        ]
      }
    },
    "metadata": {
      "reported": {
        "ID": {
          "timestamp": 1591140517
        },
        "ColorRGB": [
          {
            "timestamp": 1591140517
          },
          {
            "timestamp": 1591140517
          },
          {
            "timestamp": 1591140517
          }
        ]
      }
    },
    "version": 3,
    "timestamp": 1591140517,
    "clientToken": "426bfd96-e720-46d3-95cd-014e3ef12bb6"
  }
  ```

## Send an update from the app
<a name="using-device-shadows-app-update"></a>

This section uses the AWS CLI to demonstrate how an app can interact with a shadow.

**To get the current state of the shadow using the AWS CLI**  
From the command line, enter this command.

```
aws iot-data get-thing-shadow --thing-name mySimulatedThing --shadow-name simShadow1 /dev/stdout
```

On Windows platforms, you can use `con` instead of `/dev/stdout`.

```
aws iot-data get-thing-shadow --thing-name mySimulatedThing --shadow-name simShadow1 con
```

Because the shadow exists and had been initialized by the device to reflect its current state, it should return the following shadow document.

```
{
  "state": {
    "reported": {
      "ID": "SmartLamp21",
      "ColorRGB": [
        128,
        128,
        128
      ]
    }
  },
  "metadata": {
    "reported": {
      "ID": {
        "timestamp": 1591140517
      },
      "ColorRGB": [
        {
          "timestamp": 1591140517
        },
        {
          "timestamp": 1591140517
        },
        {
          "timestamp": 1591140517
        }
      ]
    }
  },
  "version": 3,
  "timestamp": 1591141111
}
```

The app can use this response to initialize its representation of the device state.

If the app updates the state, such as when an end user changes the color of our smart light bulb to yellow, the app would send an **update-thing-shadow** command. This command corresponds to the `UpdateThingShadow` REST API.

**To update a shadow from an app**  
From the command line, enter this command.

------
#### [ AWS CLI v2.x ]

```
aws iot-data update-thing-shadow --thing-name mySimulatedThing --shadow-name simShadow1 \
    --cli-binary-format raw-in-base64-out \
    --payload '{"state":{"desired":{"ColorRGB":[255,255,0]}},"clientToken":"21b21b21-bfd2-4279-8c65-e2f697ff4fab"}' /dev/stdout
```

------
#### [ AWS CLI v1.x ]

```
aws iot-data update-thing-shadow --thing-name mySimulatedThing --shadow-name simShadow1 \
    --payload '{"state":{"desired":{"ColorRGB":[255,255,0]}},"clientToken":"21b21b21-bfd2-4279-8c65-e2f697ff4fab"}' /dev/stdout
```

------

If successful, this command should return the following shadow document.

```
{
  "state": {
    "desired": {
      "ColorRGB": [
        255,
        255,
        0
      ]
    }
  },
  "metadata": {
    "desired": {
      "ColorRGB": [
        {
          "timestamp": 1591141596
        },
        {
          "timestamp": 1591141596
        },
        {
          "timestamp": 1591141596
        }
      ]
    }
  },
  "version": 4,
  "timestamp": 1591141596,
  "clientToken": "21b21b21-bfd2-4279-8c65-e2f697ff4fab"
}
```

## Respond to update in device
<a name="using-device-shadows-device-update"></a>

Returning to the **MQTT client** in the AWS console, you should see the messages that AWS IoT published to reflect the update command issued in the previous section.

**To view the update messages in the **MQTT client****  
In the **MQTT client**, choose **\$1aws/things/mySimulatedThing/shadow/name/simShadow1/update/delta** in the **Subscriptions** column. If the topic name is truncated, you can pause on it to see the full topic. In the topic log of this topic, you should see a `/delta` message similar to this one.

```
{
  "version": 4,
  "timestamp": 1591141596,
  "state": {
    "ColorRGB": [
      255,
      255,
      0
    ]
  },
  "metadata": {
    "ColorRGB": [
      {
        "timestamp": 1591141596
      },
      {
        "timestamp": 1591141596
      },
      {
        "timestamp": 1591141596
      }
    ]
  },
  "clientToken": "21b21b21-bfd2-4279-8c65-e2f697ff4fab"
}
```

Your device would process the contents of this message to set the device state to match the `desired` state in the message.

After the device updates the state to match the `desired` state in the message, it must send the new reported state back to AWS IoT by publishing an update message. This procedure simulates this in the **MQTT client**.

**To update the shadow from the device**

1. In the **MQTT client**, choose **Publish to a topic**.

1. In the message body window , in the topic field above the message body window, enter the shadow's topic followed by the `/update` action: `$aws/things/mySimulatedThing/shadow/name/simShadow1/update` and in the message body, enter this updated shadow document, which describes the current state of the device. Click **Publish** to publish the updated device state.

   ```
   {
     "state": {
       "reported": {
         "ColorRGB": [255,255,0]
         }
     },
     "clientToken": "a4dc2227-9213-4c6a-a6a5-053304f60258"
   }
   ```

   If the message was successfully received by AWS IoT, you should see a new response in the **\$1aws/things/mySimulatedThing/shadow/name/simShadow1/update/accepted** message log in the **MQTT client** with the current state of the shadow, such as this example.

   ```
   {
     "state": {
       "reported": {
         "ColorRGB": [
           255,
           255,
           0
         ]
       }
     },
     "metadata": {
       "reported": {
         "ColorRGB": [
           {
             "timestamp": 1591142747
           },
           {
             "timestamp": 1591142747
           },
           {
             "timestamp": 1591142747
           }
         ]
       }
     },
     "version": 5,
     "timestamp": 1591142747,
     "clientToken": "a4dc2227-9213-4c6a-a6a5-053304f60258"
   }
   ```

A successful update to the reported state of the device also causes AWS IoT to send a comprehensive description of the shadow state in a message to the `update/documents` topic, such as this message body that resulted from the shadow update performed by the device in the preceding procedure.

```
{
  "previous": {
    "state": {
      "desired": {
        "ColorRGB": [
          255,
          255,
          0
        ]
      },
      "reported": {
        "ID": "SmartLamp21",
        "ColorRGB": [
          128,
          128,
          128
        ]
      }
    },
    "metadata": {
      "desired": {
        "ColorRGB": [
          {
            "timestamp": 1591141596
          },
          {
            "timestamp": 1591141596
          },
          {
            "timestamp": 1591141596
          }
        ]
      },
      "reported": {
        "ID": {
          "timestamp": 1591140517
        },
        "ColorRGB": [
          {
            "timestamp": 1591140517
          },
          {
            "timestamp": 1591140517
          },
          {
            "timestamp": 1591140517
          }
        ]
      }
    },
    "version": 4
  },
  "current": {
    "state": {
      "desired": {
        "ColorRGB": [
          255,
          255,
          0
        ]
      },
      "reported": {
        "ID": "SmartLamp21",
        "ColorRGB": [
          255,
          255,
          0
        ]
      }
    },
    "metadata": {
      "desired": {
        "ColorRGB": [
          {
            "timestamp": 1591141596
          },
          {
            "timestamp": 1591141596
          },
          {
            "timestamp": 1591141596
          }
        ]
      },
      "reported": {
        "ID": {
          "timestamp": 1591140517
        },
        "ColorRGB": [
          {
            "timestamp": 1591142747
          },
          {
            "timestamp": 1591142747
          },
          {
            "timestamp": 1591142747
          }
        ]
      }
    },
    "version": 5
  },
  "timestamp": 1591142747,
  "clientToken": "a4dc2227-9213-4c6a-a6a5-053304f60258"
}
```

## Observe the update in the app
<a name="using-device-shadows-view-result"></a>

The app can now query the shadow for the current state as reported by the device.

**To get the current state of the shadow using the AWS CLI**

1. From the command line, enter this command.

   ```
   aws iot-data get-thing-shadow --thing-name mySimulatedThing --shadow-name simShadow1 /dev/stdout
   ```

   On Windows platforms, you can use `con` instead of `/dev/stdout`.

   ```
   aws iot-data get-thing-shadow --thing-name mySimulatedThing --shadow-name simShadow1 con
   ```

1. Because the shadow has just been updated by the device to reflect its current state, it should return the following shadow document.

   ```
   {
     "state": {
       "desired": {
         "ColorRGB": [
           255,
           255,
           0
         ]
       },
       "reported": {
         "ID": "SmartLamp21",
         "ColorRGB": [
           255,
           255,
           0
         ]
       }
     },
     "metadata": {
       "desired": {
         "ColorRGB": [
           {
             "timestamp": 1591141596
           },
           {
             "timestamp": 1591141596
           },
           {
             "timestamp": 1591141596
           }
         ]
       },
       "reported": {
         "ID": {
           "timestamp": 1591140517
         },
         "ColorRGB": [
           {
             "timestamp": 1591142747
           },
           {
             "timestamp": 1591142747
           },
           {
             "timestamp": 1591142747
           }
         ]
       }
     },
     "version": 5,
     "timestamp": 1591143269
   }
   ```

## Going beyond the simulation
<a name="using-device-shadows-next-steps"></a>

Experiment with the interaction between the AWS CLI (representing the app) and the console (representing the device) to model your IoT solution.

# Interacting with shadows
<a name="device-shadow-data-flow"></a>

This topic describes the messages associated with each of the three methods that AWS IoT provides for working with shadows. These methods include the following:

`UPDATE`  <a name="update"></a>
Creates a shadow if it doesn't exist, or updates the contents of an existing shadow with the state information provided in the message body. AWS IoT records a timestamp with each update to indicate when the state was last updated. When the shadow's state changes, AWS IoT sends `/delta` messages to all MQTT subscribers with the difference between the `desired` and the `reported` states. Devices or apps that receive a `/delta` message can perform actions based on the difference. For example, a device can update its state to the desired state, or an app can update its UI to reflect the device's state change.

`GET`  <a name="get"></a>
Retrieves a current shadow document that contains the complete state of the shadow, including metadata.

`DELETE`  <a name="delete"></a>
Deletes the device shadow and its content.  
You can't restore a deleted device shadow document, but you can create a new device shadow with the name of a deleted device shadow document. If you create a device shadow document that has the same name as one that was deleted within the past 48 hours, the version number of the new device shadow document will follow that of the deleted one. If a device shadow document has been deleted for more than 48 hours, the version number of a new device shadow document with the same name will be 0.

## Protocol support
<a name="protocol-support"></a>

AWS IoT supports [MQTT](http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/mqtt-v3.1.1.html) and a REST API over HTTPS protocols to interact with shadows. AWS IoT provides a set of reserved request and response topics for MQTT publish and subscribe actions. Devices and apps should subscribe to the response topics before publishing to a request topic for information about how AWS IoT handled the request. For more information, see [Device Shadow MQTT topics](device-shadow-mqtt.md) and [Device Shadow REST API](device-shadow-rest-api.md).

## Requesting and reporting state
<a name="shadow-reporting-state"></a>

When designing your IoT solution using AWS IoT and shadows, you should determine the apps or devices that will request changes and those that will implement them. Typically, a device implements and reports changes back to the shadow and apps and services respond to and request changes in the shadow. Your solution could be different, but the examples in this topic assume that the client app or service requests changes in the shadow and the device performs the changes and reports them back to the shadow.

## Updating a shadow
<a name="update-device-shadow"></a>

Your app or service can update a shadow's state by using the [UpdateThingShadow](device-shadow-rest-api.md#API_UpdateThingShadow) API or by publishing to the [/update](device-shadow-mqtt.md#update-pub-sub-topic) topic. Updates affect only the fields specified in the request.

### Updating a shadow when a client requests a state change
<a name="update-pub-sub-topic-client"></a>

**When a client requests a state change in a shadow by using the MQTT protocol**

1. The client should have a current shadow document so that it can identify the properties to change. See the /get action for how to obtain the current shadow document.

1. The client subscribes to these MQTT topics:
   + `$aws/things/thingName/shadow/name/shadowName/update/accepted`
   + `$aws/things/thingName/shadow/name/shadowName/update/rejected`
   + `$aws/things/thingName/shadow/name/shadowName/update/delta`
   + `$aws/things/thingName/shadow/name/shadowName/update/documents`

1. The client publishes a `$aws/things/thingName/shadow/name/shadowName/update` request topic with a state document that contains the desired state of the shadow. Only the properties to change need to be included in the document. This is an example of a document with the desired state.

   ```
   {
     "state": {
       "desired": {
         "color": {
           "r": 10
         },
         "engine": "ON"
       }
     }
   }
   ```

1. If the update request is valid, AWS IoT updates the desired state in the shadow and publishes messages on these topics:
   + `$aws/things/thingName/shadow/name/shadowName/update/accepted`
   + `$aws/things/thingName/shadow/name/shadowName/update/delta`

   The `/update/accepted` message contains an [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) shadow document, and the `/update/delta` message contains a [/delta response state document](device-shadow-document.md#device-shadow-example-response-json-delta) shadow document. 

1. If the update request is not valid, AWS IoT publishes a message with the `$aws/things/thingName/shadow/name/shadowName/update/rejected` topic with an [Error response document](device-shadow-document.md#device-shadow-example-error-json) shadow document that describes the error.

**When a client requests a state change in a shadow by using the API**

1. The client calls the `UpdateThingShadow` API with a [Request state document](device-shadow-document.md#device-shadow-example-request-json) state document as its message body.

1. If the request was valid, AWS IoT returns an HTTP success response code and an [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) shadow document as its response message body.

   AWS IoT will also publish an MQTT message to the `$aws/things/thingName/shadow/name/shadowName/update/delta` topic with a [/delta response state document](device-shadow-document.md#device-shadow-example-response-json-delta) shadow document for any devices or clients that subscribe to it.

1. If the request was not valid, AWS IoT returns an HTTP error response code an [Error response document](device-shadow-document.md#device-shadow-example-error-json) as its response message body.

When the device receives the `/desired` state on the `/update/delta` topic, it makes the desired changes in the device. It then sends a message to the `/update` topic to report its current state to the shadow. 

### Updating a shadow when a device reports its current state
<a name="update-pub-sub-topic-device"></a>

**When a device reports its current state to the shadow by using the MQTT protocol**

1. The device should subscribe to these MQTT topics before updating the shadow:
   + `$aws/things/thingName/shadow/name/shadowName/update/accepted`
   + `$aws/things/thingName/shadow/name/shadowName/update/rejected`
   + `$aws/things/thingName/shadow/name/shadowName/update/delta`
   + `$aws/things/thingName/shadow/name/shadowName/update/documents`

1. The device reports its current state by publishing a message to the `$aws/things/thingName/shadow/name/shadowName/update` topic that reports the current state, such as in this example.

   ```
   {
       "state": {
           "reported" : {
               "color" : { "r" : 10 },
               "engine" : "ON"
           }
       }
   }
   ```

1. If AWS IoT accepts the update, it publishes a message to the `$aws/things/thingName/shadow/name/shadowName/update/accepted` topics with an [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) shadow document.

1. If the update request is not valid, AWS IoT publishes a message with the `$aws/things/thingName/shadow/name/shadowName/update/rejected` topic with an [Error response document](device-shadow-document.md#device-shadow-example-error-json) shadow document that describes the error.

**When a device reports its current state to the shadow by using the API**

1. The device calls the `UpdateThingShadow` API with a [Request state document](device-shadow-document.md#device-shadow-example-request-json) state document as its message body.

1. If the request was valid, AWS IoT updates the shadow and returns an HTTP success response code with an [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) shadow document as its response message body.

   AWS IoT will also publish an MQTT message to the `$aws/things/thingName/shadow/name/shadowName/update/delta` topic with a [/delta response state document](device-shadow-document.md#device-shadow-example-response-json-delta) shadow document for any devices or clients that subscribe to it.

1. If the request was not valid, AWS IoT returns an HTTP error response code an [Error response document](device-shadow-document.md#device-shadow-example-error-json) as its response message body.

### Optimistic locking
<a name="optimistic-locking"></a>

You can use the state document version to ensure you are updating the most recent version of a device's shadow document. When you supply a version with an update request, the service rejects the request with an HTTP 409 conflict response code if the current version of the state document does not match the version supplied. The conflict response code can also occur on any API that modifies `ThingShadow`, including `DeleteThingShadow`.

For example:

Initial document:

```
{
  "state": {
    "desired": {
      "colors": [
        "RED",
        "GREEN",
        "BLUE"
      ]
    }
  },
  "version": 10
}
```

Update: (version doesn't match; this request will be rejected)

```
{
  "state": {
    "desired": {
      "colors": [
        "BLUE"
      ]
    }
  },
  "version": 9
}
```

Result:

```
{
  "code": 409,
  "message": "Version conflict",
  "clientToken": "426bfd96-e720-46d3-95cd-014e3ef12bb6"
}
```

Update: (version matches; this request will be accepted)

```
{
  "state": {
    "desired": {
      "colors": [
        "BLUE"
      ]
    }
  },
  "version": 10
}
```

Final state:

```
{
  "state": {
    "desired": {
      "colors": [
        "BLUE"
      ]
    }
  },
  "version": 11
}
```

## Retrieving a shadow document
<a name="retrieving-device-shadow"></a>

You can retrieve a shadow document by using the [GetThingShadow](device-shadow-rest-api.md#API_GetThingShadow) API or by subscribing and publishing to the [/get](device-shadow-mqtt.md#get-pub-sub-topic) topic. This retrieves a complete shadow document, including any delta between the `desired` and `reported` states. The procedure for this task is the same whether the device or a client is making the request.

**To retrieve a shadow document by using the MQTT protocol**

1. The device or client should subscribe to these MQTT topics before updating the shadow:
   + `$aws/things/thingName/shadow/name/shadowName/get/accepted`
   + `$aws/things/thingName/shadow/name/shadowName/get/rejected`

1. The device or client publishes a message to the `$aws/things/thingName/shadow/name/shadowName/get` topic with an empty message body.

1. If the request is successful, AWS IoT publishes a message to the `$aws/things/thingName/shadow/name/shadowName/get/accepted` topic with a [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) in the message body.

1. If the request was not valid, AWS IoT publishes a message to the `$aws/things/thingName/shadow/name/shadowName/get/rejected` topic with an [Error response document](device-shadow-document.md#device-shadow-example-error-json) in the message body.

**To retrieve a shadow document by using a REST API**

1. The device or client call the `GetThingShadow` API with an empty message body.

1. If the request is valid, AWS IoT returns an HTTP success response code with an [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) shadow document as its response message body.

1. If the request is not valid, AWS IoT returns an HTTP error response code an [Error response document](device-shadow-document.md#device-shadow-example-error-json) as its response message body.

## Deleting shadow data
<a name="deleting-thing-data"></a>

There are two ways to delete shadow data: you can delete specific properties in the shadow document and you can delete the shadow completely.
+ To delete specific properties from a shadow, update the shadow; however set the value of the properties that you want to delete to `null`. Fields with a value of `null` are removed from the shadow document.
+ To delete the entire shadow, use the [DeleteThingShadow](device-shadow-rest-api.md#API_DeleteThingShadow) API or publish to the [/delete](device-shadow-mqtt.md#delete-pub-sub-topic) topic.

**Note**  
Deleting a shadow doesn't reset its version number to zero at once. It will be reset to zero after 48 hours.

### Deleting a property from a shadow document
<a name="deleting-shadow-property"></a>

**To delete a property from a shadow by using the MQTT protocol**

1. The device or client should have a current shadow document so that it can identify the properties to change. See [Retrieving a shadow document](#retrieving-device-shadow) for information on how to obtain the current shadow document.

1. The device or client subscribes to these MQTT topics:
   + `$aws/things/thingName/shadow/name/shadowName/update/accepted`
   + `$aws/things/thingName/shadow/name/shadowName/update/rejected`

1. The device or client publishes a `$aws/things/thingName/shadow/name/shadowName/update` request topic with a state document that assigns `null` values to the properties of the shadow to delete. Only the properties to change need to be included in the document. This is an example of a document that deletes the `engine` property.

   ```
   {
     "state": {
       "desired": {
         "engine": null
       }
     }
   }
   ```

1. If the update request is valid, AWS IoT deletes the specified properties in the shadow and publishes a messages with the `$aws/things/thingName/shadow/name/shadowName/update/accepted` topic with an [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) shadow document in the message body. 

1. If the update request is not valid, AWS IoT publishes a message with the `$aws/things/thingName/shadow/name/shadowName/update/rejected` topic with an [Error response document](device-shadow-document.md#device-shadow-example-error-json) shadow document that describes the error.

**To delete a property from a shadow by using the REST API**

1. The device or client calls the `UpdateThingShadow` API with a [Request state document](device-shadow-document.md#device-shadow-example-request-json) that assigns `null` values to the properties of the shadow to delete. Include only the properties that you want to delete in the document. This is an example of a document that deletes the `engine` property.

   ```
   {
     "state": {
       "desired": {
         "engine": null
       }
     }
   }
   ```

1. If the request was valid, AWS IoT returns an HTTP success response code and an [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) shadow document as its response message body.

1. If the request was not valid, AWS IoT returns an HTTP error response code an [Error response document](device-shadow-document.md#device-shadow-example-error-json) as its response message body.

### Deleting a shadow
<a name="deleting-device-shadow"></a>

Following are some considerations when deleting a device's shadow.
+ Setting the device's shadow state to `null` does not delete the shadow. The shadow version will be incremented on the next update.
+ Deleting a device's shadow does not delete the thing object. Deleting a thing object does not delete the corresponding device's shadow.
+ Deleting a shadow doesn't reset its version number to zero at once. It will be reset to zero after 48 hours.

**To delete a shadow by using the MQTT protocol**

1. The device or client subscribes to these MQTT topics:
   + `$aws/things/thingName/shadow/name/shadowName/delete/accepted`
   + `$aws/things/thingName/shadow/name/shadowName/delete/rejected`

1. The device or client publishes a `$aws/things/thingName/shadow/name/shadowName/delete` with an empty message buffer.

1. If the delete request is valid, AWS IoT deletes the shadow and publishes a messages with the `$aws/things/thingName/shadow/name/shadowName/delete/accepted` topic and an abbreviated [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) shadow document in the message body. This is an example of the accepted delete message:

   ```
   {
     "version": 4,
     "timestamp": 1591057529
   }
   ```

1. If the update request is not valid, AWS IoT publishes a message with the `$aws/things/thingName/shadow/name/shadowName/delete/rejected` topic with an [Error response document](device-shadow-document.md#device-shadow-example-error-json) shadow document that describes the error.

**To delete a shadow by using the REST API**

1. The device or client calls the `DeleteThingShadow` API with an empty message buffer.

1. If the request was valid, AWS IoT returns an HTTP success response code and an [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) and an abbreviated [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted) shadow document in the message body. This is an example of the accepted delete message:

   ```
   {
     "version": 4,
     "timestamp": 1591057529
   }
   ```

1. If the request was not valid, AWS IoT returns an HTTP error response code an [Error response document](device-shadow-document.md#device-shadow-example-error-json) as its response message body.

# Device Shadow REST API
<a name="device-shadow-rest-api"></a>

A shadow exposes the following URI for updating state information:

```
https://account-specific-prefix-ats.iot.region.amazonaws.com/things/thingName/shadow
```

The endpoint is specific to your AWS account. To find your endpoint, you can:
+ Use the [describe-endpoint](https://docs.aws.amazon.com/cli/latest/reference/iot/describe-endpoint.html) command from the AWS CLI.
+ Use the AWS IoT console settings. In **Settings**, the endpoint is listed under **Custom endpoint**
+ Use the AWS IoT console thing details page. In the console:

  1. Open **Manage** and under **Manage**, choose **Things**.

  1. In the list of things, choose the thing for which you want to get the endpoint URI.

  1. Choose the **Device Shadows** tab and choose your shadow. You can view the endpoint URI in the **Device Shadow URL** section of the **Device Shadow details** page.

The format of the endpoint is as follows:

```
identifier.iot.region.amazonaws.com
```

The shadow REST API follows the same HTTPS protocols/port mappings as described in [Device communication protocols](protocols.md).

**Note**  
To use the APIs, you must use `iotdevicegateway` as the service name for authentication. For more information, see [IoTDataPlane](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/clients/client-iot-data-plane/classes/iotdataplane.html).

**Topics**
+ [

## GetThingShadow
](#API_GetThingShadow)
+ [

## UpdateThingShadow
](#API_UpdateThingShadow)
+ [

## DeleteThingShadow
](#API_DeleteThingShadow)
+ [

## ListNamedShadowsForThing
](#API_ListNamedShadowsForThing)

You can also use the API to create a named shadow by providing `name=shadowName` as part of the query parameter of the API.

## GetThingShadow
<a name="API_GetThingShadow"></a>

Gets the shadow for the specified thing.

The response state document includes the delta between the `desired` and `reported` states.

**Request**  
The request includes the standard HTTP headers plus the following URI:

```
HTTP GET https://endpoint/things/thingName/shadow?name=shadowName
Request body: (none)
```

The `name` query parameter is not required for unnamed (classic) shadows.

**Response**  
Upon success, the response includes the standard HTTP headers plus the following code and body:

```
HTTP 200
Response Body: response state document
```

For more information, see [Example Response State Document](device-shadow-document.md#device-shadow-example-response-json).

**Authorization**  
Retrieving a shadow requires a policy that allows the caller to perform the `iot:GetThingShadow` action. The Device Shadow service accepts two forms of authentication: Signature Version 4 with IAM credentials or TLS mutual authentication with a client certificate.

The following is an example policy that allows a caller to retrieve a device's shadow:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iot:GetThingShadow",
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:thing/thing"
            ]
        }
    ]
}
```

## UpdateThingShadow
<a name="API_UpdateThingShadow"></a>

Updates the shadow for the specified thing.

Updates affect only the fields specified in the request state document. Any field with a value of `null` is removed from the device's shadow.

**Request**  
The request includes the standard HTTP headers plus the following URI and body:

```
HTTP POST https://endpoint/things/thingName/shadow?name=shadowName
Request body: request state document
```

The `name` query parameter is not required for unnamed (classic) shadows.

For more information, see [Example Request State Document](device-shadow-document.md#device-shadow-example-request-json).

**Response**  
Upon success, the response includes the standard HTTP headers plus the following code and body:

```
HTTP 200
Response body: response state document
```

For more information, see [Example Response State Document](device-shadow-document.md#device-shadow-example-response-json).

**Authorization**  
Updating a shadow requires a policy that allows the caller to perform the `iot:UpdateThingShadow` action. The Device Shadow service accepts two forms of authentication: Signature Version 4 with IAM credentials or TLS mutual authentication with a client certificate.

The following is an example policy that allows a caller to update a device's shadow:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iot:UpdateThingShadow",
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:thing/thing"
            ]
        }
    ]
}
```

## DeleteThingShadow
<a name="API_DeleteThingShadow"></a>

Deletes the shadow for the specified thing.

**Request**  
The request includes the standard HTTP headers plus the following URI:

```
HTTP DELETE https://endpoint/things/thingName/shadow?name=shadowName
Request body: (none)
```

The `name` query parameter is not required for unnamed (classic) shadows.

**Response**  
Upon success, the response includes the standard HTTP headers plus the following code and body:

```
HTTP 200
Response body: Empty response state document
```

Note that deleting a shadow does not reset its version number to 0.

**Authorization**  
Deleting a device's shadow requires a policy that allows the caller to perform the `iot:DeleteThingShadow` action. The Device Shadow service accepts two forms of authentication: Signature Version 4 with IAM credentials or TLS mutual authentication with a client certificate.

The following is an example policy that allows a caller to delete a device's shadow:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iot:DeleteThingShadow",
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:thing/thing"
            ]
        }
    ]
}
```

## ListNamedShadowsForThing
<a name="API_ListNamedShadowsForThing"></a>

Lists the shadows for the specified thing.

**Request**  
The request includes the standard HTTP headers plus the following URI:

```
HTTP GET /api/things/shadow/ListNamedShadowsForThing/thingName?nextToken=nextToken&pageSize=pageSize
Request body: (none)
```

nextToken  
The token to retrieve the next set of results.  
This value is returned on paged results and is used in the call that returns the next page.

pageSize  
The number of shadow names to return in each call. See also `nextToken`.

thingName  
The name of the thing for which to list the named shadows.

**Response**  
Upon success, the response includes the standard HTTP headers plus the following response code and a [Shadow name list response document](device-shadow-document.md#device-shadow-list-json).

**Note**  
The unnamed (classic) shadow does not appear in this list. The response is an empty list if you only have a classic shadow or if the `thingName` you specify doesn't exist.

```
HTTP 200
Response body: Shadow name list document
```

**Authorization**  
Listing a device's shadow requires a policy that allows the caller to perform the `iot:ListNamedShadowsForThing` action. The Device Shadow service accepts two forms of authentication: Signature Version 4 with IAM credentials or TLS mutual authentication with a client certificate.

The following is an example policy that allows a caller to list a thing's named shadows:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "iot:ListNamedShadowsForThing",
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:thing/thing"
            ]
        }
    ]
}
```

# Device Shadow MQTT topics
<a name="device-shadow-mqtt"></a>

The Device Shadow service uses reserved MQTT topics to enable devices and apps to get, update, or delete the state information for a device (shadow). 

Publishing and subscribing on shadow topics requires topic-based authorization. AWS IoT reserves the right to add new topics to the existing topic structure. For this reason, we recommend that you avoid wild card subscriptions to shadow topics. For example, avoid subscribing to topic filters like `$aws/things/thingName/shadow/#` because the number of topics that match this topic filter might increase as AWS IoT introduces new shadow topics. For examples of the messages published on these topics see [Interacting with shadows](device-shadow-data-flow.md).

Shadows can be named or unnamed (classic). The topics used by each differ only in the topic prefix. This table shows the topic prefix used by each shadow type.


| *ShadowTopicPrefix* value | Shadow type | 
| --- | --- | 
| \$1aws/things/thingName/shadow | Unnamed (classic) shadow | 
| \$1aws/things/thingName/shadow/name/shadowName | Named shadow | 

To create a complete topic, select the `ShadowTopicPrefix` for the type of shadow to which you want to refer, replace `thingName`, and `shadowName` if applicable, with their corresponding values, and then append that with the topic stub as shown in the following sections.

The following are the MQTT topics used for interacting with shadows.

**Topics**
+ [

## /get
](#get-pub-sub-topic)
+ [

## /get/accepted
](#get-accepted-pub-sub-topic)
+ [

## /get/rejected
](#get-rejected-pub-sub-topic)
+ [

## /update
](#update-pub-sub-topic)
+ [

## /update/delta
](#update-delta-pub-sub-topic)
+ [

## /update/accepted
](#update-accepted-pub-sub-topic)
+ [

## /update/documents
](#update-documents-pub-sub-topic)
+ [

## /update/rejected
](#update-rejected-pub-sub-topic)
+ [

## /delete
](#delete-pub-sub-topic)
+ [

## /delete/accepted
](#delete-accepted-pub-sub-topic)
+ [

## /delete/rejected
](#delete-rejected-pub-sub-topic)

## /get
<a name="get-pub-sub-topic"></a>

Publish an empty message to this topic to get the device's shadow:

```
ShadowTopicPrefix/get
```

AWS IoT responds by publishing to either [/get/accepted](#get-accepted-pub-sub-topic) or [/get/rejected](#get-rejected-pub-sub-topic).

### Example policy
<a name="get-policy"></a>

The following is an example of the required policy:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/get"
            ]
        }
    ]
}
```

## /get/accepted
<a name="get-accepted-pub-sub-topic"></a>

AWS IoT publishes a response shadow document to this topic when returning the device's shadow:

```
ShadowTopicPrefix/get/accepted
```

For more information, see [Response state documents](device-shadow-document.md#device-shadow-example-response-json).

### Example policy
<a name="get-accepted-policy"></a>

The following is an example of the required policy:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingName/shadow/get/accepted"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/get/accepted"
            ]
        }
    ]
}
```

## /get/rejected
<a name="get-rejected-pub-sub-topic"></a>

AWS IoT publishes an error response document to this topic when it can't return the device's shadow:

```
ShadowTopicPrefix/get/rejected
```

For more information, see [Error response document](device-shadow-document.md#device-shadow-example-error-json).

### Example policy
<a name="get-rejected-policy"></a>

The following is an example of the required policy:

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iot:Subscribe"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingName/shadow/get/rejected"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "iot:Receive"
      ],
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/get/rejected"
      ]
    }
  ]
}
```

## /update
<a name="update-pub-sub-topic"></a>

Publish a request state document to this topic to update the device's shadow:

```
ShadowTopicPrefix/update
```

The message body contains a [partial request state document](device-shadow-document.md#device-shadow-example-request-json).

A client attempting to update the state of a device would send a JSON request state document with the `desired` property such as this:

```
{
  "state": {
    "desired": {
      "color": "red",
      "power": "on"
    }
  }
}
```

A device updating its shadow would send a JSON request state document with the `reported` property, such as this:

```
{
  "state": {
    "reported": {
      "color": "red",
      "power": "on"
    }
  }
}
```

AWS IoT responds by publishing to either [/update/accepted](#update-accepted-pub-sub-topic) or [/update/rejected](#update-rejected-pub-sub-topic).

### Example policy
<a name="update-policy"></a>

The following is an example of the required policy:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/update"
            ]
        }
    ]
}
```

## /update/delta
<a name="update-delta-pub-sub-topic"></a>

AWS IoT publishes a response state document to this topic when it accepts a change for the device's shadow, and the response state document contains different values for `desired` and `reported` states:

```
ShadowTopicPrefix/update/delta
```

The message buffer contains a [/delta response state document](device-shadow-document.md#device-shadow-example-response-json-delta).

### Message body details
<a name="update-delta-rules"></a>
+ A message published on `update/delta` includes only the desired attributes that differ between the `desired` and `reported` sections. It contains all of these attributes, regardless of whether these attributes were contained in the current update message or were already stored in AWS IoT. Attributes that do not differ between the `desired` and `reported` sections are not included.
+ If an attribute is in the `reported` section but has no equivalent in the `desired` section, it is not included.
+ If an attribute is in the `desired` section but has no equivalent in the `reported` section, it is included.
+ If an attribute is deleted from the `reported` section but still exists in the `desired` section, it is included.

### Example policy
<a name="update-delta-policy"></a>

The following is an example of the required policy:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingName/shadow/update/delta"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/update/delta"
            ]
        }
    ]
}
```

## /update/accepted
<a name="update-accepted-pub-sub-topic"></a>

AWS IoT publishes a response state document to this topic when it accepts a change for the device's shadow:

```
ShadowTopicPrefix/update/accepted
```

The message buffer contains a [/accepted response state document](device-shadow-document.md#device-shadow-example-response-json-accepted).

### Example policy
<a name="update-accepted-policy"></a>

The following is an example of the required policy:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingName/shadow/update/accepted"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/update/accepted"
            ]
        }
    ]
}
```

## /update/documents
<a name="update-documents-pub-sub-topic"></a>

AWS IoT publishes a state document to this topic whenever an update to the shadow is successfully performed:

```
ShadowTopicPrefix/update/documents
```

The message body contains a [/documents response state document](device-shadow-document.md#device-shadow-example-response-json-documents).

### Example policy
<a name="update-documents-policy"></a>

The following is an example of the required policy:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingName/shadow/update/documents"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/update/documents"
            ]
        }
    ]
}
```

## /update/rejected
<a name="update-rejected-pub-sub-topic"></a>

AWS IoT publishes an error response document to this topic when it rejects a change for the device's shadow:

```
ShadowTopicPrefix/update/rejected
```

The message body contains an [Error response document](device-shadow-document.md#device-shadow-example-error-json).

### Example policy
<a name="update-rejected-policy"></a>

The following is an example of the required policy:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingName/shadow/update/rejected"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/update/rejected"
            ]
        }
    ]
}
```

## /delete
<a name="delete-pub-sub-topic"></a>

To delete a device's shadow, publish an empty message to the delete topic:

```
ShadowTopicPrefix/delete
```

The content of the message is ignored.

Note that deleting a shadow does not reset its version number to 0.

AWS IoT responds by publishing to either [/delete/accepted](#delete-accepted-pub-sub-topic) or [/delete/rejected](#delete-rejected-pub-sub-topic).

### Example policy
<a name="delete-policy"></a>

The following is an example of the required policy:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/delete"
            ]
        }
    ]
}
```

## /delete/accepted
<a name="delete-accepted-pub-sub-topic"></a>

AWS IoT publishes a message to this topic when a device's shadow is deleted:

```
ShadowTopicPrefix/delete/accepted
```

### Example policy
<a name="delete-accepted-policy"></a>

The following is an example of the required policy:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingName/shadow/delete/accepted"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/delete/accepted"
            ]
        }
    ]
}
```

## /delete/rejected
<a name="delete-rejected-pub-sub-topic"></a>

AWS IoT publishes an error response document to this topic when it can't delete the device's shadow:

```
ShadowTopicPrefix/delete/rejected
```

The message body contains an [Error response document](device-shadow-document.md#device-shadow-example-error-json).

### Example policy
<a name="delete-rejected-policy"></a>

The following is an example of the required policy:

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/things/thingName/shadow/delete/rejected"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:us-east-1:123456789012:topic/$aws/things/thingName/shadow/delete/rejected"
            ]
        }
    ]
}
```

# Device Shadow service documents
<a name="device-shadow-document"></a>

The Device Shadow service respects all rules of the JSON specification. Values, objects, and arrays are stored in the device's shadow document.

**Topics**
+ [

## Shadow document examples
](#device-shadow-document-syntax)
+ [

## Document properties
](#document-structure)
+ [

## Delta state
](#delta-state)
+ [

## Versioning shadow documents
](#versioning)
+ [

## Client tokens in shadow documents
](#client-token)
+ [

## Empty shadow document properties
](#device-shadow-empty-fields)
+ [

## Array values in shadow documents
](#device-shadow-arrays)

## Shadow document examples
<a name="device-shadow-document-syntax"></a><a name="device-shadow-example"></a>

The Device Shadow service uses these documents in UPDATE, GET, and DELETE operations using the [REST API](device-shadow-rest-api.md) or [MQTT Pub/Sub Messages](device-shadow-mqtt.md).

**Topics**
+ [

### Request state document
](#device-shadow-example-request-json)
+ [

### Response state documents
](#device-shadow-example-response-json)
+ [

### Error response document
](#device-shadow-example-error-json)
+ [

### Shadow name list response document
](#device-shadow-list-json)

### Request state document
<a name="device-shadow-example-request-json"></a>

A request state document has the following format:

```
{
    "state": {
        "desired": {
            "attribute1": integer2,
            "attribute2": "string2",
            ...
            "attributeN": boolean2
        },
        "reported": {
            "attribute1": integer1,
            "attribute2": "string1",
            ...
            "attributeN": boolean1
        }
    },
    "clientToken": "token",
    "version": version
}
```
+ `state` — Updates affect only the fields specified. Typically, you'll use either the `desired` or the `reported` property, but not both in the same request.
  + `desired` — The state properties and values requested to be updated in the device.
  + `reported` — The state properties and values reported by the device.
+ `clientToken` — If used, you can match the request and corresponding response by the client token.
+ `version` — If used, the Device Shadow service processes the update only if the specified version matches the latest version it has.

### Response state documents
<a name="device-shadow-example-response-json"></a>

Response state documents have the following format depending on the response type.

#### /accepted response state document
<a name="device-shadow-example-response-json-accepted"></a>

```
{
    "state": {
        "desired": {
            "attribute1": integer2,
            "attribute2": "string2",
            ...
            "attributeN": boolean2
        }
    },
    "metadata": {
        "desired": {
            "attribute1": {
                "timestamp": timestamp
            },
            "attribute2": {
                "timestamp": timestamp
            },
            ...
            "attributeN": {
                "timestamp": timestamp
            }
        }
    },
    "timestamp": timestamp,
    "clientToken": "token",
    "version": version
}
```

#### /delta response state document
<a name="device-shadow-example-response-json-delta"></a>

```
{
    "state": {
        "attribute1": integer2,
        "attribute2": "string2",
        ...
        "attributeN": boolean2
    },
    "metadata": {
        "attribute1": {
            "timestamp": timestamp
        },
        "attribute2": {
            "timestamp": timestamp
        },
        ...
        "attributeN": {
            "timestamp": timestamp
        }
    },
    "timestamp": timestamp,
    "clientToken": "token",
    "version": version
}
```

#### /documents response state document
<a name="device-shadow-example-response-json-documents"></a>

```
{
  "previous" : {
    "state": {
        "desired": {
            "attribute1": integer2,
            "attribute2": "string2",
            ...
            "attributeN": boolean2
        },
        "reported": {
            "attribute1": integer1,
            "attribute2": "string1",
            ...
            "attributeN": boolean1
        }
    },
    "metadata": {
        "desired": {
            "attribute1": {
                "timestamp": timestamp
            },
            "attribute2": {
                "timestamp": timestamp
            },
            ...
            "attributeN": {
                "timestamp": timestamp
            }
        },
        "reported": {
            "attribute1": {
                "timestamp": timestamp
            },
            "attribute2": {
                "timestamp": timestamp
            },
            ...
            "attributeN": {
                "timestamp": timestamp
            }
        }
    },
    "version": version-1
  },
  "current": {
    "state": {
        "desired": {
            "attribute1": integer2,
            "attribute2": "string2",
            ...
            "attributeN": boolean2
        },
        "reported": {
            "attribute1": integer2,
            "attribute2": "string2",
            ...
            "attributeN": boolean2
        }
    },
    "metadata": {
        "desired": {
            "attribute1": {
                "timestamp": timestamp
            },
            "attribute2": {
                "timestamp": timestamp
            },
            ...
            "attributeN": {
                "timestamp": timestamp
            }
        },
        "reported": {
            "attribute1": {
                "timestamp": timestamp
            },
            "attribute2": {
                "timestamp": timestamp
            },
            ...
            "attributeN": {
                "timestamp": timestamp
            }
        }
    },
    "version": version
  },
  "timestamp": timestamp,
  "clientToken": "token"
}
```

#### Response state document properties
<a name="device-shadow-example-response-json-properties"></a>
+ `previous` — After a successful update, contains the `state` of the object before the update.
+ `current` — After a successful update, contains the `state` of the object after the update.
+ `state`
  + `reported` — Present only if a thing reported any data in the `reported` section and contains only fields that were in the request state document.
  + `desired` — Present only if a device reported any data in the `desired` section and contains only fields that were in the request state document.
+ `metadata` — Contains the timestamps for each attribute in the `desired` and `reported` sections so that you can determine when the state was updated.
+ `timestamp` — The Epoch date and time the response was generated by AWS IoT.
+ `clientToken` — Present only if a client token was used when publishing valid JSON to the `/update` topic.
+ `version` — The current version of the document for the device's shadow shared in AWS IoT. It is increased by one over the previous version of the document.

### Error response document
<a name="device-shadow-example-error-json"></a>

An error response document has the following format:

```
{
    "code": error-code,
    "message": "error-message",
    "timestamp": timestamp,
    "clientToken": "token"
}
```
+ `code` — An HTTP response code that indicates the type of error.
+ `message` — A text message that provides additional information.
+ `timestamp` — The date and time the response was generated by AWS IoT. This property is not present in all error response documents.
+ `clientToken` — Present only if a client token was used in the published message.

For more information, see [Device Shadow error messages](device-shadow-error-messages.md).

### Shadow name list response document
<a name="device-shadow-list-json"></a>

A shadow name list response document has the following format:

```
{
    "results": [
        "shadowName-1",
        "shadowName-2",
        "shadowName-3",
        "shadowName-n"
    ],
    "nextToken": "nextToken",
    "timestamp": timestamp
}
```
+ `results` — The array of shadow names.
+ `nextToken` — The token value to use in paged requests to get the next page in the sequence. This property is not present when there are no more shadow names to return. 
+ `timestamp` — The date and time the response was generated by AWS IoT.

## Document properties
<a name="document-structure"></a>

A device's shadow document has the following properties:

`state`  <a name="state"></a>  
`desired`  <a name="desired"></a>
The desired state of the device. Apps can write to this portion of the document to update the state of a device directly without having to connect to it.  
`reported`  <a name="reported"></a>
The reported state of the device. Devices write to this portion of the document to report their new state. Apps read this portion of the document to determine the device's last-reported state.

`metadata`  <a name="metadata"></a>
Information about the data stored in the `state` section of the document. This includes timestamps, in Epoch time, for each attribute in the `state` section, which enables you to determine when they were updated.  
Metadata do not contribute to the document size for service limits or pricing. For more information, see [AWS IoT Service Limits](https://docs.aws.amazon.com/general/latest/gr/aws_service_limits.html#limits_iot).

`timestamp`  <a name="timestamp"></a>
Indicates when the message was sent by AWS IoT. By using the timestamp in the message and the timestamps for individual attributes in the `desired` or `reported` section, a device can determine a property's age, even if the device doesn't have an internal clock.

`clientToken`  <a name="clientToken"></a>
A string unique to the device that enables you to associate responses with requests in an MQTT environment.

`version`  <a name="version"></a>
The document version. Every time the document is updated, this version number is incremented. Used to ensure the version of the document being updated is the most recent.

For more information, see [Shadow document examples](#device-shadow-document-syntax).

## Delta state
<a name="delta-state"></a><a name="observing-state-changes"></a>

Delta state is a virtual type of state that contains the difference between the `desired` and `reported` states. Fields in the `desired` section that are not in the `reported` section are included in the delta. Fields that are in the `reported` section and not in the `desired` section are not included in the delta. The delta contains metadata, and its values are equal to the metadata in the `desired` field. For example:

```
{
  "state": {
    "desired": {
      "color": "RED",
      "state": "STOP"
    },
    "reported": {
      "color": "GREEN",
      "engine": "ON"
    },
    "delta": {
      "color": "RED",
      "state": "STOP"
    }
  },
  "metadata": {
    "desired": {
      "color": {
        "timestamp": 12345
      },
      "state": {
        "timestamp": 12345
      }
      },
      "reported": {
        "color": {
          "timestamp": 12345
        },
        "engine": {
          "timestamp": 12345
        }
      },
      "delta": {
        "color": {
          "timestamp": 12345
        },
        "state": {
          "timestamp": 12345
        }
      }
    },
    "version": 17,
    "timestamp": 123456789
  }
}
```

When nested objects differ, the delta contains the path all the way to the root.

```
{
  "state": {
    "desired": {
      "lights": {
        "color": {
          "r": 255,
          "g": 255,
          "b": 255
        }
      }
    },
    "reported": {
      "lights": {
        "color": {
          "r": 255,
          "g": 0,
          "b": 255
        }
      }
    },
    "delta": {
      "lights": {
        "color": {
          "g": 255
        }
      }
    }
  },
  "version": 18,
  "timestamp": 123456789
}
```

The Device Shadow service calculates the delta by iterating through each field in the `desired` state and comparing it to the `reported` state.

Arrays are treated like values. If an array in the `desired` section doesn't match the array in the `reported` section, then the entire desired array is copied into the delta.

## Versioning shadow documents
<a name="versioning"></a>

The Device Shadow service supports versioning on every update message, both request and response. This means that with every update of a shadow, the version of the JSON document is incremented. This ensures two things:
+ A client can receive an error if it attempts to overwrite a shadow using an older version number. The client is informed it must resync before it can update a device's shadow.
+ A client can decide not to act on a received message if the message has a lower version than the version stored by the client. 

A client can bypass version matching by not including a version in the shadow document.

## Client tokens in shadow documents
<a name="client-token"></a>

You can use a client token with MQTT-based messaging to verify the same client token is contained in a request and request response. This ensures the response and request are associated.

**Note**  
The client token can be no longer than 64 bytes. A client token that is longer than 64 bytes causes a 400 (Bad Request) response and an *Invalid clientToken* error message.

## Empty shadow document properties
<a name="device-shadow-empty-fields"></a>

The `reported` and `desired` properties in a shadow document can be empty or omitted when they don't apply to the current shadow state. For example, a shadow document contains a `desired` property only if it has a desired state. The following is a valid example of a state document with no `desired` property:

```
{
    "reported" : { "temp": 55 }
}
```

The `reported` property can also be empty, such as if the shadow has not been updated by the device:

```
{
    "desired" : { "color" : "RED" }
}
```

If an update causes the `desired` or `reported` properties to become null, it is removed from the document. The following shows how to remove the `desired` property by setting it to `null`. You might do this when a device updates its state, for example.

```
{ 
    "state": {
        "reported": {
            "color": "red" 
        }, 
        "desired": null 
    } 
}
```

A shadow document can also have neither `desired` or `reported` properties, making the shadow document empty. This is an example of an empty, yet valid shadow document.

```
{
}
```

## Array values in shadow documents
<a name="device-shadow-arrays"></a>

Shadows support arrays, but treat them as normal values in that an update to an array replaces the whole array. It is not possible to update part of an array.

Initial state:

```
{
    "desired" : { "colors" : ["RED", "GREEN", "BLUE" ] }
}
```

Update:

```
{
    "desired" : { "colors" : ["RED"] }
}
```

Final state:

```
{
    "desired" : { "colors" : ["RED"] }
}
```

Arrays can't have null values. For example, the following array is not valid and will be rejected.

```
{
    "desired" : { 
        "colors" : [ null, "RED", "GREEN" ]
    }
}
```

# Device Shadow error messages
<a name="device-shadow-error-messages"></a>

The Device Shadow service publishes a message on the error topic (over MQTT) when an attempt to change the state document fails. This message is only emitted as a response to a publish request on one of the reserved `$aws` topics. If the client updates the document using the REST API, then it receives the HTTP error code as part of its response, and no MQTT error messages are emitted.


****  

| HTTP error code | Error messages | 
| --- | --- | 
| 400 (Bad Request) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-error-messages.html)  | 
| 401 (Unauthorized) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-error-messages.html)  | 
| 403 (Forbidden) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-error-messages.html)  | 
| 404 (Not Found) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-error-messages.html)  | 
| 409 (Conflict) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-error-messages.html)  | 
| 413 (Payload Too Large) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-error-messages.html)  | 
| 415 (Unsupported Media Type) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-error-messages.html)  | 
| 429 (Too Many Requests) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-error-messages.html)  | 
| 500 (Internal Server Error) |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/device-shadow-error-messages.html)  | 