# Litmus Edge 4.4.x - DeviceHub: Subscriptions

## Subscribe Browse Task Changed

**POST** `{{edgeUrl}}/devicehub/v2`

# Subscribe Browse Task Changed

> **WebSocket subscription**: run this over the GraphQL-over-WebSocket protocol at `wss://{{edgeHost}}/devicehub/v2` (`graphql-transport-ws`). In Postman, create a WebSocket request and send the subscription as a `subscribe` message payload -- a plain HTTP POST will not stream events.

WebSocket subscription. Convert to a Postman WebSocket request after import (URL: wss://.../devicehub/v2).

## Endpoint

``` http
POST {{edgeUrl}}/devicehub/v2
Content-Type: application/json
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. The same token is valid across `/devicehub/v2`, `/analytics/v2`, `/cc`, `/opcua`, and the other LE services.

## Request body (GraphQL)

``` graphql
subscription BrowseTaskChanged {
    BrowseTaskChanged {
        ID DeviceID DisplayName Status StatusDescription FoldersCount ItemsCount SizeOnDiskBytes
    }
}
```

## Errors

GraphQL endpoints return `200 OK` even on logical errors. Inspect the `errors` array in the response body:

``` json
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
```

| `extensions.code` | Meaning |
| --- | --- |
| `UNAUTHENTICATED` | Missing or invalid API token. |
| `FORBIDDEN` | Token lacks permission for this operation. |
| `BAD_USER_INPUT` | Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
| `NOT_FOUND` | The targeted entity does not exist. |
| `INTERNAL_SERVER_ERROR` | DeviceHub fault. Retry, then escalate via `System > Support`. |

A non-`200` HTTP response means DeviceHub itself is unreachable. See `Dashboard > DeviceHub Status`.

> **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

**GraphQL Query**

```graphql
subscription BrowseTaskChanged {
    BrowseTaskChanged {
        ID DeviceID DisplayName Status StatusDescription FoldersCount ItemsCount SizeOnDiskBytes
    }
}
```

---

## Subscribe Device State Changed

**POST** `{{edgeUrl}}/devicehub/v2`

# Subscribe Device State Changed

> **WebSocket subscription**: run this over the GraphQL-over-WebSocket protocol at `wss://{{edgeHost}}/devicehub/v2` (`graphql-transport-ws`). In Postman, create a WebSocket request and send the subscription as a `subscribe` message payload -- a plain HTTP POST will not stream events.

WebSocket subscription. State enum: StartedConnected | StartedDisconnected | StartedUnknown | Stopped | Created | Starting | Stopping | Updated | Deleted | WDActivated | WDStopping | WDStarting.

## Endpoint

``` http
POST {{edgeUrl}}/devicehub/v2
Content-Type: application/json
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. The same token is valid across `/devicehub/v2`, `/analytics/v2`, `/cc`, `/opcua`, and the other LE services.

## Request body (GraphQL)

``` graphql
subscription DeviceStateChanged {
    DeviceStateChanged {
        ID State
    }
}
```

## Errors

GraphQL endpoints return `200 OK` even on logical errors. Inspect the `errors` array in the response body:

``` json
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
```

| `extensions.code` | Meaning |
| --- | --- |
| `UNAUTHENTICATED` | Missing or invalid API token. |
| `FORBIDDEN` | Token lacks permission for this operation. |
| `BAD_USER_INPUT` | Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
| `NOT_FOUND` | The targeted entity does not exist. |
| `INTERNAL_SERVER_ERROR` | DeviceHub fault. Retry, then escalate via `System > Support`. |

A non-`200` HTTP response means DeviceHub itself is unreachable. See `Dashboard > DeviceHub Status`.

> **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

**GraphQL Query**

```graphql
subscription DeviceStateChanged {
    DeviceStateChanged {
        ID State
    }
}
```

---

## Subscribe Search Task Changed

**POST** `{{edgeUrl}}/devicehub/v2`

# Subscribe Search Task Changed

> **WebSocket subscription**: run this over the GraphQL-over-WebSocket protocol at `wss://{{edgeHost}}/devicehub/v2` (`graphql-transport-ws`). In Postman, create a WebSocket request and send the subscription as a `subscribe` message payload -- a plain HTTP POST will not stream events.

WebSocket subscription. Reports search task progress in real time.

## Endpoint

``` http
POST {{edgeUrl}}/devicehub/v2
Content-Type: application/json
```

## Authentication

HTTP Basic Auth. **Username** is your API token, **password** is empty. The same token is valid across `/devicehub/v2`, `/analytics/v2`, `/cc`, `/opcua`, and the other LE services.

## Request body (GraphQL)

``` graphql
subscription SearchTaskChanged {
    SearchTaskChanged {
        ID Status Progress SearchedItemsCount
    }
}
```

## Errors

GraphQL endpoints return `200 OK` even on logical errors. Inspect the `errors` array in the response body:

``` json
{ "errors": [ { "message": "...", "path": ["..."], "extensions": { "code": "..." } } ] }
```

| `extensions.code` | Meaning |
| --- | --- |
| `UNAUTHENTICATED` | Missing or invalid API token. |
| `FORBIDDEN` | Token lacks permission for this operation. |
| `BAD_USER_INPUT` | Invalid argument (wrong type, missing required field, malformed UUID, unknown ID, etc.). |
| `NOT_FOUND` | The targeted entity does not exist. |
| `INTERNAL_SERVER_ERROR` | DeviceHub fault. Retry, then escalate via `System > Support`. |

A non-`200` HTTP response means DeviceHub itself is unreachable. See `Dashboard > DeviceHub Status`.

> **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

**GraphQL Query**

```graphql
subscription SearchTaskChanged {
    SearchTaskChanged {
        ID Status Progress SearchedItemsCount
    }
}
```

---

