> For the complete documentation index, see [llms.txt](https://api.intecular.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://api.intecular.com/invisoutlet-pro/ota/perform-ota-update.md).

# Perform OTA Update

> Perform an OTA update for InvisOutlet, InvisDeco, or both devices as one ordered full update.

## Request

* <mark style="color:red;">`packetID`</mark>: The packet ID. This can be any six-digit number with no leading zeros.
* <mark style="color:red;">`payload.callbackName`</mark>: `21`
* <mark style="color:red;">`payload.callbackArgs[0]`</mark>: OTA target.
  * `1` — InvisOutlet only
  * `2` — InvisDeco only
  * `3` — Full update: InvisDeco first, then InvisOutlet
* <mark style="color:red;">`payload.callbackArgs[1]`</mark>: InvisDeco transport.
  * `0` — InvisDeco downloads its firmware over Wi-Fi
  * `1` — InvisOutlet downloads the InvisDeco firmware and transfers it over UART

The transport value is ignored when the target is `1`.

| `callbackArgs` | Operation                                                                    |
| -------------- | ---------------------------------------------------------------------------- |
| `[1,0]`        | Update InvisOutlet                                                           |
| `[2,0]`        | Update InvisDeco over Wi-Fi                                                  |
| `[2,1]`        | Update InvisDeco through InvisOutlet UART                                    |
| `[3,0]`        | Full update: InvisDeco over Wi-Fi, then InvisOutlet over Wi-Fi               |
| `[3,1]`        | Full update: InvisDeco through InvisOutlet UART, then InvisOutlet over Wi-Fi |

{% hint style="info" %}
If the InvisDeco Wi-Fi method is unreliable in the installation environment, use `[2,1]` for an InvisDeco-only update or `[3,1]` for a full update through InvisOutlet.
{% endhint %}

### Full update over Wi-Fi

```json
{
    "packetID": 414883,
    "payload": {
        "callbackName": 21,
        "callbackArgs": [3, 0]
    }
}
```

### Full update with InvisDeco over UART

```json
{
    "packetID": 414884,
    "payload": {
        "callbackName": 21,
        "callbackArgs": [3, 1]
    }
}
```

## Full update sequence

For target `3`, InvisOutlet treats both firmware updates as one ordered transaction:

1. InvisDeco starts and completes its update using the selected transport.
2. A successful InvisDeco result advances the transaction to the InvisOutlet update.
3. InvisOutlet downloads and installs its firmware over Wi-Fi.
4. The pending transaction state is retained across a reset so an interrupted sequence can resume safely.

The sequence is fail-closed. If the InvisDeco stage fails, the InvisOutlet stage is cancelled. This prevents the two devices from ending on an unintended firmware combination.

Progress and result events are emitted separately for each stage. Clients receive InvisDeco events first (`callbackArgs[0] = 2`), followed by InvisOutlet events (`callbackArgs[0] = 1`, and `3` when the WWW partition is updated).

## Response (revA)

The initial response confirms whether the request was accepted.

* <mark style="color:red;">`sn`</mark>: InvisOutlet serial number.
* <mark style="color:red;">`packetID`</mark>: The request packet ID.
* <mark style="color:red;">`PUBACK`</mark>:
  * `1` — Request accepted and the update will start.
  * `0` — Request rejected or could not be initialized. A full update is also rejected when InvisDeco is offline or another full update is active.

```json
{
    "sn": "0003C44076",
    "packetID": 414883,
    "PUBACK": 1
}
```

## Response (revB, synchronous)

* <mark style="color:red;">`payload.callbackName`</mark>: `21`
* <mark style="color:red;">`payload.callbackArgs[0]`</mark>: Device whose OTA is starting.
  * `1` — InvisOutlet
  * `2` — InvisDeco
* <mark style="color:red;">`payload.callbackArgs[1]`</mark>:
  * `1` — OTA can continue.
  * `0` — OTA initialization failed.

```json
{
    "sn": "0003C44076",
    "packetID": 414883,
    "payload": {
        "callbackName": 21,
        "callbackArgs": [2, 1]
    }
}
```

{% hint style="info" %}
Some hardware revisions restart or disconnect during OTA. Reconnect the TCP/WebSocket client and continue listening for the remaining stage events.
{% endhint %}

{% hint style="info" %}
Follow the transaction through OTA Download Progress (Synchronous) and OTA Result Update (Synchronous). Synchronous update messages use newly generated packet IDs, not the original request packet ID.
{% endhint %}
