Workflow 17: Create a Digital Twin (Model + Instance)

You are at https://api.litmus.io/workflows/create-digital-twin.md Parent: https://api.litmus.io/workflows/agents.md If this is the wrong workflow, back out to the index above.

17. Create a Digital Twin (Model + Instance)

UI trigger: Digital Twins -> Models -> Add Model -> (add attributes) -> Instances -> Add Instance -> Enable

A digital twin is a model (the schema: static and dynamic attributes) plus one or more instances of it that publish to a topic. All calls are GraphQL. Model, static attribute, state and delete operations go to {{edgeUrl}}/digital-twins; CreateDynamicAttributes and the 4.3.x-updated CreateInstance go to {{edgeUrl}}/digital-twins/v2. Full per-endpoint detail: /le/digital-twins.md

Step table

Step API Name Method Endpoint / GraphQL Operation Input Output / What to capture
1 Create Model POST {{edgeUrl}}/digital-twins -> CreateModel Name (unique), Assets (e.g. ASSET), optional Description, IsUNS, ConnectorName ID -> {{digital_twins_model_id}}
2 Create Static Attribute POST {{edgeUrl}}/digital-twins -> CreateStaticAttributes Items: [{ModelID, Key, Value}]; ModelID from step 1, Key unique within the model. One call can add several Array of attributes, one ID per item
3 Create Dynamic Attribute POST {{edgeUrl}}/digital-twins/v2 -> CreateDynamicAttributes Items: [{ModelID, Topic, Name, Unit, DataType}]; for nesting AttrDataType: "nestedModel" + NestedModelID or NestedInstanceID, with Topic: "" Array of attributes, one ID and SchemaID per item
4 Create Instance POST {{edgeUrl}}/digital-twins/v2 -> CreateInstance ModelID, Name, Topic, Interval (ms), FlatHierarchy, optional Source (local / external) ID -> {{digital_twins_instance_id}}
5 Enable Instance POST {{edgeUrl}}/digital-twins -> SetInstanceState InstanceID (step 4), IsEnabled: true true; the instance starts publishing to its topic
6 Delete Instance (clean up) POST {{edgeUrl}}/digital-twins -> DeleteInstance ID of the instance null on success
7 Delete Model (clean up) POST {{edgeUrl}}/digital-twins -> DeleteModel ID of the model null on success

Use the plural attribute mutations: the singular CreateStaticAttribute and CreateDynamicAttribute are deprecated on both Digital Twins endpoints ("No longer supported"). They still execute, but steps 2 and 3 use CreateStaticAttributes and CreateDynamicAttributes, which take an Items list of the same item shape and return an array. The collection chain still sends the singular forms.

Required fields (4.1.x+): CreateModelRequest.Name and .Assets are required; omitting either returns a GraphQL validation error. DeleteInstanceRequest.ID and DeleteModelRequest.ID are required.

ModelID is not checked on attribute creation: steps 2 and 3 accept an unknown ModelID and return an attribute that belongs to no model. Confirm the model with List Models before adding attributes. CreateInstance does check it and fails with DT_NOT_FOUND.

Dynamic attribute DataType: must be json, string, number, boolean or array; anything else (e.g. float) fails with DT_VALIDATION_FAILED. NestedModelID and NestedInstanceID are alternatives (set one, leave the other null) and are ignored unless AttrDataType is nestedModel. For a nested attribute the server stores DataType as nestedModel whatever you send. Nothing prevents a nesting cycle; it only surfaces when the twin is resolved.

Dynamic attribute Topic (verified on LE 4.4.0): use letters, numbers, dots, dashes and underscores, with no leading, trailing or repeated dots; a / fails with DT_VALIDATION_FAILED (line.1.speed works, line/1/speed does not). A nested model attribute takes its topic from the instance it is bound to, so send Topic: ""; any other value is rejected. The collection chain's step 3 example ("Topic": "line/1/motor" on a nested attribute) fails for that reason. Instance topics (step 4) do accept /.

Disabled vs enabled: a disabled instance is configured but does not publish. Use SetInstanceState to pause and resume instead of deleting and recreating.

Delete order: a model with instances cannot be deleted (DT_MODEL_HAS_INSTANCES). Delete its instances first (step 6), then the model (step 7). Deleting a missing model ID returns BAD_USER_INPUT.

Variable names: the collection chain uses {{digital_twins_model_id}} / {{digital_twins_instance_id}} in steps 1, 2, 5 and 7, but {{dt_model_id}} in steps 3 and 4. Set both to the same model ID when running the chain as-is.


View this page as Markdown