---
parent: /workflows/agents.md
back_out_url: /workflows/agents.md
---

# 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`, but `ListProviders` is the right way to find it instead of pinning a UUID. Do not key on `Name` across releases. Fetch the full config property list with `Get Provider Schema` (/le/integration/provider-schemas.md).

> **Transport**: the Litmus Unify provider picks its transport with `connectionType` (`mqtt` | `mqtts` | `ws` | `wss`) inside `Config`, instead of separate TCP and SSL providers.

> **Enabled flag**: the collection notes describe creating the connector with `Enabled: false` until real credentials are in place, while the example body sends `Enabled: true`. Create it disabled if the token or config are not final.

> **Unify errors are masked**: most failures return `{"message": "masked error"}` with `data: null`; the `path` shows which field failed. Validation failures carry `extensions.code = GRAPHQL_VALIDATION_FAILED` with HTTP `422`. A missing or expired Bearer token returns HTTP `401` with body `bad token`.

> **Account delete payload**: `accountDelete` resolves the now-deleted account, so its `account` field comes back masked even when the delete succeeds. Confirm removal with `listAccounts`.

> **Delete queued data**: deleting the connector (step 7) discards its queued messages. If they must reach Unify, make sure the connector is `Online` and `Enabled` first.

Related: /le/integration/streaming.md, /le/integration/provider-examples.md, /luns/mqtt.md


---
