Creating a Digital Twin Model
Create a digital twin model for your Internet of Things (IoT).
A digital twin model defines the semantics of a digital twin and is based on the DTDL v3 specifications. A digital twin model uses a Digital Twin Model Identifier (DTMI) as a unique identifier.
For example: dtmi:com:oracle:iot:connectable;1
The required digital twin model context that indicates the digital twin model uses DTDL specifications v3: dtmi:dtdl:context;3
A digital twin instance requires a digital twin model and a digital twin adapter to receive structured device data. For specific examples, see Scenarios.
Digital Twins Definition Language (DTDL) v3 is supported on GitHub by the Digital Twin Consortium. It is important to note:
- MQTT extensions and writable properties are not supported. If a
writableproperty is included, it must be set tofalse. - Only the
contentwithin the component can be annotated ashistorized, indicating the IoT platform must retain that sensor’s time-series telemetry, see the digital twin model exampledtdl-model-specifications.jsonbelow.
If you want to create a digital twin instance without ingestible data from a device, then you can create a digital twin instance without a digital twin adapter and without the authentication ID parameter, --auth-id. The associated digital twin model must not contain telemetry or properties. After, you create a digital twin instance, then you can create a digital twin relationship to simulate your IoT environment without the complexity of data or authentication.
Use the oci iot digital-twin-model create command and required parameters to create a digital twin model in a specific IoT domain. Provide the specifications as JSON content directly in the command line or as a file referenced in the command line:
Inline example: This example shows providing the JSON specifications directly in the command line:
oci iot digital-twin-model create --iot-domain-id <iot-domain-OCID> --spec '{"@context": ["dtmi:dtdl:context;3", "dtmi:dtdl:extension:historization;1", "dtmi:dtdl:extension:quantitativeTypes;1", "dtmi:com:oracle:dtdl:extension:validation;1"], "@id": "dtmi:com:oracle:iot:sample:hvac:UgNaNWHbzK;1", "@type": "Interface", "contents": [{"@type": ["Telemetry", "Temperature"], "name": "temperature", "schema": "integer", "unit": "degreeFahrenheit"}, {"@type": ["Telemetry", "Historized", "Validated"], "name": "humidity", "schema": "integer", "minimum": 0, "maximum": 100}, {"@type": ["Property", "Historized"], "name": "location", "schema": "point", "writable": true}, {"@type": ["Property", "Validated"], "name": "serialNumber", "schema": "string", "pattern": "^([0-9]){2}([0-9]){5}([0-9]){6}$"}]}'File reference example: This example shows how to create a
dtdl-model-specifications.jsonfile that contains your specifications, how to reference the.jsonfile in the command. The format may vary based on your operating system for more information about referencing files, see Using a JSON File for Complex Input:oci iot digital-twin-model create --iot-domain-id <iot-domain-OCID> --spec file://dtdl-model-specifications.jsonIn this snippet from the example digital twin model below:- Notice the
humidityvalue is annotated ashistorizedtelemetry, so each humidity reading is stored as a time-series measurement with atimeObservedtimestamp, instead of only recording the latest value. - It’s also validated to be an
integerin the range0–100. Only the content within a component can be annotated as historized notice this@typedeclaration in the example below.
{ "@type": ["Telemetry","Historized","Validated"], "name": "humidity", "schema": "integer", "minimum": 0, "maximum": 100 }In this HVAC model,dtdl-model-specifications.json- This model is based on the DTDL v3 specification and contains a Digital Twin Model Identifier (DTMI) as a unique identifier:
@id: "dtmi:com:oracle:iot:sample:hvac:<unique-id>;1" - This example digital twin model enables the historization, qualitative types, and the validation extension contexts. See DTMI Validation Extension Reference.
- As described in the snippet above the
humiditytelemetry is annotated asHistorized, so the humidity readings are retained as time series data, readings over time. locationtelemetry is annotated asHistorized, so changes to the location are also retained over time, recording property's location history with an audit trail.temperaturetelemetry is not annotated with Historized, recording only the last known value another downstream persistence configured somewhere else.serialNumberproperty is markedValidatedusing a regex pattern and is not annotated as Historized, so only the current or latest value is maintained not a historical tracking of changes.
{ "@context": [ "dtmi:dtdl:context;3", "dtmi:dtdl:extension:historization;1", "dtmi:dtdl:extension:quantitativeTypes;1", "dtmi:com:oracle:dtdl:extension:validation;1" ], "@id": "dtmi:com:oracle:iot:sample:hvac:UgNaNWHbzK;1", "@type": "Interface", "contents": [ { "@type": [ "Telemetry", "Temperature" ], "name": "temperature", "schema": "integer", "unit": "degreeFahrenheit" }, { "@type": [ "Telemetry", "Historized", "Validated" ], "name": "humidity", "schema": "integer", "minimum": 0, "maximum": 100 }, { "@type": [ "Property", "Historized" ], "name": "location", "schema": "point", "writable": false }, { "@type": [ "Property", "Validated" ], "name": "serialNumber", "schema": "string", "pattern": "^([0-9]){2}([0-9]){5}([0-9]){6}$" } ] }This example CLI response shows the digital twin model was created for the IoT domain, with a DTMI URI:
dtmi:com:oracle:iot:sample:hvac:unique-id;1:{ "data": { "defined-tags": { "Oracle-Tags": { "CreatedBy": "default/user", "CreatedOn": "2025-08-05T17:43:00.438Z" } }, "description": null, "display-name": "HVAC", "freeform-tags": {}, "id": "<iot-digital-twin-model-OCID>", "iot-domain-id": "<iot-domain-OCID>", "lifecycle-state": "ACTIVE", "spec-uri": "dtmi:com:oracle:iot:sample:hvac:unique-id;1", "system-tags": {}, "time-created": "2025-08-05T17:43:00.508000+00:00", "time-updated": "2025-08-05T17:43:00.508000+00:00" }, "etag": "<unique-id>" }For a complete list of parameters and values for CLI commands, see CLI Command Reference
- Notice the
Run the CreateDigitalTwinModel operation to create a digital twin model in the specific IoT domain.
Example request:
POST /20250531/digitalTwinModels content-type: application/json+ld { "@context": ["dtmi:dtdl:context;3"], "@id": "dtmi:com:oracle:labauto:SmartSpecimenVault;1", "@type": "Interface", "extends": "dtmi:com:oracle:iot:connectable;1", "displayName": "HVAC", "contents": [ {"@type": "Telemetry", "name": "temperature", "schema": "integer"}, {"@type": "Telemetry", "name": "humidity", "schema": "integer", "minimum":0, "maximum": 100}, {"@type": "Property", "name": "desiredTemperature", "schema": "integer", "writable": false}, {"@type": "Property", "name": "serialNumber", "schema": "string"} ] }Example response:
header: content-type: application/json Body: { "id": "<digital-twin-model-OCID>" "displayName": "<your-HVAC-display-name>", "description": "<digital-twin-model-for-HVAC>" "lifecycleState": "ACTIVE", "freeformTags": {}, "definedTags": { "Oracle-Tags": { "CreatedBy": "default/user@oracle.com", "CreatedOn": "2024-07-22T10:24:53.446Z" } }, "specUri": "dtmi:com:oracle:labauto:SmartSpecimenVault;1" "timeCreated": "2025-01-13T10:24:53Z", "timeUpdated": "2025-01-14T17:15:21Z" }