Litmus Unify/UNS - LE, LEM, LUNS API Docs

Applies to: Litmus Unify 2.0.x (current). The version map shows which operations also exist in <v2.0.0 and how they differ. Full <v2.0.0 request bodies are in collections.json.

Version map

2.0.x operation In <v2.0.0? Difference
Namespace (namespace) Yes -- "Namespace" None
Namespace Create (namespaceCreate) Partial -- only via "Rename Namespace" (NamespaceRename, a combined delete+create) 2.0.x adds a standalone create
Namespace Delete (namespaceDelete) Partial -- only via "Rename Namespace" 2.0.x adds a standalone delete
Namespace Update Class Config (namespaceUpdateClassConfig) Yes -- "Update Namespace Rules" (NamespaceUpdateRules) Operation renamed; input type (NamespaceUpdateClassConfigInput) is identical

Only in <v2.0.0:

Table of Contents


Namespace

POST {{uns_url}}/mqtt/gql

Namespace

Read the current unified namespace: its class path and the allowed values configured for each class. Takes no arguments.

Endpoint

POST {{uns_url}}/mqtt/gql

Authentication

OAuth2 Bearer token (Keycloak password grant). In Postman the token is inherited from the collection auth; see the collection overview for the raw token request.

Response

Returns Namespace!: id, uns (the /-delimited class path), classes (each { name, items, minItems, maxItems }), filters ([String!], not a Filter object type, which does not exist), and the compiled hierarchyCompiant / hierarchyNonCompiant node trees (type Node).

Known API bug: these two fields are genuinely misspelled in the live schema as hierarchyCompiant / hierarchyNonCompiant (missing the l in "Compliant"). Select them with the misspelling exactly as shown, the correctly spelled names do not exist. Flagged to the broker team.

Errors

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

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

Masked errors: Litmus Unify masks error detail by default, most failures surface as {"message": "masked error"} with data: null. The path identifies which field failed. Validation failures additionally carry extensions.code = GRAPHQL_VALIDATION_FAILED and return HTTP 422.

A missing or expired Bearer token returns HTTP 401 with the body bad token.

Request Body

GraphQL Query

query Namespace {
    namespace {
        id
        uns
        classes {
            name
            items
            minItems
            maxItems
        }
        filters
        hierarchyCompiant {
            name
            path
            class
            topics {
                path
                byteCount
                msgCount
                pubRate
                lastSeen
                lastVal {
                    timestamp
                    deviceName
                    tagName
                    datatype
                    value
                }
                clients
                UNS
            }
            clients
        }
        hierarchyNonCompiant {
            name
            path
            class
            topics {
                path
                byteCount
                msgCount
                pubRate
                lastSeen
                lastVal {
                    timestamp
                    deviceName
                    tagName
                    datatype
                    value
                }
                clients
                UNS
            }
            clients
        }
    }
}

Response

Status: 200 OK

{
  "data": {
    "namespace": {
      "id": "C5EEF0DC-15C3-4E6A-815E-1F9D497E6BC6",
      "uns": "enterprise/site/area/productionunit",
      "classes": [
        {
          "name": "enterprise",
          "items": [],
          "minItems": 0,
          "maxItems": 1
        },
        {
          "name": "site",
          "items": [],
          "minItems": 0,
          "maxItems": 10
        },
        {
          "name": "area",
          "items": [],
          "minItems": 0,
          "maxItems": 10
        },
        {
          "name": "productionunit",
          "items": [],
          "minItems": 0,
          "maxItems": 0
        }
      ],
      "filters": null,
      "hierarchyCompiant": {
        "name": "",
        "path": "",
        "class": null,
        "topics": [],
        "clients": null
      },
      "hierarchyNonCompiant": {
        "name": "",
        "path": "",
        "class": null,
        "topics": [],
        "clients": null
      }
    }
  }
}

Namespace Create

POST {{uns_url}}/mqtt/gql

Namespace Create

Create the namespace from a /-delimited class path. 2.0.1 supports a single namespace, so this succeeds only when none exists yet.

Endpoint

POST {{uns_url}}/mqtt/gql

Authentication

OAuth2 Bearer token (Keycloak password grant). In Postman the token is inherited from the collection auth; see the collection overview for the raw token request.

Arguments

Field (NamespaceCreateInput) Type Required Notes
uns String! yes Class path, e.g. enterprise/site/area/productionunit.

Response

Returns NamespaceCreatePayload with root (the created Namespace).

Calling this while a namespace already exists returns an error. The maxItems in this create response are transient and read 0 for every class (as the example below shows). The canonical limits -- enterprise = 1, site = 10, area = 10, leaf = 0 -- are returned by the Namespace query immediately after. Verified by delete + recreate on the live 2.0.1 broker.

Errors

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

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

Masked errors: Litmus Unify masks error detail by default, most failures surface as {"message": "masked error"} with data: null. The path identifies which field failed. Validation failures additionally carry extensions.code = GRAPHQL_VALIDATION_FAILED and return HTTP 422.

A missing or expired Bearer token returns HTTP 401 with the body bad token.

Request Body

GraphQL Query

mutation NamespaceCreate($input: NamespaceCreateInput) {
    namespaceCreate(input: $input) {
        root {
            id
            uns
            classes {
                name
                items
                minItems
                maxItems
            }
        }
    }
}

