> ## 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.

# List Firmware Releases

> Published firmware releases for your organization

Bota builds and publishes firmware; you choose which release a device runs. This
returns the releases available to your organization, newest first.

Pass `device_id` to narrow the list to what that device can install. Without it
you get everything published to your organization.

Unpublished releases are never returned. A release that is still being prepared
has a placeholder checksum and may have no uploaded image behind it, so there is
nothing you could safely install from it.

## Authentication

Requires an [API key](/authentication) with `devices:read` scope.

## Query Parameters

<ParamField query="device_id" type="string">
  Return only releases this device can install (e.g., `dev_abc123`). The device
  must belong to the project your key is scoped to, otherwise the request is a
  `404`.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.bota.dev/v1/firmware-releases?device_id=dev_abc123" \
    -H "Authorization: Bearer sk_live_..."
  ```

  ```javascript Node.js theme={null}
  const response = await fetch(
    'https://api.bota.dev/v1/firmware-releases?device_id=dev_abc123',
    { headers: { 'Authorization': 'Bearer sk_live_...' } },
  );

  const { data: releases } = await response.json();
  const latest = releases[0];
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      'https://api.bota.dev/v1/firmware-releases',
      params={'device_id': 'dev_abc123'},
      headers={'Authorization': 'Bearer sk_live_...'},
  )

  releases = response.json()['data']
  latest = releases[0] if releases else None
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": [
      {
        "id": "fw_3kQ9mZa7Rp2XvB4nT6yL8cW1",
        "version": "1.0.7",
        "changelog": "Fixes a battery drain during long Bluetooth sessions.",
        "is_released": true,
        "bin_sha256": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        "bin_file_size_bytes": 1048576,
        "ufw_sha256": "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9",
        "ufw_file_size_bytes": 1150000,
        "created_at": "2026-08-14T09:12:00Z",
        "updated_at": "2026-08-14T10:02:00Z"
      }
    ]
  }
  ```

  ```json 404 (device_id not in this project) theme={null}
  {
    "error": {
      "code": "not_found",
      "message": "Device not found"
    }
  }
  ```
</ResponseExample>

## Response Fields

| Field | Type | Description |
| - | - | - |
| `id` | string | Release identifier (`fw_*`). Treat it as opaque. |
| `version` | string | Firmware version, e.g. `1.0.7` |
| `changelog` | string \| null | What changed in this release |
| `is_released` | boolean | Always `true` here — this endpoint returns published releases only |
| `bin_sha256` | string | SHA-256 of the `.bin` image, used by the WiFi and cellular update path |
| `bin_file_size_bytes` | number | Size of the `.bin` image |
| `ufw_sha256` | string | SHA-256 of the `.ufw` image. Used by Bota's own tooling — Bluetooth transfer is not a supported integration path. |
| `ufw_file_size_bytes` | number | Size of the `.ufw` image |
| `created_at` | string | ISO 8601 |
| `updated_at` | string | ISO 8601 |

## Notes

* Releases are scoped to your organization and shared across its projects.
* The list is newest-first. Do not infer "latest" from the version string —
  a rollback publishes an older version as the newest release.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.