# LitmusEdgeManager 2.31.x API Documentation/Edge Lifecycle Management/AI/ML Models - LE, LEM, LUNS API Docs

## Step 1 of Upload New AI/ML Model

**POST** `{{LEM_URL}}/api/v1/file/{{project_id}}/mlModel/motionModel.zip/upload-url`

# Step 1 of Upload New AI/ML Model

Step 1 of a three-step pre-signed-URL upload flow. LEM returns an upload URL signed by its object storage; step 2 uploads the file to that URL.
## Endpoint

```http
POST {{LEM_URL}}/api/v1/file/{{project_id}}/mlModel/motionModel.zip/upload-url
```
## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.
## Request body

```json
{
  "projectId": "{{project_id}}",
  "fileName": "motionModel.zip"
}
```

## Response

`200 OK` -- `application/json`

```json
{ "url": "https://10.17.3.103/files/.../motionModel.zip?..." }
```

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Request Body

```json
{
    "projectId": "{{project_id}}",
    "fileName": "motionModel.zip"
}
```

### Response

**Status**: 200 OK

```json
{
    "url": "https://10.17.3.103/files/462j1mq70mph31wa100t1yuxa/mlModel/motionModel.zip?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ZBE3Hey7R88GtiYw%2F20241218%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20241218T141532Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=8a7fd062731b25a2bd3887e11fa790a5e26436430ee1509424108b0252e494ca"
}
```

---

## Step 2 of Upload New AI?ML Model

**PUT** `{{LEM_URL}}/files/{{project_id}}/mlModel/motionModel.zip?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ZBE3Hey7R88GtiYw%2F20241218%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20241218T141532Z&X-Amz-Expires=604800&X-Amz-SignedHeaders=host&X-Amz-Signature=8a7fd062731b25a2bd3887e11fa790a5e26436430ee1509424108b0252e494ca`

# Step 2 of Upload New AI/ML Model