Variables

{
  "input": {
    "uns": "enterprise/site/area/productionunit"
  }
}

Response

Status: 200 OK

{
  "data": {
    "namespaceCreate": {
      "root": {
        "id": "E29AC386-293C-43B0-BC6F-FECAD340FB1C",
        "uns": "enterprise/site/area/productionunit",
        "classes": [
          {
            "name": "enterprise",
            "items": [],
            "minItems": 0,
            "maxItems": 0
          },
          {
            "name": "site",
            "items": [],
            "minItems": 0,
            "maxItems": 0
          },
          {
            "name": "area",
            "items": [],
            "minItems": 0,
            "maxItems": 0
          },
          {
            "name": "productionunit",
            "items": [],
            "minItems": 0,
            "maxItems": 0
          }
        ]
      }
    }
  }
}

Namespace Delete

POST {{uns_url}}/mqtt/gql

Namespace Delete

Delete the namespace.

Endpoint

POST {{uns_url}}/mqtt/gql

Authentication

OAuth2 Bearer token (Keycloak password grant). In Postman the token is inherited from the collection auth; see the collection overview for the raw token request.

Arguments

Field (NamespaceDeleteInput) Type Required Notes
id UUID no Ignored in practice, see the warning below.

Response

Returns NamespaceDeletePayload with the deleted id.

Destructive: there is only one namespace, and this removes it regardless of the id supplied. Recreate it with Namespace Create.

Errors

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

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

Masked errors: Litmus Unify masks error detail by default, most failures surface as {"message": "masked error"} with data: null. The path identifies which field failed. Validation failures additionally carry extensions.code = GRAPHQL_VALIDATION_FAILED and return HTTP 422.

A missing or expired Bearer token returns HTTP 401 with the body bad token.

Request Body

GraphQL Query

mutation NamespaceDelete($input: NamespaceDeleteInput) {
    namespaceDelete(input: $input) {
        id
    }
}

Variables

{
  "input": {
    "id": "C5EEF0DC-15C3-4E6A-815E-1F9D497E6BC6"
  }
}

Response

Status: 200 OK

{
  "data": {
    "namespaceDelete": {
      "id": "C5EEF0DC-15C3-4E6A-815E-1F9D497E6BC6"
    }
  }
}

Namespace Update Class Config

POST {{uns_url}}/mqtt/gql

Namespace Update Class Config

Set the list of allowed values for each configurable namespace class. The cfg array is positional over the configurable classes -- every class except the final leaf. cfg length must be <= (number of classes - 1); supplying one entry per class including the leaf fails with class rule validation failed (verified on 2.0.1). Supplying fewer entries configures a leading prefix (e.g. 2 entries set the first two classes and leave the rest empty). Each entry's items must respect that class's maxItems (e.g. enterprise has maxItems = 1).

Endpoint

POST {{uns_url}}/mqtt/gql

Authentication

OAuth2 Bearer token (Keycloak password grant). In Postman the token is inherited from the collection auth; see the collection overview for the raw token request.

Arguments

Field (NamespaceUpdateClassConfigInput) Type Required Notes
id UUID! yes Namespace id (from Namespace).
cfg [NamespaceUpdateClassItem!]! yes One { items: [String!]! } per configurable class (every class except the leaf), in order. Length must be <= classes - 1.

Each class enforces its own minItems / maxItems. A cfg array with one entry per class (including the leaf, which is not configurable) returns class rule validation failed; supplying fewer entries configures a leading prefix of the classes.

Response

Returns NamespaceUpdateClassConfigPayload with the updated classes.

Errors

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

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

Masked errors: Litmus Unify masks error detail by default, most failures surface as {"message": "masked error"} with data: null. The path identifies which field failed. Validation failures additionally carry extensions.code = GRAPHQL_VALIDATION_FAILED and return HTTP 422.

A missing or expired Bearer token returns HTTP 401 with the body bad token.

Request Body

GraphQL Query

mutation NamespaceUpdateClassConfig($input: NamespaceUpdateClassConfigInput) {
    namespaceUpdateClassConfig(input: $input) {
        classes {
            name
            items
            minItems
            maxItems
        }
    }
}

Variables

{
  "input": {
    "id": "C5EEF0DC-15C3-4E6A-815E-1F9D497E6BC6",
    "cfg": [
      {
        "items": [
          "enterprise-example"
        ]
      },
      {
        "items": [
          "site-example"
        ]
      },
      {
        "items": [
          "area-example"
        ]
      }
    ]
  }
}

Response

Status: 200 OK

{
  "data": {
    "namespaceUpdateClassConfig": {
      "classes": [
        {
          "name": "enterprise",
          "items": [
            "enterprise-example"
          ],
          "minItems": 0,
          "maxItems": 1
        },
        {
          "name": "site",
          "items": [
            "site-example"
          ],
          "minItems": 0,
          "maxItems": 10
        },
        {
          "name": "area",
          "items": [
            "area-example"
          ],
          "minItems": 0,
          "maxItems": 10
        },
        {
          "name": "productionunit",
          "items": [],
          "minItems": 0,
          "maxItems": 0
        }
      ]
    }
  }
}

View this page as Markdown