Workflow 18: Connect Litmus Edge to Litmus Unify
You are at https://api.litmus.io/workflows/connect-edge-to-unify.md Parent: https://api.litmus.io/workflows/agents.md If this is the wrong workflow, back out to the index above.
18. Connect Litmus Edge to Litmus Unify
UI trigger: Unify -> create activation token -> Litmus Edge Integration -> Add Connector -> Litmus Unify -> paste token -> Save
This chain spans two products. Steps marked Unify run against the Unify GraphQL endpoint {{uns_url}}/mqtt/gql with an OAuth2 Bearer token (Keycloak password grant, see /luns/agents.md). Steps marked LE run against the Integration GraphQL endpoint {{edgeUrl}}/cc/v2 with LE auth (see /le/agents.md#authentication). The edge joins Unify through the Litmus Unify Integration provider (new in 4.4.x), which consumes a one-time activation token minted on Unify.
Step table
| Step | Runs on | API Name | Method | Endpoint / GraphQL Operation | Input | Output / What to capture |
|---|---|---|---|---|---|---|
| 1 | Unify | Create Activation Token | POST |
{{uns_url}}/mqtt/gql -> createToken |
publicURL (required); optional accountId, mqttPort |
token (base64 blob with a one-time token and the public URL) -> {{unify_activation_token}} |
| 2 | LE | Find the Litmus Unify Provider | POST |
{{edgeUrl}}/cc/v2 -> ListProviders |
none | ID of the provider named Litmus Unify (the ProviderID); check Hidden / IsExperimental |
| 3 | LE | Create Litmus Unify Connector | POST |
{{edgeUrl}}/cc/v2 -> CreateInstance |
ProviderID (step 2), Config as a JSON string with name, UnifyClientID, token (step 1), optional insecureSkipVerify; Enabled, ErrorLogging |
InstanceID -> {{unify_connector_id}}, Status |
| 4 | Unify | Find the Edge Account | POST |
{{uns_url}}/mqtt/gql -> listAccounts |
optional ids, acType |
Account with acType: "Litmus" and a litmus-edge-... username -> {{unify_edge_account_id}} |
| 5 | LE | Confirm the Connector Is Online | POST |
{{edgeUrl}}/cc/v2 -> GetInstance |
InstanceID (step 3) |
Online, Status, ErrCode, ErrMsg |
| 6 | Unify | Confirm the Edge Is Connected | POST |
{{uns_url}}/mqtt/gql -> clients |
optional ids |
Client whose account.id is the edge account, with connected: true, remote, lastSeen |
| 7 | LE | Delete the Connector (clean up) | POST |
{{edgeUrl}}/cc/v2 -> DeleteInstance |
InstanceID (step 3) |
null on success; also deletes the instance's subscriptions |
| 8 | Unify | Delete the Edge Account (clean up) | POST |
{{uns_url}}/mqtt/gql -> accountDelete |
acctId (step 4) |
AccountDeletePayload |
Resolve the ProviderID at runtime: the collection example uses
7c1f3a92-5b8e-4d6a-9f27-0a4c8e35b1d3, butListProvidersis the right way to find it instead of pinning a UUID. Do not key onNameacross releases. Fetch the full config property list withGet Provider Schema(/le/integration/provider-schemas.md).Transport: the Litmus Unify provider picks its transport with
connectionType(mqtt|mqtts|ws|wss) insideConfig, instead of separate TCP and SSL providers.Enabled flag: the collection notes describe creating the connector with
Enabled: falseuntil real credentials are in place, while the example body sendsEnabled: true. Create it disabled if the token or config are not final.Unify errors are masked: most failures return
{"message": "masked error"}withdata: null; thepathshows which field failed. Validation failures carryextensions.code = GRAPHQL_VALIDATION_FAILEDwith HTTP422. A missing or expired Bearer token returns HTTP401with bodybad token.Account delete payload:
accountDeleteresolves the now-deleted account, so itsaccountfield comes back masked even when the delete succeeds. Confirm removal withlistAccounts.Delete queued data: deleting the connector (step 7) discards its queued messages. If they must reach Unify, make sure the connector is
OnlineandEnabledfirst.
Related: /le/integration/streaming.md, /le/integration/provider-examples.md, /luns/mqtt.md