> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bota.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Update Device

> Update device metadata and settings

## Overview

Updates device metadata (firmware version, custom metadata) and/or device settings (upload configuration, audio quality, power management).

This endpoint performs a **partial update** - only fields included in the request body are modified.

## Authentication

Requires a valid API key with `devices:write` scope.

<RequestExample>
  ```bash cURL theme={null}
  curl -X PATCH https://api.bota.dev/v1/devices/dev_abc123 \
    -H "Authorization: Bearer sk_live_..." \
    -H "Content-Type: application/json" \
    -d '{
      "firmware_version": "1.3.0",
      "settings": {
        "connection": {
          "enabled_connections": { "wifi": true, "cellular": false },
          "upload_network_preference": ["wifi", "ble"]
        }
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const device = await bota.devices.update('dev_abc123', {
    firmware_version: '1.3.0',
    settings: {
      connection: {
        enabled_connections: { wifi: true, cellular: false },
        upload_network_preference: ['wifi', 'ble']
      }
    }
  });
  ```

  ```python Python theme={null}
  device = bota.devices.update('dev_abc123', {
    'firmware_version': '1.3.0',
    'settings': {
      'connection': {
        'enabled_connections': { 'wifi': True, 'cellular': False },
        'upload_network_preference': ['wifi', 'ble']
      }
    }
  })
  ```
</RequestExample>

## Path Parameters

<ParamField path="id" type="string" required>
  Device ID (e.g., `dev_abc123`)
</ParamField>

## Request Body

All fields are optional. Only include what you want to update.

<ParamField body="firmware_version" type="string">
  Firmware version string (max 32 chars)
</ParamField>

<ParamField body="metadata" type="object">
  Custom key-value metadata
</ParamField>

<ParamField body="settings" type="object">
  Device configuration (upload, audio, power)

  <Expandable title="settings properties">
    <ParamField body="connection" type="object">
      Connection configuration (which connections are enabled and network preference)

      <Expandable title="connection properties">
        <ParamField body="enabled_connections" type="object">
          Which connections are available. Bluetooth is always enabled and cannot be disabled.

          <Expandable title="enabled_connections properties">
            <ParamField body="wifi" type="boolean">
              Enable WiFi uploads (default: `true`)
            </ParamField>

            <ParamField body="cellular" type="boolean">
              Enable cellular uploads (default: `true`)
            </ParamField>
          </Expandable>
        </ParamField>

        <ParamField body="upload_network_preference" type="string[]">
          Ordered list of connection types for network preference. Values: `wifi`, `ble`, `cellular`. No duplicates. Default: `["wifi", "ble", "cellular"]`
        </ParamField>

        <ParamField body="power_management" type="object">
          Radio idle timeout configuration. Powers down WiFi/cellular radio after inactivity to save battery.

          <Expandable title="power_management properties">
            <ParamField body="wifi_idle_timeout_seconds" type="integer">
              WiFi radio idle timeout in seconds. `-1` = never power down, `0` = power down immediately after work completes, positive values wait before power-down. Range: `-1`, `0`, or `10`-`2540`. Default: `180` (3 minutes).
            </ParamField>

            <ParamField body="cellular_idle_timeout_seconds" type="integer">
              Cellular radio idle timeout in seconds. `-1` = never power down, `0` = power down immediately after work completes, positive values wait before power-down. Range: `-1`, `0`, or `10`-`2540`. Default: `180` (3 minutes).
            </ParamField>
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="upload" type="object">
      Upload behavior configuration

      <Expandable title="upload properties">
        <ParamField body="streaming_enabled" type="boolean">
          Upload chunks while recording (streaming upload mode)
        </ParamField>

        <ParamField body="streaming_chunk_kb" type="integer">
          Streaming chunk size in KB. Range: `64`-`1024`. Default: `256`.
        </ParamField>

        <ParamField body="daily_data_limit_mb" type="integer">
          Max cellular data per day in MB (`0`-`10000`). `0` = unlimited.
        </ParamField>

        <ParamField body="allow_roaming" type="boolean">
          Allow cellular uploads when roaming
        </ParamField>

        <ParamField body="pause_on_low_battery" type="boolean">
          Pause uploads when battery is low
        </ParamField>

        <ParamField body="off_peak_hours" type="object">
          Schedule uploads during off-peak hours only

          <Expandable title="off_peak_hours properties">
            <ParamField body="enabled" type="boolean">
              Enable off-peak scheduling
            </ParamField>

            <ParamField body="start" type="string">
              Start time in `HH:MM` format (e.g., `"22:00"`)
            </ParamField>

            <ParamField body="end" type="string">
              End time in `HH:MM` format (e.g., `"06:00"`)
            </ParamField>

            <ParamField body="timezone" type="string">
              IANA timezone (e.g., `"America/New_York"`)
            </ParamField>
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="audio" type="object">
      Audio quality configuration

      <Expandable title="audio properties">
        <ParamField body="codec" type="string">
          `opus` | `aac` | `wav`
        </ParamField>

        <ParamField body="sample_rate_khz" type="integer">
          `16` | `24` | `48`
        </ParamField>

        <ParamField body="bitrate_kbps" type="integer">
          `8` - `320`
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField body="power" type="object">
      Power management configuration

      <Expandable title="power properties">
        <ParamField body="auto_sleep_minutes" type="integer">
          Auto-sleep timeout (1-120)
        </ParamField>

        <ParamField body="low_battery_threshold_percent" type="integer">
          Low battery threshold (5-30)
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>
</ParamField>