Step 2: PUT the file bytes to the pre-signed URL returned by step 1. This call goes **directly to the storage backend**, not the LEM API. (The Postman item's name has a typo: `AI?ML`.)
## Endpoint

```http
PUT {{LEM_URL}}/files/{{project_id}}/mlModel/motionModel.zip?<signing-params>
```
## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.
## Request body

Raw binary upload of the model ZIP.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

---

## Step 3 of Upload New Model

**POST** `{{LEM_URL}}/api/v1/file/{{project_id}}/mlModel/motionModel.zip`

# Step 3 of Upload New Model

Step 3: notify LEM that the upload is complete. LEM records the metadata and makes the file available for `Deploy ML model`.
## Endpoint

```http
POST {{LEM_URL}}/api/v1/file/{{project_id}}/mlModel/motionModel.zip
```
## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.
## Request body

```json
{ "description": "" }
```

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Request Body

```json
{
    "description": ""
}
```

### Response

**Status**: 200 OK

```json
{
    "code": "S",
    "message": null,
    "messageDetails": null
}
```

---

## Deploy ML model

**POST** `{{LEM_URL}}/api/v1/async-task/task-with-subtasks`

# Deploy ML Model

Deploys a staged AI/ML model to one or more devices via an async task. Body is the same async-task envelope as `Applications > Launch Application to Edge Device`; the task type is `ANALYTICS_ML_MODEL_UPLOAD`.
## Endpoint

```http
POST {{LEM_URL}}/api/v1/async-task/task-with-subtasks
```
## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.
## Request body

```json
{
  "name": "Upload AI/ML Models (1 edge device)",
  "projectId": "{{project_id}}",
  "subtasks": [
    {
      "deviceId": "{{edge_device_id}}",
      "num": 0,
      "params": { "fileName": "motionModel.zip" },
      "type": "ANALYTICS_ML_MODEL_UPLOAD"
    }
  ],
  "type": "ANALYTICS_ML_MODEL_UPLOAD",
  "waitForOnline": false
}
```

## Response

`200 OK` -- `application/json`

```json
{ "taskId": "ca549da1-e645-4f21-8865-487cb5a4aac1" }
```

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Request Body

```json
{
    "name": "Upload AI/ML Models (1 edge device)",
    "description": "",
    "params": {},
    "projectId": "{{project_id}}",
    "subtasks": [
        {
            "deviceId": "{{edge_device_id}}",
            "num": 0,
            "params": {
                "fileName": "motionModel.zip"
            },
            "type": "ANALYTICS_ML_MODEL_UPLOAD",
            "plannedExecTime": 0
        }
    ],
    "type": "ANALYTICS_ML_MODEL_UPLOAD",
    "waitForOnline": false
}
```

### Response

**Status**: 200 OK

```json
{
    "taskId": "ca549da1-e645-4f21-8865-487cb5a4aac1"
}
```

---

## Verify If Deploy Task is Complete

**GET** `{{LEM_URL}}/api/v1/async-task/{{task_id}}/subtasks`

# Verify If Deploy Task is Complete

Returns the subtasks for one async task with their progress, status, and per-device messages. Use to monitor a deployment.
## Endpoint

```http
GET {{LEM_URL}}/api/v1/async-task/{{task_id}}/subtasks
```
## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.
## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

```json
[
    {
        "id": "5dda70d0-5d2a-489f-85d9-c3169620f1f1",
        "taskId": "20bb4e40-5656-43c5-880b-4cf0fa9c4d07",
        "num": 0,
        "deviceId": "vkrih85ka6fn7zcofirk20vs",
        "devicePrettyName": "VM",
        "type": "ANALYTICS_ML_MODEL_UPLOAD",
        "params": {
            "fileName": "motionModel.zip"
        },
        "plannedExecTime": 0,
        "progress": 1,
        "status": "SUCCESS",
        "msg": null,
        "startTime": 1734532298000,
        "stopTime": 1734532298000,
        "context": null,
        "createdOn": 1734532294000,
        "updatedOn": 1734532298000,
        "createdBy": "parthshah",
        "updatedBy": "parthshah",
        "done": true
    }
]
```

---

## Get Models

**GET** `{{LEM_URL}}/api/v1/analytics/{{project_id}}/models`

# Get Models

Returns the AI/ML models currently installed on every device in the project. Each device record carries `totalSize` plus an array of `models[]` with name, absolute path, and size.
## Endpoint

```http
GET {{LEM_URL}}/api/v1/analytics/{{project_id}}/models
```
## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.
## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

```json
{
    "pageNum": 0,
    "pagesCount": 1,
    "size": 3,
    "totalSize": 3,
    "elements": [
        {
            "projectId": "462j1mq70mph31wa100t1yuxa",
            "deviceId": "1a5wiavluwxuhwai5leb1v0hc",
            "hostname": "litmus-edge-94c6911b9c77",
            "prettyName": "Litmus Edge (94:c6:91:1b:9c:77)- SJ office sensor",
            "isOnline": true,
            "totalSize": 141852176,
            "models": [
                {
                    "name": "coco",
                    "absolutePath": "/var/lib/loopedge-analytics2/models/coco",
                    "size": 136145199,
                    "deploymentSource": "LE"
                },
                {
                    "name": "gasFive.tflite",
                    "absolutePath": "/var/lib/loopedge-analytics2/models/gasFive.tflite",
                    "size": 101132,
                    "deploymentSource": "LE"
                },
                {
                    "name": "motionModel",
                    "absolutePath": "/var/lib/loopedge-analytics2/models/motionModel",
                    "size": 5094648,
                    "deploymentSource": "LE"
                },
                {
                    "name": "savedmodel4",
                    "absolutePath": "/var/lib/loopedge-analytics2/models/savedmodel4",
                    "size": 511197,
                    "deploymentSource": "LE"
                },
                {
                    "name": ".ipynb_checkpoints",
                    "absolutePath": "/var/lib/loopedge-analytics2/models/.ipynb_checkpoints",
                    "size": 0,
                    "deploymentSource": "LE"
                }
            ],
            "online": true
        },
        {
            "projectId": "462j1mq70mph31wa100t1yuxa",
            "deviceId": "3y0vcdju38zvqjrlm5lcpm1l",
            "hostname": "litmus-edge-080027b4a1c8",
            "prettyName": "Litmus Edge (08:00:27:b4:a1:c8)",
            "isOnline": false,
            "totalSize": 5094648,
            "models": [
                {
                    "name": "motionModel",
                    "absolutePath": "/var/lib/loopedge-analytics2/models/motionModel",
                    "size": 5094648,
                    "deploymentSource": "LE"
                }
            ],
            "online": false
        },
        {
            "projectId": "462j1mq70mph31wa100t1yuxa",
            "deviceId": "vkrih85ka6fn7zcofirk20vs",
            "hostname": "litmus-edge-005056b965c2",
            "prettyName": "VM",
            "isOnline": true,
            "totalSize": 0,
            "models": [],
            "online": true
        }
    ]
}
```

---

## Models List

**GET** `{{LEM_URL}}/api/v1/analytics/{{project_id}}/model-list`

# Models List

Returns a flat **aggregated** list of model names across the project's devices, with total size and the number of devices running each model.
## Endpoint

```http
GET {{LEM_URL}}/api/v1/analytics/{{project_id}}/model-list
```
## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.
## Response

`200 OK` -- `application/json`. Array of `{name, size, count}` objects.

## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

```json
[
    {
        "name": ".ipynb_checkpoints",
        "size": 0,
        "count": 1
    },
    {
        "name": "savedmodel4",
        "size": 511197,
        "count": 1
    },
    {
        "name": "coco",
        "size": 136145199,
        "count": 1
    },
    {
        "name": "gasFive.tflite",
        "size": 101132,
        "count": 1
    },
    {
        "name": "motionModel",
        "size": 5094648,
        "count": 2
    }
]
```

---

## Get Models on Edge Manager

**GET** `{{LEM_URL}}/api/v1/file/{{project_id}}/list`

# Get Models on Edge Manager

Returns the AI/ML models **uploaded to LEM** (not yet deployed). These are staging files in LEM's file store ready for deployment.
## Endpoint

```http
GET {{LEM_URL}}/api/v1/file/{{project_id}}/list
```
## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.
## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


### Response

**Status**: 200 OK

```json
{
    "pageNum": 0,
    "pagesCount": 1,
    "size": 1,
    "totalSize": 1,
    "elements": [
        {
            "name": "motionModel.zip",
            "size": 0,
            "lastModified": 1734531634590,
            "fileType": "mlModel",
            "description": ""
        }
    ]
}
```

---

## Delete Model on LEM

**DELETE** `{{LEM_URL}}/api/v1/file/{{project_id}}/{fileType}/{fileName}`

# Delete Model on LEM

Removes a staged file from LEM's file store. Pass `fileType` (`mlModel`) and `fileName` in the path.
## Endpoint

```http
DELETE {{LEM_URL}}/api/v1/file/{{project_id}}/{fileType}/{fileName}
```
## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. Tokens are managed under `System > Access Control > Tokens`.
## Errors

| HTTP status         | When it happens                                                                |
|---------------------|--------------------------------------------------------------------------------|
| `400 Bad Request`   | Missing or malformed query/body parameter.                                     |
| `401 Unauthorized`  | Missing or invalid credentials.                                                |
| `403 Forbidden`     | Token lacks permission for this operation.                                     |
| `404 Not Found`     | Target entity does not exist.                                                  |
| `5xx`               | Service is unreachable, restarting, or internally errored. Inspect device logs under `System > Support`. |

> **TLS note**: edge devices use a self-signed certificate by default. Either install the device CA in your client trust store or disable certificate verification when calling this endpoint directly.


---

