Learn about twin models and how to define them in Azure Digital Twins
A key characteristic of Azure Digital Twins is the ability to define your own vocabulary and build your twin graph in the self-defined terms of your business. This capability is provided through user-provided models. You can think of models as the nouns in a description of your world. Azure Digital Twins models are represented in the JSON-LD-based Digital Twin Definition Language (DTDL).
A model is similar to a class in an object-oriented programming language, defining a data shape for one particular concept in your real work environment. Models have names (such as Room or TemperatureSensor), and contain elements such as properties, components, and relationships that describe what this type of entity in your environment does. Later, you'll use these models to create digital twins that represent specific entities that meet this type description.
Digital Twin Definition Language (DTDL) for models
Models for Azure Digital Twins are defined using the Digital Twins Definition Language (DTDL).
You can view the full language description for DTDL v3 in GitHub: DTDL Version 3 Language Description. This page includes DTDL reference details and examples to help you get started writing your own DTDL models.
DTDL is based on JSON-LD and is programming-language independent. DTDL isn't exclusive to Azure Digital Twins. It is also used to represent device data in other IoT services such as IoT Plug and Play.
The rest of this article summarizes how the language is used in Azure Digital Twins.
Supported DTDL versions
Azure Digital Twins supports DTDL versions 2 and 3 (shortened in the documentation to v2 and v3, respectively). V3 is the recommended choice for modeling in Azure Digital Twins based on its expanded capabilities, including:
- DTMI version relaxation
- Array support for properties
- Increased limits for model inheritance
- Feature extensions
- The ability to decorate custom interface schemas with semantic types (provided with the QuantitativeTypes extension)
Where these features are discussed in the documentation, they're accompanied by a note that they're only available in DTDL v3. For a complete list of differences between DTDL v2 and v3, see DTDL v3 Language Description: Changes from Version 2.
Azure Digital Twins also supports using a mix of v2 and v3 models within the same instance. When using models of both versions together, keep in mind the following restrictions:
- A v2 interface cannot extend a v3 interface, or have a component with a v3 interface as its schema.
- Conversely, a v3 interface can extend a v2 interface, and a v3 interface can have a component with a v2 interface as its schema.
- Relationships can point in either direction, from a v2 model source to a v3 model target, or vice-versa from a v3 model source to a v2 model target.
You can also migrate existing v2 models to v3. For instructions on how to do this, see Convert v2 models to v3.
Note
Currently, Azure Digital Twins Explorer fully supports DTDL v2 models and supports limited functionality for DTDL v3 models.
DTDL v3 models can be viewed in the Models panel, and twins created with DTDL v3 models can be viewed and edited (including those with array properties). However, DTDL v3 models won't show up in the Model Graph panel, and they can't be imported using Azure Digital Twins Explorer. To import DTDL v3 models to your instance, use another developer interface like the APIs and SDKs or the Azure CLI.
Model overview
Twin type models can be written in any text editor. The DTDL language follows JSON syntax, so you should store models with the extension .json. Using the JSON extension will enable many programming text editors to provide basic syntax checking and highlighting for your DTDL documents. There's also a DTDL extension available for Visual Studio Code.
Here are the fields within a model interface:
Field | Description |
---|---|
@id |
A Digital Twin Model Identifier (DTMI) for the model, in the format dtmi:<domain>:<unique-model-identifier>;<model-version-number> . In DTDL v3, the version number can be omitted, or structured as a two-part (<major>.<minor> ) version number. |
@type |
Identifies the kind of information being described. For an interface, the type is Interface . |
@context |
Sets the context for the JSON document. Models should use dtmi:dtdl:context;2 for DTDL v2, or dtmi:dtdl:context;3 for DTDL v3. DTDL v3 models can also name additional feature extensions in this field. |
displayName |
[optional] Gives you the option to define a friendly name for the model. If you don't use this field, the model will use its full DTMI value. |
contents |
All remaining interface data is placed here, as an array of attribute definitions. Each attribute must provide a @type (Property , Relationship , or Component ) to identify the sort of interface information it describes, and then a set of properties that define the actual attribute. The next section describes the model attributes in detail. |
Here's an example of a basic DTDL model. This model describes a Home, with one property for an ID. The Home model also defines a relationship to a Floor model, which can be used to indicate that a Home twin is connected to certain Floor twins.
{
"@id": "dtmi:com:adt:dtsample:home;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Home",
"contents": [
{
"@type": "Property",
"name": "id",
"schema": "string"
},
{
"@type": "Relationship",
"@id": "dtmi:com:adt:dtsample:home:rel_has_floors;1",
"name": "rel_has_floors",
"displayName": "Home has floors",
"target": "dtmi:com:adt:dtsample:floor;1"
}
]
}
Model attributes
The main information about a model is given by its attributes, which are defined within the contents
section of the model interface.
Here are the attributes available in DTDL that are supported in Azure Digital Twins. A DTDL model interface used for Azure Digital Twins may contain zero, one, or many of each of the following fields:
Property - Properties are data fields that represent the state of an entity (like the properties in many object-oriented programming languages). Properties have backing storage and can be read at any time. For more information, see Properties below.
Relationship - Relationships let you represent how a digital twin can be involved with other digital twins. Relationships can represent different semantic meanings, such as
contains
("floor contains room"),cools
("hvac cools room"),isBilledTo
("compressor is billed to user"), and so on. Relationships allow the solution to provide a graph of interrelated entities. Relationships can also have properties of their own. For more information, see Relationships below.Component - Components allow you to build your model interface as an assembly of other interfaces, if you want. An example of a component is a frontCamera interface (and another component interface backCamera) that's used in defining a model for a phone. First define an interface for frontCamera as though it were its own model, and then reference it when defining Phone.
Use a component to describe something that is an integral part of your solution but doesn't need a separate identity, and doesn't need to be created, deleted, or rearranged in the twin graph independently. If you want entities to have independent existences in the twin graph, represent them as separate digital twins of different models, connected by relationships.
Tip
Components can also be used for organization, to group sets of related properties within a model interface. In this situation, you can think of each component as a namespace or "folder" inside the interface.
For more information, see Components below.
The DTDL v3 Language Description also defines Commands and Telemetry, but neither of these are used in Azure Digital Twins. Commands are not supported, and Telemetry—although it's allowed in model definitions—has no unique use case in Azure Digital Twins modeling. Instead of using DTDL telemetry, you should use DTDL properties for storing twin state information.
Note
Although there's no need to define Telemetry fields in your DTDL models to store incoming device data, Azure Digital Twins can emit events as telemetry using the SendTelemetry API. This triggers a Digital Twin Telemetry Message event that can be received by an event handler to take actions on other twins or trigger downstream services.
Properties
This section goes into more detail about properties in DTDL models.
For comprehensive information about the fields that may appear as part of a property, see Property in the DTDL v3 Language Description.
Note
The writable
DTDL attribute for properties is not currently supported in Azure Digital Twins. It can be added to the model, but Azure Digital Twins will not enforce it. For more information, see Service-specific DTDL notes.
Schema
As per DTDL, the schema for property attributes can be a standard primitive type—integer
, double
, string
, and boolean
—and other types such as dateTime
and duration
.
In addition to primitive types, property fields can have these complex types:
Object
Map
Enum
Array
, in DTDL v3 only.Array
type for properties is not supported in DTDL v2.
They can also be semantic types, which allow you to annotate values with units. In DTDL v2, semantic types are natively supported; in DTDL v3, you can include them with a feature extension.
Basic property example
Here's a basic example of a property on a DTDL model. This example shows the ID property of a Home.
{
"@id": "dtmi:com:adt:dtsample:home;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Home",
"contents": [
{
"@type": "Property",
"name": "id",
"schema": "string"
},
{
"@type": "Relationship",
"@id": "dtmi:com:adt:dtsample:home:rel_has_floors;1",
"name": "rel_has_floors",
"displayName": "Home has floors",
"target": "dtmi:com:adt:dtsample:floor;1"
}
]
}
Complex Object type example
Properties can be of complex types, including an Object
type.
The following example shows another version of the Home model, with a property for its address. address
is an object, with its own fields for street, city, state, and zip.
{
"@id": "dtmi:com:adt:dtsample:home;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Home",
"extends": "dtmi:com:adt:dtsample:core;1",
"contents": [
{
"@type": "Property",
"name": "address",
"schema": {
"@type": "Object",
"fields": [
{
"name": "street",
"schema": "string"
},
{
"name": "city",
"schema": "string"
},
{
"name": "state",
"schema": "string"
},
{
"name": "zip",
"schema": "string"
}
]
}
},
{
"@type": "Relationship",
"@id": "dtmi:com:adt:dtsample:home:rel_has_floors;1",
"name": "rel_has_floors",
"displayName": "Home has floors",
"target": "dtmi:com:adt:dtsample:floor;1",
"properties": [
{
"@type": "Property",
"name": "lastOccupied",
"schema": "dateTime"
}
]
}
]
}
DTDL v2 semantic type example
Semantic types are for expressing a value with a unit. Properties for Azure Digital Twins can use any of the semantic types that are supported by DTDL.
In DTDL v2, semantic types are natively supported. For more information on semantic types in DTDL v2, see Semantic types in the DTDL v2 Language Description. To learn about semantic types in DTDL v3, see the QuantitativeTypes DTDL v3 feature extension.
The following example shows a DTDL v2 Sensor model with semantic type properties for Humidity and Temperature.
{
"@id": "dtmi:com:adt:dtsample:v2sensor;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;2",
"displayName": "Sensor (v2 model)",
"contents": [
{
"@type": ["Property", "Temperature"],
"name": "Temperature",
"schema": "double",
"unit": "degreeFahrenheit"
},
{
"@type": ["Property", "Humidity"],
"name": "Humidity",
"schema": "double",
"unit": "gramPerCubicMetre"
}
]
}
Important
"Property" must be the first element of the @type
array, followed by the semantic type. Otherwise, the field may not be visible in Azure Digital Twins Explorer.
Relationships
This section goes into more detail about relationships in DTDL models.
For a comprehensive list of the fields that may appear as part of a relationship, see Relationship in the DTDL v3 Language Description.
Note
The writable
, minMultiplicity
, and maxMultiplicity
DTDL attributes for relationships are not currently supported in Azure Digital Twins. They can be added to the model, but Azure Digital Twins will not enforce them. For more information, see Service-specific DTDL notes.
Basic relationship example
Here's a basic example of a relationship on a DTDL model. This example shows a relationship on a Home model that allows it to connect to a Floor model.
{
"@id": "dtmi:com:adt:dtsample:home;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Home",
"contents": [
{
"@type": "Property",
"name": "id",
"schema": "string"
},
{
"@type": "Relationship",
"@id": "dtmi:com:adt:dtsample:home:rel_has_floors;1",
"name": "rel_has_floors",
"displayName": "Home has floors",
"target": "dtmi:com:adt:dtsample:floor;1"
}
]
}
Note
For relationships, @id
is an optional field. If no @id
is provided, the digital twin interface processor will assign one.
Targeted and non-targeted relationships
Relationships can be defined with or without a target. A target specifies which types of twin the relationship can reach. For example, you might include a target to specify that a Home model can only have a rel_has_floors
relationship with twins that are Floor twins.
Sometimes, you might want to define a relationship without a specific target, so that the relationship can connect to many different types of twins.
Here's an example of a relationship on a DTDL model that doesn't have a target. In this example, the relationship is for defining what sensors a Room might have, and the relationship can connect to any type.
{
"@id": "dtmi:com:adt:dtsample:room;1",
"@type": "Interface",
"@context": [
"dtmi:dtdl:context;3",
"dtmi:dtdl:extension:quantitativeTypes;1"
],
"displayName": "Room",
"extends": "dtmi:com:adt:dtsample:core;1",
"contents": [
{
"@type": ["Property", "Humidity"],
"name": "humidity",
"schema": "double",
"unit": "gramPerCubicMetre"
},
{
"@type": "Component",
"name": "thermostat",
"schema": "dtmi:com:adt:dtsample:thermostat;1"
},
{
"@type": "Relationship",
"@id": "dtmi:com:adt:dtsample:room:rel_has_sensors;1",
"name": "rel_has_sensors",
"displayName": "Room has sensors"
Properties of relationships
DTDL also allows for relationships to have properties of their own. When you define a relationship within a DTDL model, the relationship can have its own properties
field where you can define custom properties to describe relationship-specific state.
The following example shows another version of the Home model, where the rel_has_floors
relationship has a property representing when the related Floor was last occupied.
{
"@id": "dtmi:com:adt:dtsample:home;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Home",
"extends": "dtmi:com:adt:dtsample:core;1",
"contents": [
{
"@type": "Property",
"name": "address",
"schema": {
"@type": "Object",
"fields": [
{
"name": "street",
"schema": "string"
},
{
"name": "city",
"schema": "string"
},
{
"name": "state",
"schema": "string"
},
{
"name": "zip",
"schema": "string"
}
]
}
},
{
"@type": "Relationship",
"@id": "dtmi:com:adt:dtsample:home:rel_has_floors;1",
"name": "rel_has_floors",
"displayName": "Home has floors",
"target": "dtmi:com:adt:dtsample:floor;1",
"properties": [
{
"@type": "Property",
"name": "lastOccupied",
"schema": "dateTime"
}
]
}
]
}
Components
This section goes into more detail about components in DTDL models.
For a comprehensive list of the fields that may appear as part of a component, see Component in the DTDL v3 Language Description.
Basic component example
Here's a basic example of a component on a DTDL model. This example shows a Room model that makes use of a thermostat model as a component.
[
{
"@id": "dtmi:com:adt:dtsample:room;1",
"@type": "Interface",
"@context": [
"dtmi:dtdl:context;3",
"dtmi:dtdl:extension:quantitativeTypes;1"
],
"displayName": "Room",
"extends": "dtmi:com:adt:dtsample:core;1",
"contents": [
{
"@type": ["Property", "Humidity"],
"name": "humidity",
"schema": "double",
"unit": "gramPerCubicMetre"
},
{
"@type": "Component",
"name": "thermostat",
"schema": "dtmi:com:adt:dtsample:thermostat;1"
},
{
"@type": "Relationship",
"@id": "dtmi:com:adt:dtsample:room:rel_has_sensors;1",
"name": "rel_has_sensors",
"displayName": "Room has sensors"
}
]
},
{
"@context": [
"dtmi:dtdl:context;3",
"dtmi:dtdl:extension:quantitativeTypes;1"
],
"@id": "dtmi:com:adt:dtsample:thermostat;1",
"@type": "Interface",
"displayName": "thermostat",
"contents": [
{
"@type": ["Property", "Temperature"],
"name": "temperature",
"schema": "double",
"unit": "degreeFahrenheit"
}
]
}
]
If other models in this solution should also contain a thermostat, they can reference the same thermostat model as a component in their own definitions, just like Room does.
Important
The component interface (thermostat in the example above) must be defined in the same array as any interfaces that use it (Room in the example above) in order for the component reference to be found.
Model inheritance
Sometimes, you may want to specialize a model further. For example, it might be useful to have a generic model Room, and specialized variants ConferenceRoom and Gym. To express specialization, DTDL supports inheritance. Interfaces can inherit from one or more other interfaces. You can do so by adding an extends
field to the model.
The extends
section is an interface name, or an array of interface names (allowing the extending interface to inherit from multiple parent models). A single parent can serve as the base model for multiple extending interfaces.
Note
In DTDL v2, each extends
can have at most two interfaces listed for it. In DTDL v3, there is no limit on the number of immediate values for an extends
.
In both DTDL v2 and v3, the total depth limit for an extends
hierarchy is 10.
The following example re-imagines the Home model from the earlier DTDL example as a subtype of a larger "core" model. The parent model (Core) is defined first, and then the child model (Home) builds on it by using extends
.
{
"@id": "dtmi:com:adt:dtsample:core;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Core",
"contents": [
{
"@type": "Property",
"name": "id",
"schema": "string"
},
{
"@type": "Property",
"name": "name",
"schema": "string"
}
]
}
{
"@id": "dtmi:com:adt:dtsample:home;1",
"@type": "Interface",
"@context": "dtmi:dtdl:context;3",
"displayName": "Home",
"extends": "dtmi:com:adt:dtsample:core;1",
"contents": [
{
In this case, Core contributes an ID and name to Home. Other models can also extend the Core model to get these properties as well. Here's a Room model extending the same parent interface:
{
"@id": "dtmi:com:adt:dtsample:room;1",
"@type": "Interface",
"@context": [
"dtmi:dtdl:context;3",
"dtmi:dtdl:extension:quantitativeTypes;1"
],
"displayName": "Room",
Once inheritance is applied, the extending interface exposes all properties from the entire inheritance chain.
The extending interface can't change any of the definitions of the parent interfaces; it can only add to them. It also can't redefine a capability already defined in any of its parent interfaces (even if the capabilities are defined to be the same). For example, if a parent interface defines a double
property mass
, the extending interface can't contain a declaration of mass
, even if it's also a double
.
DTDL v3 feature extensions
DTDL v3 enables language extensions that define additional metamodel classes, which you can use to write richer models. This section describes the feature extension classes that you can use to add non-core features to your DTDL v3 models.
Each feature extension is identified by its context specifier, which is a unique Digital Twin Model Identifier (DTMI) value. To enable a feature extension in a model, add the extension's context specifier to the model's @context
field (alongside the general DTDL context specifier of dtmi:dtdl:context;3
). You can add multiple feature extensions to the same model.
Here's an example of what that @context
field might look like with feature extensions. The following excerpt is from a model that uses both the QuantitativeTypes extension and the Annotation extension.
"@context": [
"dtmi:dtdl:context;3",
"dtmi:dtdl:extension:quantitativeTypes;1",
"dtmi:dtdl:extension:annotation;1"
]
After you've added a feature extension to a model, you'll have access to that extension's adjunct types within the model. You can add adjunct types to the @type
field of a DTDL element, to give the element additional capabilities. The adjunct type may add additional properties to the element.
For example, here's an excerpt from a model that's using the Annotation extension. This extension has an adjunct type called ValueAnnotation
, which is added in the example below to a property element. Adding this adjunct type to the property element allows the element to have an additional annotates
field, which is used to indicate another property that is annotated by this element.
{
"@type": [ "Property", "ValueAnnotation" ],
"name": "currentTempAccuracy",
"annotates": "currentTemp",
"schema": "double"
},
The rest of this section explains the Annotation extension and other DTDL v3 feature extensions in more detail.
Annotation extension
The Annotation extension is used to add custom metadata to a property element in a DTDL v3 model. Its context specifier is dtmi:dtdl:extension:annotation;1
.
This extension includes the ValueAnnotation
adjunct type, which can be added to a DTDL property element. The ValueAnnotation
type adds one field to the element, annotates
, which allows you to name another property that is annotated by the current element.
For more details and examples of this extension, see Annotation extension in the DTDL v3 Language Description.
Historization extension
The Historization extension is used to designate a property in a DTDL v3 model as something that should be historized (meaning the historical sequence of its values should be recorded, along with times at which the values change). Its context specifier is dtmi:dtdl:extension:historization;1
.
This extension includes the Historized
adjunct type, which can be added as a co-type to a DTDL property element to indicate that the service should persist the element's historical values and make them available for querying and analytics. The Historized
adjunct type doesn't add any fields to the element.
For more details and examples of this extension, see Historization extension in the DTDL v3 Language Description.
Overriding extension
The overriding extension is used to override a property in a DTDL V3 model with an instance value. It's used in combination with the annotation extension, and its context specifier is dtmi:dtdl:extension:overriding;1
.
This extension includes the Override
adjunct type, which can be added to a DTDL property that is also co-typed with ValueAnnotation
(from the annotation extension). The Override
type adds one field to the element, overrides
, which allows you to name a field on the annotated element to be overridden by the current element's value.
For more details and examples of this extension, see Overriding extension in the DTDL v3 Language Description.
QuantitativeTypes extension
The QuantitativeTypes extension is used to enable semantic types, unit types, and units in a DTDL v3 model. Its context specifier is dtmi:dtdl:extension:quantitativeTypes;1
.
This extension enables the use of many semantic types as adjunct types, which can be added to a CommandRequest, a Field, a MapValue, or a property in DTDL v3. Semantic types add one field to the element, unit
, which accepts a valid unit that corresponds to the semantic type.
For more details about the extension, including examples and a full list of supported semantic types and units, see QuantitativeTypes extension in the DTDL v3 Language Description.
Service-specific DTDL notes
Not all services that use DTDL implement the exact same features of DTDL. There are some DTDL features that Azure Digital Twins doesn't currently support, including:
- DTDL commands
- The
writable
attribute on properties or relationships. Although this attribute can be set as per DTDL specifications, the value isn't used by Azure Digital Twins. Instead, these attributes are always treated as writable by external clients that have general write permissions to the Azure Digital Twins service. - The
minMultiplicity
andmaxMultiplicity
properties on relationships. Although these attributes can be set as per DTDL specifications, the values aren't enforced by Azure Digital Twins.
For a DTDL model to be compatible with Azure Digital Twins, it must also meet these requirements:
- All top-level DTDL elements in a model must be of type
Interface
. The reason for this requirement is that Azure Digital Twins model APIs can receive JSON objects that represent either an interface or an array of interfaces. As a result, no other DTDL element types are allowed at the top level. - DTDL for Azure Digital Twins must not define any commands.
- Azure Digital Twins only allows a single level of component nesting, meaning that an interface that's being used as a component can't have any components itself.
- Interfaces can't be defined inline within other DTDL interfaces; they must be defined as separate top-level entities with their own IDs. Then, when another interface wants to include that interface as a component or through inheritance, it can reference its ID.
Modeling tools and best practices
This section describes additional considerations and recommendations for modeling.
Use existing industry-standard ontologies
An ontology is a set of models that comprehensively describe a given domain, like manufacturing, building structures, IoT systems, smart cities, energy grids, web content, and more.
If your solution is for a certain industry that uses any sort of modeling standard, consider starting with a pre-existing set of models designed for your industry instead of designing your models from scratch. Microsoft has partnered with domain experts to create DTDL model ontologies based on industry standards, to help minimize reinvention and encourage consistency and simplicity across industry solutions. You can read more about these ontologies, including how to use them and what ontologies are available now, in What is an ontology?.
Consider query implications
While designing models to reflect the entities in your environment, it can be useful to look ahead and consider the query implications of your design. You may want to design properties in a way that will avoid large result sets from graph traversal. You may also want to model relationships that will need to be answered in a single query as single-level relationships.
Validate models
After creating a model, it's recommended to validate your models offline before uploading them to your Azure Digital Twins instance.
To help you validate your models, a .NET client-side DTDL parsing library is provided on NuGet: DTDLParser. You can use the parser library directly in your C# code. You can also view sample use of the parser in the DTDLParserResolveSample in GitHub.
Upload and delete models in bulk
Once you're finished creating, extending, or selecting your models, you need to upload them to your Azure Digital Twins instance to make them available for use in your solution.
You can upload many models in a single API call using the Import Jobs API. The API can simultaneously accept up to the Azure Digital Twins limit for number of models in an instance, and it automatically reorders models if needed to resolve dependencies between them. For detailed instructions and examples that use this API, see bulk import instructions for models.
An alternative to the Import Jobs API is the Model uploader sample, which uses the individual model APIs to upload multiple model files at once. The sample also implements automatic reordering to resolve model dependencies. It currently only works with version 2 of DTDL.
If you need to delete all models in an Azure Digital Twins instance at once, you can use the Model Deleter sample. This is a project that contains recursive logic to handle model dependencies through the deletion process. It currently only works with version 2 of DTDL.
Or, if you want to clear out the data in an instance by deleting all the models along with all twins and relationships, you can use the Delete Jobs API.
Visualize models
Once you have uploaded models into your Azure Digital Twins instance, you can use Azure Digital Twins Explorer to view them. The explorer contains a list of all models in the instance, as well as a model graph that illustrates how they relate to each other, including any inheritance and model relationships.
Note
Currently, Azure Digital Twins Explorer fully supports DTDL v2 models and supports limited functionality for DTDL v3 models.
DTDL v3 models can be viewed in the Models panel, and twins created with DTDL v3 models can be viewed and edited (including those with array properties). However, DTDL v3 models won't show up in the Model Graph panel, and they can't be imported using Azure Digital Twins Explorer. To import DTDL v3 models to your instance, use another developer interface like the APIs and SDKs or the Azure CLI.
Here's an example of what a model graph might look like:
For more information about the model experience in Azure Digital Twins Explorer, see Explore models and the Model Graph.
Next steps
Learn about creating models based on industry-standard ontologies: What is an ontology?
Dive deeper into managing models with API operations: Manage DTDL models
Learn about how models are used to create digital twins: Digital twins and the twin graph
Feedback
https://aka.ms/ContentUserFeedback.
Coming soon: Throughout 2024 we will be phasing out GitHub Issues as the feedback mechanism for content and replacing it with a new feedback system. For more information see:Submit and view feedback for