# Asynchronous Tasks

import { Stepper } from "zudoku/ui/Stepper";

Beyond reading data, the API can execute tasks on devices. Because tasks take time to complete on
physical devices, they run asynchronously. You execute a task, get a `taskId` back immediately, and
poll for completion.

A single task runs across one or more devices. The work on each individual device is a device task,
and the overall task is done once every device task is completed.

This page describes the pattern. The per-task-type payload fields are documented in the
[API Reference](/api).

:::lock

`POST /v1/tasks` requires Admin or Operator permissions. To enable it for your account, please
[contact our support team](mailto:cs_engineers@securithings.com).

:::

## The lifecycle

<Stepper>

1. **Execute the task**

   Send `POST /v1/tasks` with a `taskType` and the devices to run it on. For tasks that require
   configuration, use `defaultPayload` to apply the same configuration to every device, or set a
   `payload` per device.

   ```json
   {
     "taskType": "restartDevice",
     "devices": [
       { "deviceId": "9ff559ee-38b6-11f1-81cb-465864a35d0a" },
       { "deviceId": "dc7d4ef1-6bf9-11f1-b083-d27bafcacdf8" }
     ]
   }
   ```

1. **Take the task ID**

   The response returns the ID of the created task.

   ```json
   { "taskId": "23bpozz1mpjjedtr" }
   ```

1. **Poll until every device task is completed**

   `GET /v1/tasks/{id}` returns one entry per device task.

   ```json
   {
     "userName": "service-account-integrator_1",
     "deviceTasks": [
       {
         "createDate": "2026-07-15T10:13:14.000Z",
         "currentStepStatus": "runSucceeded",
         "deviceHost": "192.168.2.69",
         "deviceId": "9ff559ee-38b6-11f1-81cb-465864a35d0a",
         "deviceModel": "P3265-LV",
         "deviceName": "192.168.2.69 - Unit",
         "deviceTaskId": "366717",
         "result": "succeeded",
         "status": "completed",
         "taskId": "23bpozz1mpjjedtr",
         "taskType": "restartDevice"
       },
       {
         "createDate": "2026-07-15T10:13:14.000Z",
         "currentStepStatus": "runSucceeded",
         "deviceHost": "192.168.2.70",
         "deviceId": "dc7d4ef1-6bf9-11f1-b083-d27bafcacdf8",
         "deviceModel": "P3265-LV",
         "deviceName": "192.168.2.70 - Unit",
         "deviceTaskId": "366718",
         "result": "succeeded",
         "status": "completed",
         "taskId": "23bpozz1mpjjedtr",
         "taskType": "restartDevice"
       }
     ],
     "total": 2
   }
   ```

</Stepper>

:::info

`status` tells you whether a device task has finished (`pending`, `running`, `completed`), and
`result` tells you how it finished (`succeeded`, `failed`, `rolledBack`, `aborted`). `result` is
`null` until the device task completes, so always check both.

:::

:::zap

Add `includeSteps=true` to `GET /v1/tasks/{id}` to include the per-step breakdown of each device
task. Steps increase the response size considerably, so they are not returned by default. Request
them only when a device task fails and further information is required to investigate it.

:::

## Check availability first

Not every device supports every task. Device objects expose an `availableTask` map, so check it
before executing:

```json
"availableTask": {
  "hardenDevice": false,
  "restartDevice": true,
  "rotate8021xCertificate": false,
  "rotatePassword": true,
  "rotateSslCertificate": true,
  "upgradeFirmware": true
}
```
