Litmus Unify/MQTT - 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. In
<v2.0.0the account operations lived in a separate top-level "Security" folder (documented at /luns/security.md); here they are underMQTT/Accounts.
Version map
| 2.0.x operation | In <v2.0.0? | Difference |
|---|---|---|
Server (broker info) |
Yes -- "Server Info" (ServerInfo) and Tools/"MQTT Server Config" (MqttServerConfig) |
2.0.x unifies the read into one server { config sumInfo nodes } query (no mode/info field) |
Account (account) |
Yes -- "Get Accounts" / "Account Details" | 2.0.x merges single-account and all-accounts into one query (id optional) |
List Accounts (ListAccounts) |
Partial -- "Get Accounts" returned all | 2.0.x adds filters (ids, acType) |
Account Create (accountCreate) |
Yes -- "Create Account" | Both call accountCreate. 2.0.x returns a server-generated password, shown once |
Account Update (accountUpdate) |
Yes -- "Reset Account Password" (accountUpdate) |
<v2.0.0 used this only to reset a password; 2.0.x generalizes it |
Account Enable / Account Disable |
Yes -- "Enable Account" / "Disable Account" | None |
Account Add Rules (accountAddRules) |
Yes -- "Add Account Rules" and UNS/"Add Permission to Account" | Perm now includes Deny; input field is acctId |
Account Remove Rules (accountRemoveRules) |
Yes -- "Remove Account Rules" | None |
Account Update Rules (accountUpdateRules) |
No | New in 2.0.x |
Account Delete (accountDelete) |
Partial -- "Remove Account" actually called accountRemoveRules |
2.0.x adds a real accountDelete |
Clients (clients) |
Yes -- "List Clients and Connections" | None |
Topics (client topics) |
No | New in 2.0.x |
Topic Remove (topicRemove) |
No | Not in the live 2.0.1 schema (absent from Mutation introspection); listed only for historical reference |
MQTT Update And Restart (mqttUpdateAndRestart) |
No -- <v2.0.0 had a read-only "Server Config" | 2.0.x adds this write+restart mutation |
Create Token (createToken) |
Yes -- Security/"Create LitmusEdge Activation Token" | Same operation, moved into the MQTT Client folder |
Only in <v2.0.0:
- "Client Details" (
ClientsDetails) -- per-client detail lookup; no 2.0.x equivalent. - "Server Config" (
ServerConfig) and Tools/"MQTT Server Config" (MqttServerConfig) -- read-only config queries, replaced by theServerquery plus theMQTT Update And Restartmutation. The<v2.0.0account ops are at /luns/security.md and the server-config query at /luns/tools.md.
Table of Contents
- Server
- Account
- List Accounts
- Account Create
- Account Update
- Account Disable
- Account Enable
- Account Add Rules
- Account Update Rules
- Account Remove Rules
- Account Delete
- Clients
- Topics
- Topic Remove
- MQTT Update And Restart
- Create Token
Server
POST {{uns_url}}/mqtt/gql
Server
Full broker server state: socket / TLS configuration and the MQTT statistics (cluster-wide aggregate plus per-node) that drive the dashboard counters. 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
| Field | Meaning |
|---|---|
config |
ServerConfig: listener configuration -- updateEnabled, socketTCP, socketWS, socketHealthCheck, sslEnabled, and the ssl block (TLS / WSS sockets, cert, CA). |
sumInfo |
ServerInfo: cluster-wide aggregate counters (version, uptime, byte / message / packet counts, clientsConnected/Disconnected/Max/Total, subscriptions, host, and the mqttConfig protocol limits). |
nodes |
[ServerInfo!]!: the same ServerInfo counters broken down per cluster node (one entry per broker node; three on this deployment). |
query Server {
server {
config { sslEnabled socketTCP { port enabled } socketWS { port enabled } }
sumInfo { version uptime clientsConnected subscriptions }
nodes { host uptime clientsConnected }
}
}
Serverhas nomodeorinfofield on 2.0.1 (verified against the live schema).ServerInfoitself has nomodeornodesfield.sumInfo.mqttConfigis in the schema but its resolver returns a masked error on this broker, so omit it.
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 Server {
server {
config {
updateEnabled
sslEnabled
}
sumInfo {
version
uptime
bytesSent
bytesRcvd
msgSent
msgRcvd
msgDropped
packetsSent
packetsRcvd
clientsConnected
clientsDisconnected
clientsMax
clientsTotal
subscriptions
host
}
nodes {
version
uptime
bytesSent
bytesRcvd
msgSent
msgRcvd
msgDropped
packetsSent
packetsRcvd
clientsConnected
clientsDisconnected
clientsMax
clientsTotal
subscriptions
host
}
}
}
Response
Status: 200 OK
{
"data": {
"server": {
"config": {
"updateEnabled": false,
"sslEnabled": true
},
"sumInfo": {
"version": "",
"uptime": "",
"bytesSent": 48,
"bytesRcvd": 6758,
"msgSent": 0,
"msgRcvd": 0,
"msgDropped": 0,
"packetsSent": 7,
"packetsRcvd": 12,
"clientsConnected": 0,
"clientsDisconnected": 0,
"clientsMax": 0,
"clientsTotal": 0,
"subscriptions": 0,
"host": ""
},
"nodes": [
{
"version": "2.0.1",
"uptime": "2h6m30s",
"bytesSent": 4,
"bytesRcvd": 18,
"msgSent": 0,
"msgRcvd": 0,
"msgDropped": 0,
"packetsSent": 1,
"packetsRcvd": 1,
"clientsConnected": 0,
"clientsDisconnected": 0,
"clientsMax": 0,
"clientsTotal": 0,
"subscriptions": 0,
"host": ".mqtt-2."
},
{
"version": "2.0.1",
"uptime": "2h7m0s",
"bytesSent": 40,
"bytesRcvd": 6720,
"msgSent": 0,
"msgRcvd": 0,
"msgDropped": 0,
"packetsSent": 5,
"packetsRcvd": 10,
"clientsConnected": 0,
"clientsDisconnected": 0,
"clientsMax": 0,
"clientsTotal": 0,
"subscriptions": 0,
"host": ".mqtt-0."
},
{
"version": "2.0.1",
"uptime": "2h7m0s",
"bytesSent": 4,
"bytesRcvd": 20,
"msgSent": 0,
"msgRcvd": 0,
"msgDropped": 0,
"packetsSent": 1,
"packetsRcvd": 1,
"clientsConnected": 0,
"clientsDisconnected": 0,
"clientsMax": 0,
"clientsTotal": 0,
"subscriptions": 0,
"host": ".mqtt-1."
}
]
}
}
}
Account
POST {{uns_url}}/mqtt/gql
Account
Fetch MQTT client accounts. Pass an account id for one account, or omit it to return every account. Always returns a list.
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
| Argument | Type | Required | Notes |
|---|---|---|---|
id |
UUID |
no | Account id; omit to return all accounts. |
Response
Returns [Account!]!. Each Account carries id, username, enabled, acType (General / Litmus), its ACL rules ({ id, path, perm }), and connected clients.
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 Account {
account {
id
username
enabled
rules {
id
path
perm
}
clients {
id
account {
id
username
enabled
rules {
id
path
perm
}
acType
}
connected
protoLevel
remote
lastSeen
pubTopics {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
pubTopicsRejected {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
subTopics {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
}
acType
}
}
Response
Status: 200 OK
{
"data": {
"account": []
}
}
List Accounts
POST {{uns_url}}/mqtt/gql
List Accounts
List accounts with an optional filter by id set or account type.
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 (ListAccountsRequest) |
Type | Required | Notes |
|---|---|---|---|
ids |
[UUID!] |
no | Restrict to these account ids. |
acType |
AccountType |
no | General or Litmus. |
Response
Returns [Account!]! (same shape as Account).
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 ListAccounts {
listAccounts {
id
username
enabled
rules {
id
path
perm
}
clients {
id
account {
id
username
enabled
rules {
id
path
perm
}
acType
}
connected
protoLevel
remote
lastSeen
pubTopics {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
pubTopicsRejected {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
subTopics {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
}
acType
}
}
Response
Status: 200 OK
{
"data": {
"listAccounts": []
}
}
Account Create
POST {{uns_url}}/mqtt/gql
Account Create
Create a new MQTT client account. Fails if the username already exists.
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 (AccountCreateInput) |
Type | Required | Notes |
|---|---|---|---|
username |
String! |
yes | Login for the MQTT client. |
acType |
AccountType |
no | General (default) or Litmus. |
Response
Returns AccountCreatePayload with the created account and the generated password.
Capture
passwordfrom this response, it is shown once and cannot be retrieved later (useReset Account Passwordto issue a new one).
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 AccountCreate($input: AccountCreateInput!) {
accountCreate(input: $input) {
account {
id
username
enabled
rules {
id
path
perm
}
clients {
id
connected
protoLevel
remote
lastSeen
}
acType
}
password
}
}
Variables
{
"input": {
"username": "docs-example-account",
"acType": "General"
}
}
Response
Status: 200 OK
{
"data": {
"accountCreate": {
"account": {
"id": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"username": "docs-example-account",
"enabled": true,
"rules": null,
"clients": null,
"acType": "General"
},
"password": "-peaXZD3MK!bwrVpi"
}
}
}
Account Update
POST {{uns_url}}/mqtt/gql
Account Update
Update an existing account, addressed by its id.
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 (AccountUpdateInput) |
Type | Required | Notes |
|---|---|---|---|
acctId |
UUID! |
yes | Account id to update. |
Response
Returns AccountUpdatePayload with the updated account.
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 AccountUpdate($input: AccountUpdateInput!) {
accountUpdate(input: $input) {
account {
id
username
enabled
rules {
id
path
perm
}
clients {
id
connected
protoLevel
remote
lastSeen
}
acType
}
password
}
}
Variables
{
"input": {
"acctId": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A"
}
}
Response
Status: 200 OK
{
"data": {
"accountUpdate": {
"account": {
"id": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"username": "docs-example-account",
"enabled": true,
"rules": [
{
"id": "092A9DEE-65B8-41B5-B5EA-4AA34D9F5CB7",
"path": "enterprise/#",
"perm": "Sub"
}
],
"clients": null,
"acType": "General"
},
"password": "jgKxGv3mf6QQH7p@i"
}
}
}
Account Disable
POST {{uns_url}}/mqtt/gql
Account Disable
Disable an account. Disabled accounts cannot connect to the broker; existing sessions are dropped.
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 (AccountDisableInput) |
Type | Required | Notes |
|---|---|---|---|
acctId |
UUID! |
yes | Account id to disable. |
Response
Returns AccountDisablePayload with the updated account.
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 AccountDisable($input: AccountDisableInput!) {
accountDisable(input: $input) {
account {
id
username
enabled
rules {
id
path
perm
}
clients {
id
connected
protoLevel
remote
lastSeen
}
acType
}
}
}
Variables
{
"input": {
"acctId": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A"
}
}
Response
Status: 200 OK
{
"data": {
"accountDisable": {
"account": {
"id": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"username": "docs-example-account",
"enabled": false,
"rules": [
{
"id": "092A9DEE-65B8-41B5-B5EA-4AA34D9F5CB7",
"path": "enterprise/#",
"perm": "Sub"
}
],
"clients": null,
"acType": "General"
}
}
}
}
Account Enable
POST {{uns_url}}/mqtt/gql
Account Enable
Re-enable a previously disabled account.
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 (AccountEnableInput) |
Type | Required | Notes |
|---|---|---|---|
acctId |
UUID! |
yes | Account id to enable. |
Response
Returns AccountEnablePayload with the updated account.
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 AccountEnable($input: AccountEnableInput!) {
accountEnable(input: $input) {
account {
id
username
enabled
rules {
id
path
perm
}
clients {
id
connected
protoLevel
remote
lastSeen
}
acType
}
}
}
Variables
{
"input": {
"acctId": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A"
}
}
Response
Status: 200 OK
{
"data": {
"accountEnable": {
"account": {
"id": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"username": "docs-example-account",
"enabled": true,
"rules": [
{
"id": "092A9DEE-65B8-41B5-B5EA-4AA34D9F5CB7",
"path": "enterprise/#",
"perm": "Sub"
}
],
"clients": null,
"acType": "General"
}
}
}
}
Account Add Rules
POST {{uns_url}}/mqtt/gql
Account Add Rules
Add one or more ACL rules to an account. Each rule grants or denies a permission on a topic path.
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 (AccountAddRulesInput) |
Type | Required | Notes |
|---|---|---|---|
acctId |
UUID! |
yes | Target account id. |
rules |
[AddRuleInput!]! |
yes | Each { path: String!, perm: Perm! }. |
Perm is one of Sub, Pub, PubSub, Deny. path accepts MQTT topic filters, e.g. enterprise/site/area/+/temperature.
Response
Returns AccountAddRulesPayload with the account and its rule ids (needed by Account Update Rules / Account Remove Rules).
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 AccountAddRules($input: AccountAddRulesInput!) {
accountAddRules(input: $input) {
account {
id
username
enabled
rules {
id
path
perm
}
clients {
id
connected
protoLevel
remote
lastSeen
}
acType
}
rulesAdded {
id
path
perm
}
}
}
Variables
{
"input": {
"acctId": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"rules": [
{
"path": "enterprise/site/area/+/temperature",
"perm": "PubSub"
}
]
}
}
Response
Status: 200 OK
{
"data": {
"accountAddRules": {
"account": {
"id": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"username": "docs-example-account",
"enabled": true,
"rules": [
{
"id": "092A9DEE-65B8-41B5-B5EA-4AA34D9F5CB7",
"path": "enterprise/site/area/+/temperature",
"perm": "PubSub"
}
],
"clients": null,
"acType": "General"
},
"rulesAdded": [
{
"id": "092A9DEE-65B8-41B5-B5EA-4AA34D9F5CB7",
"path": "enterprise/site/area/+/temperature",
"perm": "PubSub"
}
]
}
}
}
Account Update Rules
POST {{uns_url}}/mqtt/gql
Account Update Rules
Modify existing ACL rules in place, addressed by rule id.
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 (AccountUpdateRulesInput) |
Type | Required | Notes |
|---|---|---|---|
acctId |
UUID! |
yes | Target account id. |
rules |
[UpdateRuleInput!]! |
yes | Each { id: UUID!, path: String!, perm: Perm! }. |
Response
Returns AccountUpdateRulesPayload with the updated account.
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 AccountUpdateRules($input: AccountUpdateRulesInput!) {
accountUpdateRules(input: $input) {
account {
id
username
enabled
rules {
id
path
perm
}
clients {
id
connected
protoLevel
remote
lastSeen
}
acType
}
rulesUpdated {
id
path
perm
}
}
}
Variables
{
"input": {
"acctId": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"rules": [
{
"id": "092A9DEE-65B8-41B5-B5EA-4AA34D9F5CB7",
"path": "enterprise/#",
"perm": "Sub"
}
]
}
}
Response
Status: 200 OK
{
"data": {
"accountUpdateRules": {
"account": {
"id": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"username": "docs-example-account",
"enabled": true,
"rules": [
{
"id": "092A9DEE-65B8-41B5-B5EA-4AA34D9F5CB7",
"path": "enterprise/#",
"perm": "Sub"
}
],
"clients": null,
"acType": "General"
},
"rulesUpdated": [
{
"id": "092A9DEE-65B8-41B5-B5EA-4AA34D9F5CB7",
"path": "enterprise/#",
"perm": "Sub"
}
]
}
}
}
Account Remove Rules
POST {{uns_url}}/mqtt/gql
Account Remove Rules
Remove ACL rules from an account by rule id.
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 (AccountRemoveRulesInput) |
Type | Required | Notes |
|---|---|---|---|
acctId |
UUID! |
yes | Target account id. |
ruleIds |
[UUID!]! |
yes | Rule ids to remove. |
Response
Returns AccountRemoveRulesPayload with the updated account.
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 AccountRemoveRules($input: AccountRemoveRulesInput!) {
accountRemoveRules(input: $input) {
account {
id
username
enabled
rules {
id
path
perm
}
clients {
id
connected
protoLevel
remote
lastSeen
}
acType
}
rulesRemoved {
id
path
perm
}
}
}
Variables
{
"input": {
"acctId": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"ruleIds": [
"092A9DEE-65B8-41B5-B5EA-4AA34D9F5CB7"
]
}
}
Response
Status: 200 OK
{
"data": {
"accountRemoveRules": {
"account": {
"id": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"username": "docs-example-account",
"enabled": true,
"rules": null,
"clients": null,
"acType": "General"
},
"rulesRemoved": [
{
"id": "092A9DEE-65B8-41B5-B5EA-4AA34D9F5CB7",
"path": "enterprise/#",
"perm": "Sub"
}
]
}
}
}
Account Delete
POST {{uns_url}}/mqtt/gql
Account Delete
Delete an account and revoke its access.
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 (AccountDeleteInput) |
Type | Required | Notes |
|---|---|---|---|
acctId |
UUID! |
yes | Account id to delete. |
Response
Returns AccountDeletePayload.
The payload's
accountfield resolves the now-deleted account, so the broker masks it even though the delete succeeds. Confirm removal withList Accounts.
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 AccountDelete($input: AccountDeleteInput!) {
accountDelete(input: $input) {
account {
id
username
enabled
rules {
id
path
perm
}
clients {
id
connected
protoLevel
remote
lastSeen
}
acType
}
}
}
Variables
{
"input": {
"acctId": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A"
}
}
Response
Status: 200 OK
{
"errors": [
{
"message": "masked error",
"path": [
"accountDelete",
"account"
]
}
],
"data": {
"accountDelete": null
}
}
Clients
POST {{uns_url}}/mqtt/gql
Clients
List the MQTT clients known to the broker and their live connection state. Omit ids for the full list, or pass specific client ids to narrow it.
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
| Argument | Type | Required | Notes |
|---|---|---|---|
ids |
[String!] |
no | Client ids to fetch; omit for all clients. |
Response
Returns [Client!]!. Each Client carries id, the owning account, connected, protoLevel, remote (IP), lastSeen, and the client's pubTopics / pubTopicsRejected / subTopics.
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 Clients {
clients {
id
account {
id
username
enabled
rules {
id
path
perm
}
clients {
id
connected
protoLevel
remote
lastSeen
pubTopics {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
pubTopicsRejected {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
subTopics {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
}
acType
}
connected
protoLevel
remote
lastSeen
pubTopics {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
pubTopicsRejected {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
subTopics {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
}
}
Response
Status: 200 OK
{
"data": {
"clients": []
}
}
Topics
POST {{uns_url}}/mqtt/gql
Topics
List broker topics, optionally narrowed by an MQTT topic filter expression (wildcards + and # are supported).
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
| Argument | Type | Required | Notes |
|---|---|---|---|
filter |
String |
no | MQTT filter expression, e.g. enterprise/#. Omit for all topics. |
Response
Returns [Topic!]!. Each Topic carries path, byteCount, msgCount, pubRate, lastSeen, the last lastVal, clients ([String!], the publishing client ids, distinct from the top-level Client type), and its UNS classification (TopicType, one of UNS, NonUNS, Raw).
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 Topics {
topics {
path
byteCount
msgCount
pubRate
lastSeen
lastVal {
timestamp
deviceName
tagName
datatype
value
}
clients
UNS
}
}
Response
Status: 200 OK
{
"data": {
"topics": []
}
}
Topic Remove
POST {{uns_url}}/mqtt/gql
Topic Remove
Remove retained topics whose path matches an MQTT filter expression.
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 (TopicRemoveInput) |
Type | Required | Notes |
|---|---|---|---|
filter |
String! |
yes | MQTT filter expression, e.g. docs/example/#. |
Response
Returns TopicRemovePayload with the remaining topics.
Removed in 2.0.1:
topicRemoveis absent from the live 2.0.1 schema (confirmed by introspecting the Mutation type, which lists notopicRemove). Calling it fails GraphQL validation. The request below is retained only for historical reference.
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 TopicRemove($input: TopicRemoveInput) {
topicRemove(input: $input) {
topics {
path
}
}
}
Variables
{
"input": {
"filter": "docs/example/#"
}
}
Response
Status: 422 Unprocessable Entity
{
"errors": [
{
"message": "masked error",
"extensions": {
"code": "GRAPHQL_VALIDATION_FAILED"
}
}
],
"data": null
}
MQTT Update And Restart
POST {{uns_url}}/mqtt/gql
MQTT Update And Restart
Replace the broker's listener / TLS configuration and restart the broker to apply it.
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 (mqttUpdateAndRestartInput) |
Type | Required | Notes |
|---|---|---|---|
socketsTCP / socketsWS / socketsHealthCheck |
mqttUpdateAndRestartSocket! |
yes | Each { port: Int!, enabled: Boolean! }. |
sslEnabled |
Boolean! |
yes | Enable TLS listeners. |
sslKey / sslCert / sslCA |
String! |
yes | PEM material for TLS. |
sslSocketsTLS / sslSocketsWSS |
mqttUpdateAndRestartSocket! |
yes | TLS / secure-WebSocket sockets. |
Response
Returns mqttUpdateAndRestartPayload.
Disruptive: restarting the broker drops every active client connection.
sslKeyis write-only (never returned byServer), so resubmit the full SSL material when TLS is enabled.
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 MqttUpdateAndRestart {
mqttUpdateAndRestart {
cfg {
updateEnabled
socketTCP {
port
enabled
}
socketWS {
port
enabled
}
socketHealthCheck {
port
enabled
}
sslEnabled
ssl {
cert
ca
socketTLS {
port
enabled
}
socketWSS {
port
enabled
}
}
}
}
}
Create Token
POST {{uns_url}}/mqtt/gql
Create Token
Mint a one-time activation token used to join a LitmusEdge client to this Unify instance.
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 (CreateTokenRequest) |
Type | Required | Notes |
|---|---|---|---|
publicURL |
String! |
yes | Public URL the joining client should call back to. |
accountId |
UUID |
no | Bind the token to a specific account. |
mqttPort |
Int |
no | MQTT port advertised to the client. |
Response
Returns CreateTokenResponse with token (a base64 blob encoding a one-time token and the public URL). Hand it to the LitmusEdge client during onboarding.
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 CreateToken($input: CreateTokenRequest!) {
createToken(input: $input) {
token
}
}
Variables
{
"input": {
"accountId": "ABCB0332-E3F1-49D1-A0C7-C60BB6AFE89A",
"publicURL": "https://4.149.171.74",
"mqttPort": 8883
}
}
Response
Status: 200 OK
{
"data": {
"createToken": {
"token": "eyJvbmVUaW1lVG9rZW4iOiI0NTY5NDQ3MS1jNGVkLTRiYTctYTZhYi1iMzFkNmUxMGY5YzgiLCJwdWJsaWNVUkwiOiJodHRwczovLzQuMTQ5LjE3MS43NC9hcGkvdjEvam9pbiJ9"
}
}
}