# Update Device Status

Source: https://help.zira.us/developers/api-reference/update-device-status
Summary: Update CV device status and trigger diagnostic alert evaluation.
Updated: 2026-08-06

## `POST /devices/status/{id}`

Use this endpoint when an integration needs to report device health or operational state for a specific CV device.

## Authentication

```http
x-api-key: <your-api-key>
Content-Type: application/json
```

See [API Authentication](/developers/api-reference/api-authentication) for how to create a key.

## Path parameters

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | yes | ID of the data source whose device status you are reporting. |

## Request body

Send a `status` object describing the device’s current health. Report the full set of fields every time.

```json
{
  "status": {
    "battery": 82,
    "isCharging": true,
    "onLine": true,
    "deviceOn": true,
    "cameraOn": true,
    "wifiConnected": true,
    "cellularConnected": false,
    "temperature": 31.5,
    "version": "2.14.0"
  }
}
```

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | object | yes | The device’s current health and operational state. Its fields are listed below. |
| `status.battery` | number | no | Battery charge as a percentage. A low value raises an alert unless `isCharging` is true. |
| `status.isCharging` | boolean | no | Whether the device is currently charging. |
| `status.onLine` | boolean | no | Whether the device can reach Zira. |
| `status.deviceOn` | boolean | no | Whether the device itself is powered on and running. |
| `status.cameraOn` | boolean | no | Whether the camera is active. |
| `status.wifiConnected` | boolean | no | Whether Wi-Fi is connected. Send at least one connected network flag. |
| `status.cellularConnected` | boolean | no | Whether a cellular connection is up. |
| `status.ethernetConnected` | boolean | no | Whether a wired connection is up. |
| `status.temperature` | number | no | Device temperature in °C. A high value raises an alert. |
| `status.version` | string | no | Software version running on the device. |

## Response

`200 OK`

Returns the fixed string `"SUCCESS"` once the status has been stored. Nothing about the device or the alerts that were raised is echoed back — a `200` means "status recorded", not "device healthy".

```json
{
  "data": "SUCCESS"
}
```

| Field | Type | Description |
| --- | --- | --- |
| `data` | string | Always the literal `"SUCCESS"` on a 200. |

### Good to know

- Status values are not validated — they are evaluated. An unhealthy or missing value raises an alert for the device instead of failing your request, and you still get a `200`.
- Because of that, send the full set every time: `battery`, `onLine`, `deviceOn`, `cameraOn`, `wifiConnected` and `cellularConnected`. A field you leave out is treated as if it were bad news.
- Re-reporting a healthy status is how you clear alerts you raised earlier — Zira resolves an alert once the new status no longer triggers it.
- The device is identified by the path segment, not by a `deviceId` in the body.
- The reported status shows up in Zira as the data source’s device status.
- Errors from this endpoint are unusually detailed compared with the rest of the API. Do not treat that detail as a stable contract, and do not show it to end users.

## Errors

Failures return a JSON body with a `message` and an `internalErrorCode`, at the status shown below. Whenever the underlying error carries structured detail — which every schema-validation failure does — the body is replaced with a generic `Internal server error.` / `02-001` pair while the real status code is kept. Branch on the HTTP status and on `internalErrorCode`; never parse the message text.

```json
{
  "message": "Internal server error.",
  "internalErrorCode": "02-001"
}
```

| Status | Meaning |
| --- | --- |
| `400` | The request failed validation — a missing required field, a field the schema does not allow, an unparseable body, a value out of range, or a malformed `lastValue`. |
| `401` | The API key resolved to a user context that is not allowed to read or write the record you asked for. |
| `403` | The `x-api-key` header is missing or is not a recognised key. API Gateway rejects the call before the endpoint runs, so the body is only `{"message":"Forbidden"}`. |
| `409` | The write conflicts with an existing record, or it references a record that does not exist. |
| `429` | The API key exceeded the rate limit or quota on its usage plan. Also returned by API Gateway rather than the endpoint. |
| `500` | Unexpected server error, or the database returned no result where one was required. |