## Response

Returns the updated device object with all settings (including defaults).

<ResponseExample>
  ```json 200 theme={null}
  {
    "id": "dev_abc123",
    "serial_number": "SN-2025-001234",
    "model": "bota_pin",
    "firmware_version": "1.3.0",
    "status": "bound",
    "end_user_id": "eu_xyz789",
    "metadata": {},
    "settings": {
      "connection": {
        "enabled_connections": { "wifi": true, "cellular": false },
        "upload_network_preference": ["wifi", "ble"],
        "power_management": {
          "wifi_idle_timeout_seconds": 180,
          "cellular_idle_timeout_seconds": 180
        }
      },
      "upload": {
        "streaming_enabled": true,
        "streaming_chunk_kb": 256,
        "daily_data_limit_mb": 500,
        "allow_roaming": false,
        "pause_on_low_battery": true,
        "off_peak_hours": null
      },
      "audio": {
        "codec": "opus",
        "sample_rate_khz": 16,
        "bitrate_kbps": 32
      },
      "power": {
        "auto_sleep_minutes": 30,
        "low_battery_threshold_percent": 20
      }
    },
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": "2025-01-15T14:20:00Z"
  }
  ```

  ```json 404 theme={null}
  {
    "error": {
      "code": "not_found",
      "message": "Device not found"
    }
  }
  ```
</ResponseExample>

## Response Fields

| Field                 | Type            | Description                                                                  |
| --------------------- | --------------- | ---------------------------------------------------------------------------- |
| `id`                  | string          | Device identifier (`dev_*`)                                                  |
| `serial_number`       | string          | Physical serial number                                                       |
| `model`               | string          | Device model (`bota_pin` or `bota_note`)                                     |
| `firmware_version`    | string \| null  | Current firmware version                                                     |
| `status`              | string          | `unbound` or `bound`                                                         |
| `end_user_id`         | string \| null  | Bound end user (`eu_*`)                                                      |
| `battery_percent`     | integer \| null | Battery level (0-100)                                                        |
| `storage_used_mb`     | integer \| null | Storage used in MB                                                           |
| `storage_total_mb`    | integer \| null | Total storage capacity in MB                                                 |
| `signal_strength_dbm` | integer \| null | Signal strength in dBm                                                       |
| `last_heartbeat_at`   | string \| null  | Last heartbeat timestamp (ISO 8601)                                          |
| `recording_state`     | object \| null  | Current recording state                                                      |
| `metadata`            | object          | Custom key-value metadata                                                    |
| `settings`            | object          | Device settings including connection, upload, audio, and power configuration |
| `created_at`          | string          | Creation timestamp (ISO 8601)                                                |
| `updated_at`          | string          | Last update timestamp (ISO 8601)                                             |

## Examples

### Update Connection Settings Only

```bash cURL theme={null}
curl -X PATCH https://api.bota.dev/v1/devices/dev_abc123 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"settings": {"connection": {"upload_network_preference": ["cellular", "wifi", "ble"]}}}'
```

### Configure Radio Idle Timeouts

```bash cURL theme={null}
curl -X PATCH https://api.bota.dev/v1/devices/dev_abc123 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"settings": {"connection": {"power_management": {"wifi_idle_timeout_seconds": 300, "cellular_idle_timeout_seconds": 60}}}}'
```

### Update Firmware Version

```bash cURL theme={null}
curl -X PATCH https://api.bota.dev/v1/devices/dev_abc123 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"firmware_version": "1.4.0"}'
```

### Update Custom Metadata

```bash cURL theme={null}
curl -X PATCH https://api.bota.dev/v1/devices/dev_abc123 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{"metadata": {"department": "Sales", "region": "West"}}'
```

### Travel Mode Preset

```bash cURL theme={null}
curl -X PATCH https://api.bota.dev/v1/devices/dev_abc123 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "settings": {
      "connection": {
        "enabled_connections": { "wifi": true, "cellular": false },
        "upload_network_preference": ["wifi", "ble"]
      },
      "upload": {
        "allow_roaming": false
      }
    }
  }'
```

## Notes

<Info>
  **Settings Merge:** When updating `settings`, a deep merge is performed. Only the specified nested fields are updated; others remain unchanged.
</Info>

<Info>
  **Defaults Included:** The response always includes complete settings with defaults filled in, even if you only updated one field.
</Info>

## Related Endpoints

* [Get Device](/api-reference/devices/get) - Fetch device details
* [Create Device](/api-reference/devices/create) - Create new device
* [Bind Device](/api-reference/devices/bind) - Bind to end user
