> ## 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 Device OTA History

> Every firmware assignment a device has had, newest first

Every assignment this device has had, newest first — including the ones that
were applied, failed, or called off. Use it to answer "what has this device been
through" rather than "what is happening now".

## Authentication

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

## Path Parameters

<ParamField path="id" type="string" required>
  The device's unique identifier (e.g., `dev_abc123`).
</ParamField>

## Query Parameters

<ParamField query="limit" type="number" default="10">
  How many assignments to return, 1–100.
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.bota.dev/v1/devices/dev_abc123/ota/history?limit=5" \
    -H "Authorization: Bearer sk_live_..."
  ```

  ```javascript Node.js theme={null}
  const { data: history } = await fetch(
    'https://api.bota.dev/v1/devices/dev_abc123/ota/history?limit=5',
    { headers: { 'Authorization': 'Bearer sk_live_...' } },
  ).then((r) => r.json());

  const failures = history.filter((a) => a.status === 'failed');
  ```

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

  history = requests.get(
      'https://api.bota.dev/v1/devices/dev_abc123/ota/history',
      params={'limit': 5},
      headers={'Authorization': 'Bearer sk_live_...'},
  ).json()['data']

  failures = [a for a in history if a['status'] == 'failed']
  ```
</RequestExample>

<ResponseExample>
  ```json 200 theme={null}
  {
    "data": [
      {
        "id": "ota_7Rp2XvB4nT6yL8cW1kQ9mZa3",
        "device_id": "dev_abc123",
        "firmware_release_id": "fw_3kQ9mZa7Rp2XvB4nT6yL8cW1",
        "status": "applied",
        "assigned_at": "2026-08-14T12:00:00Z",
        "delivered_at": "2026-08-14T12:01:30Z",
        "applied_at": "2026-08-14T12:06:12Z",
        "error_message": null
      },
      {
        "id": "ota_2XvB4nT6yL8cW1kQ9mZa3Rp7",
        "device_id": "dev_abc123",
        "firmware_release_id": "fw_9mZa3Rp2XvB4nT6yL8cW1kQ8",
        "status": "cancelled",
        "assigned_at": "2026-08-12T09:40:00Z",
        "delivered_at": null,
        "applied_at": null,
        "error_message": null
      }
    ]
  }
  ```

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

## Response Fields

Each entry has the same shape as
[Get Device OTA Status](/api-reference/firmware/get-ota), where the `status`
values are also documented.

## Notes

* `failed` covers two different things: the device reported a failure, and the
  assignment was settled because the device moved between projects. Where a
  reason exists it is in `error_message`.
* `cancelled` means an operator called the assignment off. It is deliberately
  distinct from `failed` so a real failure is not confused with a decision.


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