

# AWS IoT Device Management commands
<a name="iot-remote-command"></a>

**Important**  
This documentation describes how you can use the [commands feature in AWS IoT Device Management](https://docs.aws.amazon.com/iot/latest/developerguide/iot-remote-command-concepts.html#command-iot-namespace). For information about using this feature for AWS IoT FleetWise, see [Remote commands](https://docs.aws.amazon.com/iot-fleetwise/latest/developerguide/remote-commands.html).  
You are solely responsible for deploying commands in a manner that is safe and compliant with applicable laws. For more information on your responsibilities, please see the [AWS Service Terms for AWS IoT Services](https://aws.amazon.com/service-terms/).

Use AWS IoT Device Management Commands to send an instruction from the cloud to a device that's connected to AWS IoT. Commands target one device at a time and can be used for low-latency, high-throughput applications, such as retrieving device-side logs or initiating a device state change.

The *command* is a reusable resource that's managed by AWS IoT Device Management. It contains configurations that are applied before they are published to the device. You can predefine a set of commands for specific use cases, such as turning on a light bulb or unlocking a vehicle door.

The AWS IoT Commands feature enables you to:
+ Create reusable command templates with static or dynamic payloads, then execute them on specific devices.
+ Target devices registered as AWS IoT things or unregistered MQTT clients.
+ Run multiple commands concurrently on the same device.
+ Enable event notifications and track execution status as devices process commands.

The following topics show you how to create commands, send them to your device, and retrieve the status reported by the device.

**Topics**
+ [Quick start](iot-commands-quickstart.md)
+ [Commands concepts and status](iot-remote-command-concepts.md)
+ [High-level commands workflow](iot-remote-command-workflow.md)
+ [Create and manage commands](iot-remote-command-create-manage.md)
+ [Start and monitor command executions](iot-remote-command-execution-start-monitor.md)
+ [Deprecate a command resource](iot-remote-command-deprecate.md)

# Quick start
<a name="iot-commands-quickstart"></a>

Complete these steps to send your first command:

1. **Prerequisites** - Ensure you are onboarded to IoT Core, a device connected to IoT Core, IAM permissions for Commands API operations, and an MQTT client library installed on your device.

1. **Create a command** - Define a command with a static payload, or a payload template specifying device actions. See [Create a command resource](iot-remote-command-create-manage.md#iot-remote-command-create).

1. **Identify your device** - Register your device as an IoT thing or note its MQTT client ID. See [Target device considerations](iot-remote-command-execution-start-monitor.md#iot-command-execution-target).

1. **Configure permissions** - Set up IAM policies allowing your device to receive commands and publish responses.

1. **Subscribe to topics** - Configure your device to subscribe to commands request and response topics. See [Choose target device for your commands and subscribe to MQTT topics](iot-remote-command-workflow.md#command-choose-target).

1. **Execute the command** - Start the command execution on your target device. See [Start a command executionStart a command execution (console)Start a command execution (AWS CLI)](iot-remote-command-execution-start-monitor.md#iot-remote-command-execution-start).

**Common use cases:**
+ *Remote diagnostics* - Retrieve logs, run diagnostics, check device health
+ *Configuration updates* - Change settings, update parameters, toggle features
+ *Device control* - Lock/unlock, power on/off, mode changes

# Commands concepts and status
<a name="iot-remote-command-concepts"></a>

Use AWS IoT Commands to send instructions from the cloud to connected devices. To use this feature:

1. Create a command with a payload containing the configurations required to run on the device.

1. Specify the target device that will receive the payload and perform the actions.

1. Execute the command on the target device and retrieve status information. To troubleshoot issues, see CloudWatch logs.

For more information about this workflow, see [High-level commands workflow](iot-remote-command-workflow.md).

**Topics**
+ [Commands key concepts](#iot-command-concepts)
+ [Command states](#iot-command-states)
+ [Command execution status](#iot-command-execution-status)

## Commands key concepts
<a name="iot-command-concepts"></a>

The following key concepts help you understand the Commands feature. Terms are used consistently throughout this documentation:
+ *Command* - A reusable template defining device instructions
+ *Execution* - An instance of a command running on a device
+ *Thing name* - Identifier for devices registered in IoT registry
+ *Client ID* - MQTT identifier for unregistered devices
+ *Payload* - The instruction data sent to devices
+ *Topic* - MQTT channel for command communication

**Commands**  
Commands are instructions sent from the cloud to your IoT devices as MQTT messages. After receiving the payload, devices process the instructions and take corresponding actions, such as modifying configuration settings, transmitting sensor readings, or uploading logs. Devices then return results to the cloud, enabling remote monitoring and control.

**Namespace**  
When creating a command, specify its namespace. For AWS IoT Device Management commands, use the default `AWS-IoT` namespace and provide either a payload or payloadTemplate. For AWS IoT FleetWise commands, use the `AWS-IoT-FleetWise` namespace. For more information, see [Remote commands](https://docs.aws.amazon.com/iot-fleetwise/latest/developerguide/remote-commands.html) in the *AWS IoT FleetWise Developer Guide*.

**Payload**  
When creating a command, provide a static payload that defines the actions the device must perform. The payload can use any supported format. To ensure devices correctly interpret the payload, we recommend specifying the payload format type. Devices using the MQTT5 protocol can follow the MQTT standard to identify the format. Format indicators for JSON or CBOR are available in the commands request topic.

**Payload template**  
A payload template defines a command payload with placeholders that generate different payloads at runtime based on parameter values you provide. For example, instead of creating separate payloads for different temperature values, create one template with a temperature placeholder and specify the value during execution. This eliminates maintaining multiple similar payloads.

**Target device**  
To execute a command, specify a target device using either its thing name (for devices registered with AWS IoT) or MQTT client ID (for unregistered devices). The client ID is a unique identifier defined in the [MQTT](mqtt.md) protocol used to connect devices to AWS IoT. For details, see [Target device considerations](iot-remote-command-execution-start-monitor.md#iot-command-execution-target).

**Commands topics**  
Before executing a command, devices must subscribe to the commands request topic. When you execute a command, the payload is sent to the device on this topic. After execution, devices publish results and status to the commands response topic. For more information, see [Commands topics](reserved-topics.md#reserved-topics-commands).

**Command execution**  
An execution is an instance of a command running on a target device. When you start an execution, the payload is delivered to the device and a unique execution ID is generated. The device executes the command and reports progress to AWS IoT. Device-side logic determines execution behavior and status reporting to reserved topics.

### Parameter value conditions
<a name="iot-command-parameter-value-conditions"></a>

When creating commands with payload templates, define value conditions to validate parameter values before execution. Value conditions ensure parameters meet requirements, preventing invalid executions.

**Supported operators by [CommandParameterValue](https://docs.aws.amazon.com//iot/latest/apireference/API_CommandParameterValue.html) type**

**Numeric types (INTEGER, LONG, DOUBLE, UNSIGNEDLONG)**  
+ `EQUALS` - Value must equal the specified number
+ `NOT_EQUALS` - Value must not equal the specified number
+ `GREATER_THAN` - Value must be greater than the specified number
+ `GREATER_THAN_EQUALS` - Value must be greater than or equal to the specified number
+ `LESS_THAN` - Value must be less than the specified number
+ `LESS_THAN_EQUALS` - Value must be less than or equal to the specified number
+ `IN_RANGE` - Value must be within the specified range (inclusive)
+ `NOT_IN_RANGE` - Value must be outside the specified range (inclusive)
+ `IN_SET` - Value must match one of the specified numbers
+ `NOT_IN_SET` - Value must not match any of the specified numbers

**String type (STRING)**  
+ `EQUALS` - Value must equal the specified string
+ `NOT_EQUALS` - Value must not equal the specified string
+ `IN_SET` - Value must match one of the specified strings
+ `NOT_IN_SET` - Value must not match any of the specified strings

**Boolean type**  
+ Value conditions are not supported

**Binary type**  
+ Value conditions are not supported

**Example: Temperature control command**

```
{
  "commandId": "SetTemperature",
  "namespace": "AWS-IoT",
  "payloadTemplate": "{\"temperature\": \"${aws:iot:commandexecution::parameter:temperature}\"}",
  "parameters": [
    {
      "name": "temperature",
      "type": "INTEGER",
      "valueConditions": [
        {
          "comparisonOperator": "IN_RANGE",
          "operand": {
            "numberRange": {
              "min": "60",
              "max": "80"
            }
          }
        }
      ]
    }
  ]
}
```

In this example, the `temperature` parameter must be between 60 and 80 (inclusive). Execution requests with values outside this range fail validation.

**Note**  
Value conditions are evaluated at invocation of [StartCommandExecution API](https://docs.aws.amazon.com//iot/latest/apireference/API_iot-jobs-data_StartCommandExecution.html). Failed validations return an error and prevent execution creation.

### Parameter value priority and evaluation
<a name="iot-command-parameter-value-priority"></a>

When starting command executions with payload templates, parameter values are resolved using the following priority:

1. **Execution request parameters** - Values provided in the `StartCommandExecution` request take highest priority

1. **Command default values** - If a parameter is not provided in the execution request, the parameter's `defaultValue` is used

1. **No value** - If neither is provided, execution fails as the parameter required to generate the execution request

Value conditions are evaluated on the final parameter value derived above on the priority and before execution creation. If validation fails, the execution request returns an error.

**Example: SetTemperature command with `defaultValue`**

```
{
  "parameters": [
    {
      "name": "temperature",
      "type": "INTEGER",
      "defaultValue": {"I": 72},
      "valueConditions": [
        {
          "comparisonOperator": "IN_RANGE",
          "operand": {"numberRange": {"min": "60", "max": "80"}}
        }
      ]
    }
  ]
}
```

When starting execution:
+ If you provide `"temperature": {"I": 75}` in the request, 75 is used
+ If you omit the temperature parameter, the default value 72 is used
+ Both values are validated against the range condition [60,80]

## Command states
<a name="iot-command-states"></a>

Commands in your AWS account can be in one of three states: *Available*, *Deprecated*, or *Pending deletion*.

**Available**  
After successful creation, a command is in the Available state and can be executed on devices.

**Deprecated**  
Mark commands for deprecation when no longer needed. Deprecated commands cannot start new executions, but pending executions continue to completion. To enable new executions, restore the command to Available state.

**Pending deletion**  
When you mark a command for deletion, it is deleted automatically if deprecated longer than the maximum timeout (default: 12 hours). This action is permanent. If not deprecated or deprecated for less than the timeout, the command enters Pending deletion state and is removed after the timeout expires.

## Command execution status
<a name="iot-command-execution-status"></a>

When you start an execution on a target device, it enters `CREATED` status and can transition to other statuses based on device reports. You can retrieve status information and track executions.

**Note**  
You can run multiple commands concurrently on a device. Use concurrency control to limit executions per device and prevent overload. For maximum concurrent executions per device, see [AWS IoT Device Management commands quotas](https://docs.aws.amazon.com/general/latest/gr/iot_device_management.html#commands-limits).

The following table shows execution statuses and their transitions based on execution progress.


**Command execution status and source**  

| Command execution status | Initiated by device/cloud? | Terminal execution? | Allowed status transitions | 
| --- | --- | --- | --- | 
| CREATED | Cloud | No |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/iot-remote-command-concepts.html)  | 
| IN\$1PROGRESS | Device | No |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/iot-remote-command-concepts.html)  | 
| TIMED\$1OUT | Device and cloud | No |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iot/latest/developerguide/iot-remote-command-concepts.html)  | 
| SUCCEEDED | Device | Yes | Not applicable | 
| FAILED | Device | Yes | Not applicable | 
| REJECTED | Device | Yes | Not applicable | 

Devices can publish status and result updates anytime using commands reserved MQTT topics. To provide additional context, devices can use `reasonCode` and `reasonDescription` fields in the `statusReason` object.

The following diagram shows execution status transitions.

![\[Image showing how a command execution status transitions between various statuses.\]](http://docs.aws.amazon.com/iot/latest/developerguide/images/command-execution-status-transitions.png)


**Note**  
When AWS IoT detects no device response within the timeout period, it sets `TIMED_OUT` as a temporary status allowing retries and state changes. If your device explicitly reports `TIMED_OUT`, this becomes a terminal status with no further transitions. For more information, see [Non-terminal command executions](#iot-command-execution-status-nonterminal).

The following sections describe terminal and non-terminal executions and their statuses.

**Topics**
+ [Non-terminal command executions](#iot-command-execution-status-nonterminal)
+ [Terminal command executions](#iot-command-execution-status-terminal)

### Non-terminal command executions
<a name="iot-command-execution-status-nonterminal"></a>

An execution is non-terminal if it can accept updates from devices. Non-terminal executions are considered *Active*. The following statuses are non-terminal:
+ 

**CREATED**  
When you start an execution from the AWS IoT console or use the `StartCommandExecution` API, successful requests change the status to `CREATED`. From this status, executions can transition to any other non-terminal or terminal status.
+ 

**IN\$1PROGRESS**  
After receiving the payload, devices can start executing instructions and performing specified actions. While executing, devices can publish responses to the commands response topic and update status to `IN_PROGRESS`. From `IN_PROGRESS`, executions can transition to any terminal or non-terminal status except `CREATED`.
**Note**  
The `UpdateCommandExecution` API can be invoked multiple times with `IN_PROGRESS` status. Specify additional execution details using the `statusReason` object.
+ 

**TIMED\$1OUT**  
Both cloud and device can trigger this status. Executions in `CREATED` or `IN_PROGRESS` status can change to `TIMED_OUT` for the following reasons:
  + After sending the command, a timer starts. If the device doesn't respond within the specified duration, the cloud changes status to `TIMED_OUT`. In this case, the execution is non-terminal.
  + The device can override status to any terminal status or report a timeout and set status to `TIMED_OUT`. In this case, status remains `TIMED_OUT`, but `StatusReason` object fields change based on device information. The execution becomes terminal.

  For more information, see [Time out value and `TIMED_OUT` execution status](iot-remote-command-execution-start-monitor.md#iot-command-execution-timeout-status).

### Terminal command executions
<a name="iot-command-execution-status-terminal"></a>

An execution becomes terminal when it no longer accepts updates from devices. The following statuses are terminal. Executions can transition to terminal statuses from any non-terminal status: `CREATED`, `IN_PROGRESS`, or `TIMED_OUT`.
+ 

**SUCCEEDED**  
If the device successfully completes execution, it can publish a response to the commands response topic and update status to `SUCCEEDED`.
+ 

**FAILED**  
When a device fails to complete execution, it can publish a response to the commands response topic and update status to `FAILED`. Use the `reasonCode` and `reasonDescription` fields in the `statusReason` object, or CloudWatch logs, to troubleshoot failures.
+ 

**REJECTED**  
When a device receives an invalid or incompatible request, it can invoke the `UpdateCommandExecution` API with status `REJECTED`. Use the `reasonCode` and `reasonDescription` fields in the `statusReason` object, or CloudWatch logs, to troubleshoot issues.

# High-level commands workflow
<a name="iot-remote-command-workflow"></a>

This workflow shows how devices interact with AWS IoT Device Management Commands. All HTTP API requests use [Sigv4 credentials](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_sigv.html) for signing.

![\[Overview of the AWS IoT Device Management device command high-level workflow.\]](http://docs.aws.amazon.com/iot/latest/developerguide/images/device-command-workflow.png)


**Topics**
+ [Create and manage commands](#command-create-command)
+ [Choose target device for your commands and subscribe to MQTT topics](#command-choose-target)
+ [Start and monitor command executions for your target device](#command-command-executions)
+ [(Optional) Enable notifications for commands events](#iot-remote-command-commands-notifications)

## Create and manage commands
<a name="command-create-command"></a>

To create and manage commands for your devices, perform the following steps.

1. 

**Create a command resource**

   Create a Command from the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) or using the [https://docs.aws.amazon.com/iot/latest/apireference/API_CreateCommand.html](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateCommand.html) API.

1. 

**Specify the payload**

   Provide a Payload in any format. Specify the content type to ensure correct device interpretation.

   For dynamic Commands with payload templates, the final payload is generated at runtime using your supplied parameters. Templates support JSON format only, but the generated Payload can be sent as JSON or CBOR.

1. 

**(Optional) Manage the created commands**

   Update the display name and description after creation. Mark Commands as deprecated when no longer needed, or delete them permanently. To modify Payload information, create a new Command.

## Choose target device for your commands and subscribe to MQTT topics
<a name="command-choose-target"></a>

Choose your target device and configure MQTT topics for receiving Commands and publishing responses.

1. 

**Choose the target device for your command**

   Choose a target device to receive and execute the Command. Use a Thing name for registered devices or a Client ID for unregistered devices. For more information, see [Target device considerations](iot-remote-command-execution-start-monitor.md#iot-command-execution-target).

1. 

**Configure the AWS IoT device policy**

   Configure an IAM policy granting permissions to receive Executions and publish updates. See [Sample IAM policy](iot-remote-command-execution-start-monitor.md#iot-remote-command-execution-update-policy) for policy examples.

1. 

**Establish an MQTT connection**

   Connect devices to the message broker and subscribe to request and response Topics. Devices need `iot:Connect` permission. Find your data plane endpoint using the `DescribeEndpoint` API or `describe-endpoint` CLI command:

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

   Running this command returns the account-specific data plane endpoint as shown below.

   ```
   account-specific-prefix.iot.region.amazonaws.com
   ```

1. 

**Subscribe to commands topics**

   Subscribe to the Commands request Topic. When you start an Execution, the message broker publishes the Payload to this Topic. Your device receives and processes the Command.

   (Optional) Subscribe to response Topics (`accepted` or `rejected`) to receive confirmation whether the cloud service accepted or rejected the device response.

   In this example, replace:
   + *`<device>`* with `thing` or `client` depending on whether the device you're targeting has been registered as an IoT thing, or specified as an MQTT client.
   + *`<DeviceID>`* with the unique identifier of your target device. This ID can be the unique MQTT client ID or a thing name.
**Note**  
If the payload type is not JSON or CBOR, the *<PayloadFormat>* field might not be present in the commands request topic. To get the payload format, we recommend that you use MQTT5 to get the format information from the MQTT message headers. For more information, see [Commands topics](reserved-topics.md#reserved-topics-commands).

   ```
   $aws/commands/<devices>/<DeviceID>/executions/+/request/<PayloadFormat>
   $aws/commands/<devices>/<DeviceID>/executions/+/response/accepted/<PayloadFormat>
   $aws/commands/<devices>/<DeviceID>/executions/+/response/rejected/<PayloadFormat>
   ```

## Start and monitor command executions for your target device
<a name="command-command-executions"></a>

After you have created the commands and specified the targets for the command, you can start the execution on the target device by performing the following steps.

1. 

**Start command execution on the target device**

   Start the Execution from the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) or using the `StartCommandExecution` API with your account-specific endpoint. Use `iot:Data-ATS` for dual-stack (IPv4/IPv6) or `iot:Jobs` for IPv4 only.

   The API publishes the Payload to the Commands request Topic.
**Note**  
If the device is offline and uses MQTT persistent sessions, the Command waits at the message broker. When the device reconnects before timeout, it can process the Command and publish results. If timeout expires, the execution times out and the payload will be discarded.

1. 

**Update the result of the command execution**

   The device receives the Payload, processes the Command, performs the specified actions, and publishes results to the Commands response Topic using `UpdateCommandExecution` MQTT based API. If subscribed to accepted and rejected Topics, the device receives confirmation whether the cloud service accepted or rejected the response.

   Depending on what you specified in the request topic, *<devices>* can be either things or clients, and *<DeviceID>* can be your AWS IoT thing name or the MQTT client ID.
**Note**  
The *<PayloadFormat>* can only be JSON or CBOR in the commands response topic.

   ```
   $aws/commands/<devices>/<DeviceID>/executions/<ExecutionId>/response/<PayloadFormat>
   ```

1. 

**(Optional) Retrieve command execution result**

   Retrieve Execution results from the AWS IoT console or using `GetCommandExecution`. The device must publish results to the Commands response Topic for latest information. View additional details including last update time, result, and completion time.

## (Optional) Enable notifications for commands events
<a name="iot-remote-command-commands-notifications"></a>

Subscribe to Commands events for notifications when Execution status changes. For detailed information about command execution events, including the event message format and payload attributes, see [Command execution events](command-events.md).

1. 

**Create a topic rule**

   Subscribe to the Commands events Topic for status change notifications. Create a topic rule to route device data to other AWS IoT services like AWS Lambda, Amazon SQS, and AWS Step Functions using the AWS IoT console or [Creating an AWS IoT rule](iot-create-rule.md).

   In this example, replace `<CommandID>` with the identifier of the command for which you want to receive notifications and `<CommandExecutionStatus>` with the status of the command execution.

   ```
   $aws/events/commandExecution/<CommandID>/<CommandExecutionStatus>
   ```
**Note**  
To receive notifications for all commands and command execution statuses, you can use wildcard characters and subscribe to the following topic.

   ```
   $aws/events/commandExecution/+/#
   ```

1. 

**Receive and process commands events**

   Manage Commands push notifications and build applications using the subscribed events.

The following code shows a sample payload for the commands events notifications that you'll receive.

```
{
    "executionId": "2bd65c51-4cfd-49e4-9310-d5cbfdbc8554",
    "status":"FAILED",
    "statusReason": {
         "reasonCode": "DEVICE_TOO_BUSY",
         "reasonDescription": ""
    },
    "eventType": "COMMAND_EXECUTION",
    "commandArn":"arn:aws:iot:us-east-1:123456789012:command/0b9d9ddf-e873-43a9-8e2c-9fe004a90086",
    "targetArn":"arn:aws:iot:us-east-1:123456789012:thing/5006c3fc-de96-4def-8427-7eee36c6f2bd",
    "timestamp":1717708862107
}
```

# Create and manage commands
<a name="iot-remote-command-create-manage"></a>

Use AWS IoT Device Management Commands to configure reusable remote actions or send immediate instructions to devices. Create and manage Commands from the AWS IoT console or using the AWS CLI.

**Topics**
+ [Create a command resource](#iot-remote-command-create)
+ [Retrieve information about a command](#iot-remote-command-get)
+ [List commands in your AWS account](#iot-remote-command-list)
+ [Update a command resource](#iot-remote-command-update)
+ [Deprecate or restore a command resource](#iot-remote-command-deprecatecmd)
+ [Delete a command resource](#iot-remote-command-delete)

## Create a command resource
<a name="iot-remote-command-create"></a>

Provide the following information when creating a Command:
+ 

**General information**  
Provide a unique Command ID to identify the Command when running it on target devices. Optionally specify a display name, description, and tags for management.
+ **Payload**

  For static Commands, provide a Payload defining device actions. Specify the Payload format type for correct device interpretation.

  For dynamic Commands, see the Payload template attribute.
+ **Payload template**

  For dynamic Commands, provide a payloadTemplate with placeholders and parameters. Optionally provide `defaultValue` and conditions. AWS IoT Device Management Commands replaces placeholders at runtime. Missing parameters use their defaultValue. All values must satisfy defined conditions.

  The following case-sensitive placeholder types are supported:
  + `${aws:iot:commandexecution::parameter:parameter1}` – A placeholder for the value of a parameter with the name `parameter1`.
  + `${aws:iot:commandexecution::executionTimeoutSec}` – A placeholder for the command execution timeout parameter supplied at runtime.

### Payload and commands topics
<a name="iot-commands-payload-mqtt"></a>

Commands reserved Topics use a format based on Payload format type.
+ For `application/json` or `application/cbor` content types, use this request Topic:

  ```
  $aws/commands/<devices>/<DeviceID>/executions/+/request/<PayloadFormat>
  ```
+ For other content types or unspecified format, use this request Topic. The Payload format appears in the MQTT message header.

  ```
  $aws/commands/<devices>/<DeviceID>/executions/+/request
  ```

The Commands response Topic uses `json` or `cbor` format regardless of Payload type. *<PayloadFormat>* must be `json` or `cbor`:

```
$aws/commands/<devices>/<DeviceID>/executions/<ExecutionId>/response/<PayloadFormat>
```

### Create a command resource (console)
<a name="iot-remote-command-create-console"></a>

The following sections describe Payload format considerations and Command creation from the console.

**Topics**
+ [Static command payload format](#iot-commands-payload-format)
+ [Dynamic command payload format](#iot-commands-dynamic-payload-format)
+ [How to create a command (console)](#iot-commands-console-how)

#### Static command payload format
<a name="iot-commands-payload-format"></a>

The Payload supports any format up to 32 KB. Specify the Payload format type for secure and correct device interpretation.

Specify Payload format type using `type/subtype` format (e.g., `application/json` or `application/cbor`). Default: `application/octet-stream`. See [Common MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/MIME_types/Common_types) for supported formats.

#### Dynamic command payload format
<a name="iot-commands-dynamic-payload-format"></a>

The payloadTemplate must be valid JSON with at least one placeholder, up to 32 KB.

For `AwsJsonSubstitution` preprocessor, AWS IoT Device Management Commands sends notifications in JSON or CBOR format based on preprocessor configuration.

#### How to create a command (console)
<a name="iot-commands-console-how"></a>

To create a Command from the console, go to [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) and follow these steps:

1. Choose **Create command**.

1. Specify a unique Command ID.

1. (Optional) Specify display name, description, and tags.

1. Upload the Payload file containing device actions. Specify the Payload format type for correct device interpretation.

1. (Optional) For JSON payload templates with placeholders, parameters pre-populate in the inline table for editing.

1. (Optional) Configure parameter value type (required), default value, and conditions.

1. Choose **Create command**.

### Create a command resource (CLI)
<a name="iot-remote-command-create-cli"></a>

Use the [https://docs.aws.amazon.com/iot/latest/apireference/API_CreateCommand.html](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateCommand.html) API or [https://docs.aws.amazon.com/cli/latest/reference/iot/create-command.html](https://docs.aws.amazon.com/cli/latest/reference/iot/create-command.html) CLI command to create a Command.

**Topics**
+ [Command payload](#iot-commands-payload)
+ [Sample IAM policy](#iot-remote-command-create-iam)
+ [Static command creation example](#iot-remote-command-create-example)
+ [Dynamic command creation example](#iot-remote-dynamic-command-create-example)

#### Command payload
<a name="iot-commands-payload"></a>

Provide a static Payload or payload template. Static Payloads are base64 encoded. For payload templates, the final Payload generates at runtime using parameter values. Devices process the Payload and perform specified actions. Specify the Payload content type for correct device reception.

**Note**  
Payloads cannot be modified after Command creation. Create a new Command to modify the Payload.

#### Sample IAM policy
<a name="iot-remote-command-create-iam"></a>

Before you use this API operation, make sure that your IAM policy authorizes you to perform this action on the device. The following example shows an IAM policy that allows the user permission to perform the `CreateCommand` action.

In this example, replace:
+ `region` with your AWS Region, such as `us-east-1`.
+ `account-id` with your AWS account number, such as `123456789012`.
+ `command-id` with a unique identifier for your AWS IoT command ID, such as `LockDoor`. If you want to send more than one command, you can specify these commands under the *Resource* section in the IAM policy.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
        "Action": "iot:CreateCommand",
        "Effect": "Allow",
        "Resource": "arn:aws:iot:us-east-1:123456789012:command/command-id"
    }
}
```

#### Static command creation example
<a name="iot-remote-command-create-example"></a>

The following example shows how you can create a static command. Depending on your application, replace:
+ *`<command-id>`* with a unique identifier for the command. For example, to lock the door of your house, you can specify *`LockDoor`*. We recommend that you use UUID. You can also use alpha-numeric characters, "-", and "\$1".
+ (Optional) *`<display-name>`* and *`<description>`* , which are optional fields that you can use to provide a friendly name and a meaningful description for the command, such as *`Lock the doors of my home`*.
+ `namespace`, which you can use to specify the namespace of the command. It must be `AWS-IoT`. For information about using this feature for AWS IoT FleetWise, see [Remote commands](https://docs.aws.amazon.com/iot-fleetwise/latest/developerguide/remote-commands.html)
+ `payload` contains information about the payload that you want to use when running the command and it's content type.

```
aws iot create-command \ 
    --command-id <command-id> \
    --display-name <display-name> \
    --description <description> \ 
    --namespace AWS-IoT \ 
    --payload '{"content":"eyAibWVzc2FnZSI6ICJIZWxsbyBJb1QiIH0=","contentType":"application/json"}'
```

Running this command generates a response that contains the ID and ARN (Amazon resource name) of the command. For example, if you specified the `LockDoor` command during creation, the following shows a sample output of running the command.

```
{
    "commandId": "LockDoor",
    "commandArn": "arn:aws:iot:us-east-1:123456789012:command/LockDoor"
}
```

#### Dynamic command creation example
<a name="iot-remote-dynamic-command-create-example"></a>

The following example shows how you can create a dynamic command. Depending on your application, replace:
+ *`<command-id>`* with a unique identifier for the command. For example, to set the light power status, you can specify *`Light_Power_Status`*. We recommend that you use UUID. You can also use alpha-numeric characters, "-", and "\$1".
+ (Optional) *`<display-name>`* and *`<description>`* , which are optional fields that you can use to provide a friendly name and a meaningful description for the command, such as *`Turn a light ON or OFF`*.
+ `namespace`, which you can use to specify the namespace of the command. It must be `AWS-IoT`. For information about using this feature for AWS IoT FleetWise, see [Remote commands](https://docs.aws.amazon.com/iot-fleetwise/latest/developerguide/remote-commands.html)
+ `payloadTemplate` contains the JSON formatted playoad template with placehodlers.
+ `preprocessor` contains the configuration for preprocessor that determines how the payloadTemplate must be processed.
+ `mandatoryParameter` contains the parameters corresponding to the placeholders in the payloadTemplate, their type, default values, and conditions.

```
aws iot create-command \
    --command-id Light_Power_Status \
    --description "Turn a light ON or OFF" \
    --namespace AWS-IoT \
    --payload-template '{"powerStatus":"${aws:iot:commandexecution::parameter:powerStatus}"}' \
    --preprocessor awsJsonSubstitution={outputFormat=JSON} \
    --mandatory-parameters "name=powerStatus, defaultValue={S=OFF}, valueConditions=[{comparisonOperator=IN_SET, operand={strings=['ON','OFF']}}]"
```

Running this command generates a response that contains the ID and ARN (Amazon resource name) of the command. For example, if you specified the `Light_Power_Status` command during creation, the following shows a sample output of running the command.

```
{
    "commandId": "Light_Power_Status",
    "commandArn": "arn:aws:iot:us-east-1:123456789012:command/Light_Power_Status"
}
```

## Retrieve information about a command
<a name="iot-remote-command-get"></a>

After you create a command, you can retrieve information about it from the AWS IoT console and using the AWS CLI. You can obtain the following information.
+ The command ID, Amazon resource name (ARN), any display name and description that you specified for the command.
+ The command state, which indicates whether a command is available to run on the target device, or whether it's being deprecated or deleted.
+ The payload or payloadTemplate that you provided.
+ The preprocessor that you provided.
+ The mandatoryParameters that you provided.
+ The time when the command was created and last updated.

### Retrieve a command resource (console)
<a name="iot-remote-command-get-console"></a>

To retrieve a command from the console, go to the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) of the AWS IoT console and then choose the command that you created to view it's details.

In addition to the command details, you can see the command history, which provides information about the executions of the command on the target device. After you run this command on the device, you can find information about the executions on this tab.

### Retrieve a command resource (CLI)
<a name="iot-remote-command-get-cli"></a>

Use the [https://docs.aws.amazon.com/iot/latest/apireference/API_GetCommand.html](https://docs.aws.amazon.com/iot/latest/apireference/API_GetCommand.html) HTTP control plane API operation or the [https://docs.aws.amazon.com/cli/latest/reference/get-command.html](https://docs.aws.amazon.com/cli/latest/reference/get-command.html) AWS CLI command to retrieve information about a command resource. You must've already created the command using the `CreateCommand` API request or the `create-command` CLI.

#### Sample IAM policy
<a name="iot-remote-command-get-iam"></a>

Before you use this API operation, make sure that your IAM policy authorizes you to perform this action on the device. The following example shows an IAM policy that allows the user permission to perform the `GetCommand` action.

In this example, replace:
+ `region` with your AWS Region, such as `us-east-1`.
+ `account-id` with your AWS account number, such as `123456789023`.
+ `command-id` with your AWS IoT unique command identifier, such as `LockDoor` or `Light_Power_Status`. If you want to retrieve more than one command, you can specify these commands under the *Resource* section in the IAM policy.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
        "Action": "iot:GetCommand",
        "Effect": "Allow",
        "Resource": "arn:aws:iot:us-east-1:123456789012:command/command-id"
    }
}
```

#### Retrieve a command example (AWS CLI)
<a name="iot-remote-command-get-example"></a>

The following example shows you how to retrieve information about a command using the `get-command` AWS CLI. Depending on your application, replace *`<command-id>`* with the identifier for the command for which you want to retrieve information. You can obtain this information from the response of the `create-command` CLI.

```
aws iot get-command --command-id <command-id>
```

Running this command generates a response that contains information about the command, the payload, and the time when it was created and last updated. It also provides information that indicates whether a command has been deprecated or is being deleted.

For example, the following code shows a sample response. 

```
{
    "commandId": "LockDoor",
    "commandArn": "arn:aws:iot:<region>:<account>:command/LockDoor",
    "namespace": "AWS-IoT",
    "payload":{
        "content": "eyAibWVzc2FnZSI6ICJIZWxsbyBJb1QiIH0=",
        "contentType": "application/json"
    },
    "createdAt": "2024-03-23T00:50:10.095000-07:00",
    "lastUpdatedAt": "2024-03-23T00:50:10.095000-07:00",
    "deprecated": false,
    "pendingDeletion": false
}
```

## List commands in your AWS account
<a name="iot-remote-command-list"></a>

After you have created commands, you can view the commands that you have created in your account. In the list, you can find information about:
+ The command ID, and any display name that you specified for the commands.
+ The Amazon resource name (ARN) of the commands.
+ The command state which indicates whether the commands are available to run on the target device, or whether they are deprecated.
**Note**  
The list does not display that are being deleted from your account. If the commands are pending deletion, you can still view the details for these commands using their command ID.
+ The time when the commands were created and last updated.

### List commands in your account (console)
<a name="iot-remote-command-list-console"></a>

In the AWS IoT console, you can find the list of commands that you created and their details by going to the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub).

### List commands in your account (CLI)
<a name="iot-remote-command-list-cli"></a>

To list the commands that you created, use the [https://docs.aws.amazon.com/iot/latest/apireference/API_ListCommands.html](https://docs.aws.amazon.com/iot/latest/apireference/API_ListCommands.html) API operation or the [https://docs.aws.amazon.com/cli/latest/reference/iot/list-commands.html](https://docs.aws.amazon.com/cli/latest/reference/iot/list-commands.html) CLI.

#### Sample IAM policy
<a name="iot-remote-command-list-iam"></a>

Before you use this API operation, make sure that your IAM policy authorizes you to perform this action on the device. The following example shows an IAM policy that allows the user permission to perform the `ListCommands` action.

In this example, replace:
+ `region` with your AWS Region, such as `us-east-1`.
+ `account-id` with your AWS account number, such as `123456789012`.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
        "Action": "iot:ListCommands",
        "Effect": "Allow",
        "Resource": "arn:aws:iot:us-east-1:123456789012:command/*"
    }
}
```

#### List commands in your account example
<a name="iot-remote-command-list-example"></a>

The following command shows how to list commands in your account.

```
aws iot list-commands --namespace "AWS-IoT"
```

Running this command generates a response that contains a list of commands that you created, the time when the commands were created and when it was last updated. It also provides the command state information, which indicates whether a command has been deprecated or is available to run on the target device. For more information about the different statuses and status reason, see [Command execution status](iot-remote-command-concepts.md#iot-command-execution-status).

## Update a command resource
<a name="iot-remote-command-update"></a>

After you have created a command, you can update the display name and description of the command.

**Note**  
The payload for the command can't be updated. To update this information or to use a modified payload, you'll need to create a new command.

### Update a command resource (console)
<a name="iot-remote-command-update-console"></a>

To update a command from the console, go to the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) of the AWS IoT console and perform the following steps.

1. To update an existing command resource, choose the command that you want to update, and then under **Actions**, choose **Edit**.

1. Specify the display name and description that you want to use, and any name-value pairs as tags for your command.

1. Choose **Edit** to save the command with the new settings.

### Update a command resource (CLI)
<a name="iot-remote-command-update-cli"></a>

Use the [https://docs.aws.amazon.com/iot/latest/apireference/API_UpdateCommand.html](https://docs.aws.amazon.com/iot/latest/apireference/API_UpdateCommand.html) control plane API operation or the [https://docs.aws.amazon.com/cli/latest/reference/iot/update-command.html](https://docs.aws.amazon.com/cli/latest/reference/iot/update-command.html) AWS CLI to update a command resource. Using this API, you can:
+ Edit the display name and description of a command that you created.
+ Deprecate a command resource, or restore a command that has already been deprecated.

#### Sample IAM policy
<a name="iot-remote-command-update-iam"></a>

Before you use this API operation, make sure that your IAM policy authorizes you to perform this action on the device. The following example shows an IAM policy that allows the user permission to perform the `UpdateCommand` action.

In this example, replace:
+ `region` with your AWS Region, such as `us-east-1`.
+ `account-id` with your AWS account number, such as `123456789012`.
+ `command-id` with your AWS IoT unique command identifier, such as `LockDoor`. If you want to retrieve more than one command, you can specify these commands under the *Resource* section in the IAM policy.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
        "Action": "iot:UpdateCommand",
        "Effect": "Allow",
        "Resource": "arn:aws:iot:us-east-1:123456789012:command/command-id"
    }
}
```

#### Update information about a command examples (AWS CLI)
<a name="iot-remote-command-update-example"></a>

The following example shows you how to update information about a command using the `update-command` AWS CLI command. For information about how you can use this API to deprecate or restore a command resource, see [Update a command resource (CLI)](iot-remote-command-deprecate.md#iot-remote-command-deprecate-cli).

The example shows how you can update the display name and description of a command. Depending on your application, replace *`<command-id>`* with the identifier for the command for which you want to retrieve information.

```
aws iot update-command \ 
    --command-id <command-id>    
    --displayname <display-name> \
    --description <description>
```

Running this command generates a response that contains the updated information about the command and the time when it was last updated. The following code shows a sample request and response for updating the display name and description of a command that turns off the AC.

```
aws iot update-command \ 
    --command-id <LockDoor> \ 
    --displayname <Secondary lock door> \
    --description <Locks doors to my home>
```

Running this command generates the following response.

```
{
    "commandId": "LockDoor",
    "commandArn": "arn:aws:iot:us-east-1:123456789012:command/LockDoor",
    "displayName": "Secondary lock door",
    "description": "Locks doors to my home",
    "lastUpdatedAt": "2024-05-09T23:15:53.899000-07:00"
}
```

## Deprecate or restore a command resource
<a name="iot-remote-command-deprecatecmd"></a>

After you have created a command, if no longer want to continue using the command, you can mark it as deprecated. When you deprecate a command, all pending command executions will continue running on the target device until they reach a terminal status. Once a command has been deprecated, if you want to use it such as for sending a new command execution to the target device, you must restore it.

**Note**  
You can't edit a deprecated command, or run any new executions for it. To run new commands on the device, you must restore it so that the command state changes to *Available*.

 For additional information about deprecating and restoring a command, and considerations for it, see [Deprecate a command resource](iot-remote-command-deprecate.md).

## Delete a command resource
<a name="iot-remote-command-delete"></a>

If you no longer want to use a command, you can remove it permanently from your account. If the deletion action is successful:
+ If the command has been deprecated for a duration that's longer than the maximum timeout of 12 hours, the command will be deleted immediately.
+ If the command isn't deprecated, or has been deprecated for a duration shorter than the maximum timeout, the command will be in a `pending deletion` state. It will be removed automatically from your account after the maximum timeout of 12 hours.

**Note**  
The command might be deleted even if there are any pending command executions. The command will be in a pending deletion state and will be removed from your account automatically.

### Delete a command resource (console)
<a name="iot-remote-command-delete-console"></a>

To delete a command from the console, go to the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) of the AWS IoT console and perform the following steps.

1. Choose the command that you want to delete, and and then under **Actions**, choose **Delete**.

1. Confirm that you want to delete the command and then choose **Delete**.

The command will be marked for deletion and will be permanently removed from your account after 12 hours.

### Delete a command resource (CLI)
<a name="iot-remote-command-delete-cli"></a>

Use the `DeleteCommand` HTTP control plane API operation or the `delete-command` AWS CLI command to delete a command resource. If the deletion action is successful, you'll see a HTTP `statusCode` of 204 or 202, and the command will be deleted from your account automatically after the maximum timeout duration of 12 hours. In the case of the 204 status, it indicates that the command has been deleted.

#### Sample IAM policy
<a name="iot-remote-command-delete-iam"></a>

Before you use this API operation, make sure that your IAM policy authorizes you to perform this action on the device. The following example shows an IAM policy that allows the user permission to perform the `DeleteCommand` action.

In this example, replace:
+ `region` with your AWS Region, such as `us-east-1`.
+ `account-id` with your AWS account number, such as `123456789012`.
+ `command-id` with your AWS IoT unique command identifier, such as `LockDoor`. If you want to retrieve more than one command, you can specify these commands under the *Resource* section in the IAM policy.

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": {
        "Action": "iot:DeleteCommand",
        "Effect": "Allow",
        "Resource": "arn:aws:iot:us-east-1:123456789012:command/command-id"
    }
}
```

#### Delete a command example (AWS CLI)
<a name="iot-remote-command-delete-example"></a>

The following examples show you how to delete a command using the `delete-command` AWS CLI command. Depending on your application, replace *`<command-id>`* with the identifier for the command that you're deleting.

```
aws iot delete-command --command-id <command-id>
```

If the API request is successful, then the command generates a status code of 202 or 204. You can use the `GetCommand` API to verify that the command no longer exists in your account.

# Start and monitor command executions
<a name="iot-remote-command-execution-start-monitor"></a>

After creating a Command, start an Execution on the target device. The device updates results and publishes status to MQTT reserved Topics. Retrieve and monitor Execution status from your account.

Start and monitor Commands using the AWS IoT console or AWS CLI.

**Topics**
+ [Start a command execution](#iot-remote-command-execution-start)
+ [Update the result of a command execution](#iot-remote-command-execution-update)
+ [Retrieve a command execution](#iot-remote-command-execution-get)
+ [Viewing commands updates using the MQTT test client](#iot-remote-command-execution-update-mqtt)
+ [List command executions in your AWS account](#iot-remote-command-execution-list)
+ [Delete a command execution](#iot-remote-command-execution-delete)

## Start a command execution
<a name="iot-remote-command-execution-start"></a>

**Important**  
You are solely responsible for deploying commands in a manner that is safe and compliant with applicable laws.

Before starting an Execution, ensure:
+ You created a Command in the AWS IoT namespace with Payload information. When starting Execution, the device processes Payload instructions and performs specified actions. See [Create a command resource](iot-remote-command-create-manage.md#iot-remote-command-create) for Command creation.
+ Your device subscribed to MQTT reserved Topics for Commands. When starting Execution, Payload information publishes to this reserved MQTT request Topic:

  *<devices>* can be Things or MQTT clients. *<DeviceID>* is the Thing name or Client ID. Supported *<PayloadFormat>* values: JSON and CBOR. For more information, see [Commands topics](reserved-topics.md#reserved-topics-commands).

  ```
  $aws/commands/<devices>/<DeviceID>/executions/+/request/<PayloadFormat>
  ```

  For non-JSON/CBOR *<PayloadFormat>*, use this Commands Topic format:

  ```
  $aws/commands/<devices>/<DeviceID>/executions/+/request
  ```

### Target device considerations
<a name="iot-command-execution-target"></a>

Specify the target device to receive and execute the Command. Use a Thing name for registered devices or Client ID for unregistered devices. After receiving the Payload, the device executes the Command and performs specified actions.

#### AWS IoT thing
<a name="iot-command-execution-target-thing"></a>

Target devices can be Things registered in the AWS IoT registry. Things simplify device search and management.

Register devices as Things from the [Connect device page](https://console.aws.amazon.com/iot/home#/connect-overview) or using [https://docs.aws.amazon.com/iot/latest/apireference/API_CreateThing.html](https://docs.aws.amazon.com/iot/latest/apireference/API_CreateThing.html). Find existing Things from [Thing Hub](https://console.aws.amazon.com/iot/home#/thinghub) or using [https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeThing.html](https://docs.aws.amazon.com/iot/latest/apireference/API_DescribeThing.html). See [Managing things with the registry](https://docs.aws.amazon.com/iot/latest/developerguide/thing-registry) for registration details.

#### Client ID
<a name="iot-command-execution-target-clientid"></a>

For unregistered devices, use the Client ID.

The Client ID is a unique identifier you assign to devices. Defined in the MQTT protocol, it contains alphanumeric characters, underscores, or dashes. Each device connecting to AWS IoT needs a unique Client ID.

**Note**  
For registered Things, the Client ID can match the Thing name.
When targeting a specific Client ID, devices must connect to AWS IoT using that Client ID to receive the Payload.

The Client ID is the MQTT client ID devices use when connecting to AWS IoT Core. AWS IoT uses this ID to identify devices and manage connections and subscriptions.

### Command execution timeout considerations
<a name="iot-command-execution-timeout"></a>

Timeout specifies the duration (in seconds) for devices to provide Execution results.

After creating an Execution, a timer starts. If the device goes offline or fails to report results within timeout, the Execution times out with status `TIMED_OUT`.

Default: 10 seconds. Maximum: 12 hours.

#### Time out value and `TIMED_OUT` execution status
<a name="iot-command-execution-timeout-status"></a>

Both cloud and device can report timeout.

After sending the Command, a timer starts. If no device response arrives within timeout, the cloud sets Execution status to `TIMED_OUT` with reason code `$NO_RESPONSE_FROM_DEVICE`.

This occurs when:
+ Device went offline during Execution.
+ Device failed to complete Execution within timeout.
+ Device failed to report status within timeout.

In this instance, when the execution status of `TIMED_OUT` is reported from the cloud, the command execution is non-terminal. Your device can publish a response that overrides the status to any of the terminal statuses: `SUCCEEDED`, `FAILED`, or `REJECTED`. The command execution then becomes terminal and doesn't accept any further updates.

Your device can also update a `TIMED_OUT` status initiated by the cloud by reporting that a timeout occurred when it was executing the command. In this case, the command execution status remains at `TIMED_OUT`, but the `statusReason` object is updated based on the information reported by the device. The command execution then becomes terminal, and no further updates are accepted.

#### Using MQTT persistent sessions
<a name="iot-command-execution-timeout-persistent"></a>

You can configure MQTT persistent sessions to use with the AWS IoT Device Management commands feature. This feature is especially useful in cases such as when your device goes offline and you want to make sure that the device still receives the command when it comes back online before the timeout duration, and performs the instructions specified.

By default, the MQTT persistent session expiry is set to 60 minutes. If your command execution timeout is configured to a value that exceeds this duration, command executions that run longer than 60 minutes can be rejected by the message broker and fail. To run commands that are longer than 60 minutes in duration, you can request an increase to the persistent session expiry time.

**Note**  
To ensure that you're using the MQTT persistent sessions feature correctly, set the Clean Start flag to zero. For more information, see [MQTT persistent sessions](https://docs.aws.amazon.com/iot/latest/developerguide/mqtt.html#mqtt-persistent-sessions).

### Start a command execution (console)
<a name="iot-remote-command-execution-start-console"></a>

To start running the command from the console, go to the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) page of the AWS IoT console and perform the following steps.

1. To run the command that you've created, choose **Run command**.

1. Review information about the command that you created, including the MQTT reserved topics, and parameters, if applicable.

   For dynamic commands, enter the parameter values or leave them with defaults. For parameters that do not have a default value, you must provide a value to be sent as part of this execution.

1. Specify the target device to receive and execute the Command. The device can be specified as an AWS IoT thing if it has been registered with AWS IoT, or using the client ID if your device has not been registered yet. For more information, see [Target device considerations](#iot-command-execution-target)

1. (Optional) Configure a timeout value for the command that determines the duration for which you want the command to run before it times out. If your command needs to run longer than 60 minutes, you may have to increase the MQTT persistent sessions expiry time. For more information, see [Command execution timeout considerations](#iot-command-execution-timeout).

1. Choose **Run command**.

### Start a command execution (AWS CLI)
<a name="iot-remote-command-execution-start-cli"></a>

Use the [https://docs.aws.amazon.com/iot/latest/apireference/API_StartCommandExecution.html](https://docs.aws.amazon.com/iot/latest/apireference/API_StartCommandExecution.html) HTTP data plane API operation to start a command execution. The API request and response are correlated by the command execution ID. After the device completes executing the command, it can report the status and execution result to the cloud by publishing a message to the commands response topic. For a custom response code, application codes that you own can process the response message and post the result to AWS IoT.

If your devices have subscribed to the commands request topic, the `StartCommandExecution` API will publish the payload message to the topic. The payload can use any format of your choice. For more information, see [Command payload](iot-remote-command-create-manage.md#iot-commands-payload).

```
$aws/commands/<devices>/<DeviceID>/executions/+/request/<PayloadFormat>
```

If the payload format is not JSON or CBOR, the following shows the format of the commands request topic.

```
$aws/commands/<devices>/<DeviceID>/executions/+/request
```

#### Sample IAM policy
<a name="iot-remote-command-execution-start-policy"></a>

Before you use this API operation, make sure that your IAM policy authorizes you to perform this action on the device. The following example shows an IAM policy that allows the user permission to perform the `StartCommandExecution` action.

In this example, replace:
+ `region` with your AWS Region, such as `us-east-1`.
+ `account-id` with your AWS account number, such as `123456789012`.
+ `command-id` with a unique identifier for your AWS IoT command, such as `LockDoor`. If you want to send more than one command, you can specify these commands in the IAM policy.
+ `devices` with either `thing` or `client` depending on whether your devices have been registered as AWS IoT things, or are specified as MQTT clients.
+ `device-id` with your AWS IoT `thing-name` or `client-id`.

```
{
  "Effect": "Allow",
  "Action": [
      "iot:StartCommandExecution"
  ],
  "Resource": [
      "arn:aws:iot:region:account-id:command/command-id",
      "arn:aws:iot:region:account-id:devices/device-id"
  ]
}
```

To see a list of condition keys supported for `StartCommandExecution`, see [Condition Keys for AWS IoT](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awsiot.html#awsiot-policy-keys) in the *IAM User Guide*.

#### Obtain account-specific data plane endpoint
<a name="iot-remote-command-execution-start-endpoint"></a>

Before you run the API command, you must obtain the account-specific endpoint URL for the endpoint. If you're using dual-stack endpoints (IPv4 and IPv6), use the `iot:Data-ATS`. The `iot:Jobs` endpoint is for IPv4 only. For example, if you run this command:

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

It returns the account-specific endpoint URL as shown in the sample response below.

```
{
    "endpointAddress":
    "<account-specific-prefix>-ats.iot.<region>.api.com"
}
```

#### Start a command execution example (AWS CLI)
<a name="iot-remote-command-execution-start-example"></a>

The following example displays how to start executing a command using the `start-command-execution` AWS CLI command.

In this example, replace:
+ *`<command-arn>`* with the ARN for the command that you want to execute. You can obtain this information from the response of the `create-command` CLI command. For example, if you're executing the command for changing the steering wheel mode, use `arn:aws:iot:region:account-id:command/SetComfortSteeringMode`.
+ *`<target-arn>`* with the Thing ARN for the target device, which can be an IoT thing or MQTT client, for which you want to execute the command. For example, if you're executing the command for the target device `myRegisteredThing`, use `arn:aws:iot:region:account-id:thing/myRegisteredThing`.
+ *`<endpoint-url>`* with the account-specific endpoint that you obtained in [Obtain account-specific data plane endpoint](#iot-remote-command-execution-start-endpoint), prefixed by `https://`. For example, `https://123456789012abcd.jobs.iot.us-east-1.amazonaws.com`.
+ (Optional) You can also specify an additional parameter, `executionTimeoutSeconds`, when performing the `StartCommandExecution` API operation. This optional field specifies the time in seconds within which the device must complete executing the command. By default, the value is 10 seconds. When the command execution status is `CREATED`, a timer starts. If the command execution result is not received before the timer expires, then the status automatically changes to `TIMED_OUT`.
+ 

  ```
  aws iot-jobs-data start-command-execution \
      --command-arn <command-arn>  \
      --target-arn <target-arn> \  
      --endpoint <endpoint-url> \ 
      --execution-timeout-seconds 900
  ```
+ (Optional) For dynamic commands, specify the parameters and their values to be used for substitution. You must provide a value for parameters that do not have a defaultValue set at command creation. If a parameter has a defaultValue, the parameter value provided here takes precedence. For parameters that have valueConditions set, the parameter value provided here must satisfy the condition.

  Based on `Light_Power_Status` dynamic command example:
+ 

  ```
  aws iot-jobs-data start-command-execution \
      --command-arn arn:aws:iot:us-east-1:123456789012:command/Light_Power_Status  \
      --target-arn arn:aws:iot:us-east-1:123456789012:thing/exampleThing \
      --endpoint <endpoint-url> \
      --execution-timeout-seconds 900 \
      --parameters "powerStatus={S=ON}"
  ```

Running this command returns a command execution ID. You can use this ID to query the command execution status, details, and command execution history.

**Note**  
If the command has been deprecated, then the `StartCommandExecution` API request will fail with a validation exception. To fix this error, first restore the command using the `UpdateCommand` API, and then perform the `StartCommandExecution` request.

```
{
    "executionId": "07e4b780-7eca-4ffd-b772-b76358da5542"
}
```

## Update the result of a command execution
<a name="iot-remote-command-execution-update"></a>

Use the `UpdateCommandExecution` MQTT data plane API operation to update the status or result of a command execution.

**Note**  
Before you use this API:  
Your device must have established an MQTT connection and subscribed to the commands request and response topics. For more information, see [High-level commands workflow](iot-remote-command-workflow.md).
You must have already executed this command using the `StartCommandExecution` API operation.

### Sample IAM policy
<a name="iot-remote-command-execution-update-policy"></a>

Before you use this API operation, make sure that your IAM policy authorizes your device to perform these actions. Following shows an example policy that authorizes your device to perform the action. For additional sample IAM policies that allow the user permission to perform the `UpdateCommandExecution` MQTT action, see [Connect and publish policy examples](connect-and-pub.md).

In this example, replace:
+ `Region` with your AWS Region, such as `us-east-1`.
+ `AccountID` with your AWS account number, such as *`123456789012`*.
+ `ThingName` with the name of your AWS IoT thing for which you are targeting the command execution, such as *`myRegisteredThing`*.
+ `commands-request-topic` and `commands-response-topic` with the names of your AWS IoT commands request and response topics. For more information, see [High-level commands workflow](iot-remote-command-workflow.md).

#### Sample IAM policy for MQTT client ID
<a name="iot-remote-command-execution-update-policy-client"></a>

The following code shows a sample device policy when using MQTT client ID.

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/clients/${iot:ClientId}/executions/*/response",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/clients/${iot:ClientId}/executions/*/response/json"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/clients/${iot:ClientId}/executions/*/request",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/clients/${iot:ClientId}/executions/*/response/accepted",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/clients/${iot:ClientId}/executions/*/response/rejected",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/clients/${iot:ClientId}/executions/*/request/json",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/clients/${iot:ClientId}/executions/*/response/accepted/json",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/clients/${iot:ClientId}/executions/*/response/rejected/json"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/clients/${iot:ClientId}/executions/+/request",
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/clients/${iot:ClientId}/executions/+/response/accepted",
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/clients/${iot:ClientId}/executions/+/response/rejected",
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/clients/${iot:ClientId}/executions/+/request/json",
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/clients/${iot:ClientId}/executions/+/response/accepted/json",
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/clients/${iot:ClientId}/executions/+/response/rejected/json"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:us-east-1:123456789012:client/${iot:ClientId}"
    }
  ]
}
```

#### Sample IAM policy for IoT thing
<a name="iot-remote-command-execution-update-policy-thing"></a>

The following code shows a sample device policy when using an AWS IoT thing.

****  

```
{
  "Version":"2012-10-17",		 	 	 
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "iot:Publish",
      "Resource": "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/*/response"
    },
    {
      "Effect": "Allow",
      "Action": "iot:Receive",
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/*/request",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/*/response/accepted",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/*/response/rejected",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/*/request/json",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/*/response/accepted/json",
        "arn:aws:iot:us-east-1:123456789012:topic/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/*/response/rejected/json"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Subscribe",
      "Resource": [
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/+/request",
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/+/response/accepted",
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/+/response/rejected",
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/+/request/json",
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/+/response/accepted/json",
        "arn:aws:iot:us-east-1:123456789012:topicfilter/$aws/commands/things/${iot:Connection.Thing.ThingName}/executions/+/response/rejected/json"
      ]
    },
    {
      "Effect": "Allow",
      "Action": "iot:Connect",
      "Resource": "arn:aws:iot:us-east-1:123456789012:client/${iot:ClientId}"
    }
  ]
}
```

### How to use the `UpdateCommandExecution` API
<a name="iot-remote-command-execution-update-works"></a>

After the command execution is received at the request topic, the device processes the command. It then uses the `UpdateCommandExecution` API to update the status and result of the command execution to the following response topic.

```
$aws/commands/<devices>/<DeviceID>/executions/<ExecutionId>/response/<PayloadFormat>
```

In this example, *`<DeviceID>`* is the unique identifier of your target device, and *`<execution-id>`* is the identifier of the command execution on the target device. The *<PayloadFormat>* can be JSON or CBOR.

**Note**  
If you haven't registered your device with AWS IoT, you can use the client ID as your identifier instead of a thing name.

```
$aws/commands/clients/<ClientID>/executions/<ExecutionId>/response/<PayloadFormat>
```

#### Device reported updates to execution status
<a name="iot-command-execution-reported"></a>

Your devices can use the API to report any of the following status updates to the command execution. For more information about these statuses, see [Command execution status](iot-remote-command-concepts.md#iot-command-execution-status).
+ `IN_PROGRESS`: When the device starts executing the command, it can update the status to `IN_PROGRESS`.
+ `SUCCEEDED`: When the device successfully processes the command and completes executing it, the device can publish a message to the response topic as `SUCCEEDED`.
+ `FAILED`: If the device failed to execute the command, it can publish a message to the response topic as `FAILED`.
+ `REJECTED`: If the device failed to accept the command, it can publish a message to the response topic as `REJECTED`.
+ `TIMED_OUT`: The command execution status can change to `TIMED_OUT` due to any of the following reasons.
  + The result of the command execution wasn't received. This can happen because the execution wasn't completed within the specified duration, or if the device failed to publish the status information to the response topic.
  + The device reports that a time out occurred when attempting to execute the command.

For more information about the `TIMED_OUT` status, see [Time out value and `TIMED_OUT` execution status](#iot-command-execution-timeout-status).

#### Considerations when using the `UpdateCommandExecution` API
<a name="iot-remote-command-execution-update-considerations"></a>

The following are some important considerations when using the `UpdateCommandExecution` API.
+ Your devices can use an optional `statusReason` object to provide additional information about the execution. If your devices provide this object, the `reasonCode` field of the object is required, but the `reasonDescription` field is optional.
+ When your devices use the `statusReason` object, the `reasonCode` must use the pattern `[A-Z0-9_-]+` and not exceed 64 characters in length. If you provide the `reasonDescription`, ensure that it doesn't exceed 1,024 characters in length. It can use any characters except control characters such as newlines.
+ Your devices can use an optional `result` object to provide information about the result of the command execution, such as the return value of a remote function call. If you provide the `result`, it must require at least one entry.
+ In the `result` field, you specify the entries as key-value pairs. For each entry, you must specify the data type information as a string, boolean, or binary. A string data type must use the key `s`, a boolean data type uses the key `b`, and a binary data type must use the key `bin`. Ensure that these keys are lowercase.
+ If you encounter an error when running the `UpdateCommandExecution` API, you can view the error in the `AWSIoTLogsV2` log group in Amazon CloudWatch. For information about enabling logging and viewing the logs, see [Configure AWS IoT logging](configure-logging.md).

#### `UpdateCommandExecution` API example
<a name="iot-remote-command-execution-update-example"></a>

The following code shows an example of how your device can use the `UpdateCommandExecution` API to report the execution status, the `statusReason` field to provide additional information about the status, and the result field to provide information about the result of the execution, such as the car battery percentage in this case.

```
{
  "status": "IN_PROGRESS",
  "statusReason": {
    "reasonCode": "200",
    "reasonDescription": "Execution_in_progress"
  },
  "result": {
        "car_battery": {
            "s": "car battery at 50 percent"
        }
    }
}
```

## Retrieve a command execution
<a name="iot-remote-command-execution-get"></a>

After you run a command, you can retrieve information about the command execution from the AWS IoT console and using the AWS CLI. You can obtain the following information.

**Note**  
To retrieve the latest command execution status, your device must publish the status information to the response topic using the `UpdateCommandExecution` MQTT API, as described below. Until the device publishes to this topic, the `GetCommandExecution` API will report the status as `CREATED` or `TIMED_OUT`.

Each command execution that you create will have:
+ An **Execution ID**, which is a unique identifier of the command execution.
+ The **Status** of the command execution. When you run the command on the target device, the command execution enters a `CREATED` state. It can then transition to other command execution statuses as described below.
+ The **Result** of the command execution.
+ The unique **Command ID** and the target device for which executions have been created.
+ The **Start date**, which shows the time when the command execution was created.

### Retrieve a command execution (console)
<a name="iot-remote-command-execution-get-console"></a>

You can retrieve a command execution from the console using either of the following methods.
+ 

**From the Command hub page**  
Go to the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) page of the AWS IoT console and perform these steps.

  1. Choose the command for which you created an execution on the target device.

  1. In the command details page, on the **Command history** tab, you'll see the executions that you created. Choose the execution for which you want to retrive information.

  1. If your devices used the `UpdateCommandExecution` API to provide the result information, you can then find this information in the **Results** tab of this page.
+ 

**From the Thing hub page**  
If you chose an AWS IoT thing as your target device when running the command, you can view the execution details from the Thing hub page.

  1. Go to the [Thing Hub](https://console.aws.amazon.com/iot/home#/thinghub) page in the AWS IoT console and choose the thing for which you created the command execution.

  1. In the thing details page, on the **Command history**, you'll see the executions that you created. Choose the execution for which you want to retrive information.

  1. If your devices used the `UpdateCommandExecution` API to provide the result information, you can then find this information in the **Results** tab of this page.

### Retrieve a command execution (CLI)
<a name="iot-remote-command-execution-get-cli"></a>

Use the [https://docs.aws.amazon.com/iot/latest/apireference/API_GetCommandExecution.html](https://docs.aws.amazon.com/iot/latest/apireference/API_GetCommandExecution.html) AWS IoT Core control plane HTTP API operation to retrieve information about a command execution. You must have already executed this command using the `StartCommandExecution` API operation.

#### Sample IAM policy
<a name="iot-remote-command-execution-get-policy"></a>

Before you use this API operation, make sure that your IAM policy authorizes you to perform this action on the device. The following example shows an IAM policy that allows the user permission to perform the `GetCommandExecution` action.

In this example, replace:
+ `region` with your AWS Region, such as `us-east-1`.
+ `account-id` with your AWS account number, such as `123456789012`.
+ `command-id` with your unique AWS IoT command identifier, such as `LockDoor`.
+ `devices` with either `thing` or `client` depending on whether your devices have been registered as AWS IoT things, or are specified as MQTT clients.
+ `device-id` with your AWS IoT `thing-name` or `client-id`.

```
{
  "Effect": "Allow",
  "Action": [
      "iot:GetCommandExecution"
  ],
  "Resource": [
      "arn:aws:iot:region:account-id:command/command-id",
      "arn:aws:iot:region:account-id:devices/device-id"
  ]
}
```

#### Retrieve a command execution example
<a name="iot-remote-command-execution-get-example"></a>

The following example shows you how to retrieve information about a command that was executed using the `start-command-execution` AWS CLI command. The following example shows how you can retrieve information about a command that was executed to turn off the steering wheel mode.

In this example, replace:
+ *`<execution-id>`* with the identifier for the command execution for which you want to retrieve information.
+ *`<target-arn>`* with the Amazon Resource Number (ARN) of the device for which you're targeting the execution. You can obtain this information from the response of the `start-command-execution` CLI command.
+ Optionally, if your devices used the `UpdateCommandExection` API to provide the execution result, you can specify whether to include the command execution result in the response of the `GetCommandExecution` API using the `GetCommandExecution` API.

```
aws iot get-command-execution  
    --execution-id <execution-id> \ 
    --target-arn <target-arn> \
    --include-result
```

Running this command generates a response that contains information about the ARN of the command execution, the execution status, and the time when it started executing, and when it completed. It also provides a `statusReason` object that contains additional information about the status. For more information about the different statuses and status reason, see [Command execution status](iot-remote-command-concepts.md#iot-command-execution-status). 

The following code shows a sample response from the API request.

**Note**  
The `completedAt` field in the execution response corresponds to the time when the device reports a terminal status to the cloud. In the case of `TIMED_OUT` status, this field will be set only when the device reports a time out. When the `TIMED_OUT` status is set by the cloud, the `TIMED_OUT` status is not updated. For more information about the time out behavior, see [Command execution timeout considerations](#iot-command-execution-timeout).

```
{
    "executionId": "07e4b780-7eca-4ffd-b772-b76358da5542",
    "commandArn": "arn:aws:iot:us-east-1:123456789012:command/LockDoor",
    "targetArn": "arn:aws:iot:us-east-1:123456789012:thing/myRegisteredThing",
    "status": "SUCCEEDED",
    "statusReason": {
        "reasonCode": "DEVICE_SUCCESSFULLY_EXECUTED",
        "reasonDescription": "SUCCESS"
    },
    "result": {
        "sn": { "s": "ABC-001" },
        "digital": { "b": true }        
    },
    "createdAt": "2024-03-23T00:50:10.095000-07:00",
    "completedAt": "2024-03-23T00:50:10.095000-07:00"    
}
```

## Viewing commands updates using the MQTT test client
<a name="iot-remote-command-execution-update-mqtt"></a>

You can use the MQTT test client to view the message exchange over MQTT when using the commands feature. After your device establishes an MQTT connection with AWS IoT, you can create a command, specify the payload, and then run it on the device. When you run the command, if your device subscribed to the MQTT reserved request topic for commands, it sees the payload message published to this topic.

The device then receives the payload instructions and performs the specified operations on the AWS IoT device. It then uses the `UpdateCommandExecution` API to publish the command execution result and status information to the MQTT reserved response topics for commands. AWS IoT Device Management listens to updates on the response topics and stores the updated information and publishes logs to AWS CloudTrail and Amazon CloudWatch. You can then retrieve the latest command execution information from the console or by using the `GetCommandExecution` API.

The following steps show how to use the MQTT test client to observe messages.

1. Open the [MQTT test client](https://console.aws.amazon.com/iot/home#/test) in the AWS IoT console.

1. On the **Subscribe** tab, enter the following topic and then choose **Subscribe**, where *<thingId>* is the thing name of the device that you have registered with AWS IoT.
**Note**  
You can find the thing name for your device from the [Thing Hub](https://console.aws.amazon.com/iot/home#/thinghub) page of the AWS IoT console. If you haven't registered your device as a thing, you can register the device when connecting to AWS IoT from the [Connect device page](https://console.aws.amazon.com/iot/home#/connect-overview).

   ```
   $aws/commands/things/<thingId>/executions/+/request
   ```

1. (Optional) On the **Subscribe** tab, you can also enter the following topics and choose **Subscribe**.

   ```
   $aws/commands/things/+/executions/+/response/accepted/json
   $aws/commands/things/+/executions/+/response/rejected/json
   ```

1. When you start a command execution, the message payload will be sent to the device using the request topic that the device has subscribed to, `$aws/commands/things/<thingId>/executions/+/request`. In the MQTT test client, you should see the command payload that contains the instructions for the device to process the command.

1. After the device starts executing the command, it can publish status updates to the following MQTT reserved response topic for commands.

   ```
   $aws/commands/<devices>/<device-id>/executions/<executionId>/response/json
   ```

   For example, consider a command that you executed to turn on the AC of your car to reduce the temperature to a desired value. The following JSON shows a sample message that the vehicle published to the response topic which shows that it failed to execute the command.

   ```
   {
     "deviceId": "My_Car",
     "executionId": "07e4b780-7eca-4ffd-b772-b76358da5542",
     "status": "FAILED",
     "statusReason": {
       "reasonCode": "CAR_LOW_ON_BATTERY",
       "reasonDescription": "Car battery is lower than 5 percent"
     }
   }
   ```

   In this case, you can charge your car's battery and then run the command again.

## List command executions in your AWS account
<a name="iot-remote-command-execution-list"></a>

After you run a command, you can retrieve information about the command execution from the AWS IoT console and using the AWS CLI. You can obtain the following information.
+ An **Execution ID**, which is a unique identifier of the command execution.
+ The **Status** of the command execution. When you run the command on the target device, the command execution enters a `CREATED` state. It can then transition to other command execution statuses as described below.
+ The unique **Command ID** and the target device for which executions have been created.
+ The **Start date**, which shows the time when the command execution was created.

### List command executions in your account (console)
<a name="iot-remote-command-execution-list-console"></a>

You can see all the command executions from the console using either of the following methods.
+ 

**From the Command hub page**  
Go to the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) page of the AWS IoT console and perform these steps.

  1. Choose the command for which you created an execution on the target device.

  1. In the command details page, go to the **Command history** tab, and you'll see a list of executions that you created.
+ 

**From the Thing hub page**  
If you chose an AWS IoT thing as your target device when running the command, and created multiple command executions for a single device, you can view the executions for the device from the Thing hub page.

  1. Go to the [Thing Hub](https://console.aws.amazon.com/iot/home#/thinghub) page in the AWS IoT console and choose the thing for which you created the executions.

  1. In the thing details page, on the **Command history**, you'll see a list of executions that you created for the device.

### List command executions in your account (CLI)
<a name="iot-remote-command-execution-list-cli"></a>

Use the [https://docs.aws.amazon.com/iot/latest/apireference/API_ListCommandExecutions.html](https://docs.aws.amazon.com/iot/latest/apireference/API_ListCommandExecutions.html) AWS IoT Core control plane HTTP API operation to list all command executions in your account.

#### Sample IAM policy
<a name="iot-remote-command-execution-list-policy"></a>

Before you use this API operation, make sure that your IAM policy authorizes you to perform this action on the device. The following example shows an IAM policy that allows the user permission to perform the `ListCommandExecutions` action.

In this example, replace:
+ `region` with your AWS Region, such as `us-east-1`.
+ `account-id` with your AWS account number, such as `123456789012`.
+ `command-id` with your unique AWS IoT command identifier, such as `LockDoor`.

```
{
  "Effect": "Allow",
  "Action": "iot:ListCommandExecutions",
  "Resource": *
}
```

#### List command executions example
<a name="iot-remote-command-execution-list-example"></a>

The following example shows you how to list command executions in your AWS account.

When running the command, you must specify whether to filter the list to display only command executions that were created for a particular device using the `targetArn`, or executions for a particular command specified using the `commandArn`.

In this example, replace:
+ *`<target-arn>`* with the Amazon Resource Number (ARN) of the device for which you're targeting the execution, such as `arn:aws:iot:us-east-1:123456789012:thing/b8e4157c98f332cffb37627f`.
+ *`<target-arn>`* with the Amazon Resource Number (ARN) of the device for which you're targeting the execution, such as `arn:aws:iot:us-east-1:123456789012:thing/b8e4157c98f332cffb37627f`.
+ *`<after>`* with the time after which you want to list the executions that were created, for example, `2024-11-01T03:00`.

```
aws iot list-command-executions \ 
--target-arn <target-arn> \ 
--started-time-filter '{after=<after>}' \
--sort-order "ASCENDING"
```

Running this command generates a response that contains a list of command executions that you created, and the time when the executions started executing, and when it completed. It also provides status information, and the `statusReason` object that contains additional information about the status.

```
{
    "commandExecutions": [
        {
            "commandArn": "arn:aws:iot:us-east-1:123456789012:command/TestMe002",
            "executionId": "b2b654ca-1a71-427f-9669-e74ae9d92d24",
            "targetArn": "arn:aws:iot:us-east-1:123456789012:thing/b8e4157c98f332cffb37627f",
            "status": "TIMED_OUT",
            "createdAt": "2024-11-24T14:39:25.791000-08:00",
            "startedAt": "2024-11-24T14:39:25.791000-08:00"
        },
        {
            "commandArn": "arn:aws:iot:us-east-1:123456789012:command/TestMe002",
            "executionId": "34bf015f-ef0f-4453-acd0-9cca2d42a48f",
            "targetArn": "arn:aws:iot:us-east-1:123456789012:thing/b8e4157c98f332cffb37627f",
            "status": "IN_PROGRESS",
            "createdAt": "2024-11-24T14:05:36.021000-08:00",
            "startedAt": "2024-11-24T14:05:36.021000-08:00"
        }
    ]
}
```

For more information about the different statuses and status reason, see [Command execution status](iot-remote-command-concepts.md#iot-command-execution-status).

## Delete a command execution
<a name="iot-remote-command-execution-delete"></a>

If you no longer want to use a command execution, you can remove it permanently from your account.

**Note**  
A command execution can be deleted only if it has entered a terminal status, such as `SUCCEEDED`, `FAILED`, or `REJECTED`.
This operation can be performed only using the AWS IoT Core API or the AWS CLI. It is not available from the console.

### Sample IAM policy
<a name="iot-remote-command-execution-delete-policy"></a>

Before you use this API operation, make sure that your IAM policy authorizes your device to perform these actions. Following shows an example policy that authorizes your device to perform the action.

In this example, replace:
+ `Region` with your AWS Region, such as `us-east-1`.
+ `AccountID` with your AWS account number, such as *`123456789012`*.
+ `CommandID` with the identifier of the command for which you want to delete the execution.
+ `devices` with either `thing` or `client` depending on whether your devices have been registered as AWS IoT things, or are specified as MQTT clients.
+ `device-id` with your AWS IoT `thing-name` or `client-id`.

```
{
  "Effect": "Allow",
  "Action": [
      "iot:DeleteCommandExecution"
  ],
  "Resource": [
      "arn:aws:iot:region:account-id:command/command-id",
      "arn:aws:iot:region:account-id:devices/device-id"
  ]
}
```

### Delete a command execution example
<a name="iot-remote-command-execution-delete-example"></a>

The following example shows you how to delete a command using the `delete-command` AWS CLI command. Depending on your application, replace *`<execution-id>`* with the identifier for the command execution that you're deleting, and the *`<target-arn>`* with the ARN of your target device. 

```
aws iot delete-command-execution \ 
--execution-id <execution-id> \ 
--target-arn <target-arn>
```

If the API request is successful, then the command execution generates a status code of 200. You can use the `GetCommandExecution` API to verify that the command execution no longer exists in your account.

# Deprecate a command resource
<a name="iot-remote-command-deprecate"></a>

Deprecate commands to indicate they are outdated and should not be used. For example, deprecate commands no longer actively maintained or when creating newer commands with the same ID but different payloads.

## Key considerations
<a name="iot-remote-command-deprecate-considerations"></a>

Important considerations when deprecating commands:
+ Deprecating a command does not delete it. You can retrieve the command using its ID and restore it for reuse.
+ Attempting to start new executions on deprecated commands generates an error, preventing use of outdated commands.
+ To execute a deprecated command, first restore it. After restoration, the command becomes available for regular use and execution on target devices.
+ If you deprecate a command while executions are in progress, they continue running until completion. You can still retrieve execution status.

## Deprecate a command resource (console)
<a name="iot-remote-command-deprecate-console"></a>

To deprecate a command from the console, go to the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) of the AWS IoT console and perform the following steps.

1. Choose the command that you want to deprecate, and then under **Actions**, choose **Deprecate**.

1. Confirm that you want to deprecate the command and then choose **Deprecate**.

## Deprecate a command resource (CLI)
<a name="iot-remote-command-deprecate-cli"></a>

Mark commands as deprecated using the `update-command` CLI. You must deprecate a command before deletion. To use a deprecated command, restore it first.

```
aws iot update-command \ 
    --command-id <command-id> \ 
    --deprecated
```

For example, if you deprecated the `ACSwitch` command that you updated in the example above, the following code shows a sample output of running the command.

```
{
    "commandId": "turnOffAc",
    "deprecated": true,
    "lastUpdatedAt": "2024-05-09T23:16:51.370000-07:00"
}
```

## Check deprecation time and status
<a name="iot-remote-command-deprecate-check"></a>

Use the `GetCommand` API to determine if a command is deprecated and when it was last deprecated.

```
aws iot get-command --command-id <turnOffAC>
```

This command generates a response containing command information, including creation and deprecation timestamps from the last updated field. This helps determine command lifetime and whether to delete or reuse it. The following shows a sample response for the `turnOffAc` command:

```
{
    "commandId": "turnOffAC",
    "commandArn": "arn:aws:iot:us-east-1:123456789012:command/turnOffAC",
    "namespace": "AWS-IoT",
    "payload": {
        "content": "testPayload.json",
        "contentType": "application/json"
    },
    "createdAt": "2024-03-23T00:50:10.095000-07:00",
    "lastUpdatedAt": "2024-05-09T23:16:51.370000-07:00",
    "deprecated": false
}
```

## Restore a command resource
<a name="iot-remote-command-undeprecate"></a>

To use or send the `ACSwitch` command to your device, restore it first.

To restore a command from the console, go to the [Command Hub](https://console.aws.amazon.com/iot/home#/commandHub) of the AWS IoT console, choose the command that you want to restore, and then under **Actions**, choose **Restore**.

To restore a command using the AWS IoT Core API or the AWS CLI, use the `UpdateCommand` API operation or the `update-command` CLI. The following code shows a sample request and response.

```
aws iot update-command \ 
    --command-id <command-id> 
    --no-deprecated
```

The following code shows a sample output.

```
{
    "commandId": "ACSwitch",
    "deprecated": false,
    "lastUpdatedAt": "2024-05-09T23:17:21.954000-07:00"
}
```