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.0request 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:
- "Rename Namespace" (
NamespaceRename) -- in 2.0.x doNamespace Delete+Namespace Create. - The
<v2.0.0"UNS" folder was a grab-bag that also held operations now relocated:AccountandAdd Permission to Account-> /luns/mqtt.md (Accounts);Kafka-> /luns/integrations.md;Topics-> /luns/dashboard.md and /luns/mqtt.md (Clients).
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 thelin "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"}withdata: null. Thepathidentifies which field failed. Validation failures additionally carryextensions.code = GRAPHQL_VALIDATION_FAILEDand return HTTP422.
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
maxItemsin this create response are transient and read0for every class (as the example below shows). The canonical limits --enterprise= 1,site= 10,area= 10, leaf = 0 -- are returned by theNamespacequery 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"}withdata: null. Thepathidentifies which field failed. Validation failures additionally carryextensions.code = GRAPHQL_VALIDATION_FAILEDand return HTTP422.
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
idsupplied. Recreate it withNamespace 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"}withdata: null. Thepathidentifies which field failed. Validation failures additionally carryextensions.code = GRAPHQL_VALIDATION_FAILEDand return HTTP422.
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"}withdata: null. Thepathidentifies which field failed. Validation failures additionally carryextensions.code = GRAPHQL_VALIDATION_FAILEDand return HTTP422.
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
}
]
}
}
}