Skip to main content
Technical Preview

Overview

Two client-mode connectors for Azure Digital Twins:
  • AzureDigitalTwins calls your instance’s data plane (https://<instance>.api.<region>.digitaltwins.azure.net, api-version 2023-10-31). Use it to keep a twin graph in step with the plant: patch twin properties from UNS telemetry, create or replace twins and relationships, query the graph, and publish telemetry on a twin so ADT event routes forward it to Event Grid, Event Hubs or Service Bus.
  • AzureDigitalTwinsEntraToken calls Microsoft Entra ID (login.microsoftonline.com) with the client-credentials flow and returns an access token for the https://digitaltwins.azure.net audience.
Topics use cloud-iot/azure-digital-twins/<object>/<verb>; replies land on <topic>/response. Before deploying, replace YOUR_INSTANCE.api.YOUR_REGION in the AzureDigitalTwins connector with your instance host name, shown as Host name on the instance overview in the Azure portal or by az dt show, for example plant-porto.api.weu.digitaltwins.azure.net.
Never commit a client secret or access token. Store the tenant id, client id and client secret as broker secrets and map them into payloads with GET SECRET.

Authentication

Every data-plane event sends a Microsoft Entra ID access token as Authorization: Bearer <token>. The token must be issued for the Azure Digital Twins audience https://digitaltwins.azure.net.
  1. Register an app in Microsoft Entra ID (or use a managed identity if the broker runs on Azure) and create a client secret.
  2. On the Azure Digital Twins instance, assign that identity Azure Digital Twins Data Owner for read and write, or Azure Digital Twins Data Reader for read only. Owning the Azure subscription is not enough; the data-plane role is required.
  3. Publish tenant_id, client_id and client_secret to cloud-iot/azure-digital-twins/token/get. The reply carries access_token and expires_in (about one hour). The client secret must be URL-encoded because it goes into a form body.
  4. Pass access_token on every data-plane payload. Refresh it before it expires; the helper actions below do this every 45 minutes.
A missing or expired token returns 401. A valid token without the data-plane role returns 403.

Basic Syntax

MQTT examples

Request bodies go under body, so control fields like access_token, twin_id and message_id are not sent to Azure. Patch a twin from telemetry: publish to cloud-iot/azure-digital-twins/twin/update:
A successful patch returns 204 with an empty body. replace fails with 400 if the property has never been set on the twin, so use add for the first write. Every property must exist in the twin’s DTDL model. Create or replace a twin: publish to cloud-iot/azure-digital-twins/twin/upsert:
Link it to its line: publish to cloud-iot/azure-digital-twins/relationship/upsert:
Query the graph: publish to cloud-iot/azure-digital-twins/query/run:
The reply has value (the matching twins) and continuationToken. Send {"continuationToken": "..."} as the body to get the next page. Send telemetry on a twin: publish to cloud-iot/azure-digital-twins/telemetry/send:
Telemetry is not stored on the twin. ADT forwards it to whatever event routes you configured (check them on cloud-iot/azure-digital-twins/event-route/list). message_id must be unique per message; ADT uses it to drop duplicates. Read: publish {"access_token": "<token>", "twin_id": "press-01"} to cloud-iot/azure-digital-twins/twin/get or .../relationship/list, {"access_token": "<token>"} to .../model/list or .../event-route/list, and {"access_token": "<token>", "model_id": "dtmi%3Acoreflux%3AMachine%3B1"} to .../model/get. URL-encode the model id because it contains : and ;.

Helper actions

Keep the Entra credentials in broker secrets, refresh the token on a timer and keep it in broker-internal state, so machines only publish their raw values:
Here the fourth topic segment (press-01 in plant/porto/line1/press-01/temperature) is the twin id. Name twins after your UNS asset ids so this mapping stays trivial. Store a client secret that is already URL-encoded, or encode it before publishing. Restrict who can read cloud-iot/azure-digital-twins/# with a rule: these payloads carry tokens and secrets.

Notes

  • Errors come back on the response topic: 401 for a missing, expired or wrong-audience token, 403 without the Data Owner or Data Reader role, 404 (DigitalTwinNotFound, RelationshipNotFound, ModelNotFound), 400 for a bad JSON Patch, a property that is not in the DTDL model or an invalid query, 412 for a failed If-Match / If-None-Match precondition, 429 when throttled.
  • ADT throttles requests per instance and per twin (see Azure Digital Twins service limits). Batch high-rate telemetry or use ON CHANGE instead of patching on every sample.
  • PATCH and PUT here send no If-Match / If-None-Match header, so they overwrite unconditionally. Add the header to the event if you need optimistic concurrency.
  • Model upload and decommission, deletes, import and delete jobs, event connector writes, component telemetry and component patches, and the ARM control plane (creating instances) are not part of this template.
Last modified on October 21, 2026