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.

Note

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 writable property is included, it must be set to false.
  • Only the content within the component can be annotated as historized, indicating the IoT platform must retain that sensor’s time-series telemetry, see the digital twin model example dtdl-model-specifications.json below.

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.json file that contains your specifications, how to reference the .json file 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.json
    In this snippet from the example digital twin model below:
    • Notice the humidity value is annotated as historized telemetry, so each humidity reading is stored as a time-series measurement with a timeObserved timestamp, instead of only recording the latest value.
    • It’s also validated to be an integer in the range 0–100. Only the content within a component can be annotated as historized notice this @type declaration 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 humidity telemetry is annotated as Historized, so the humidity readings are retained as time series data, readings over time.
    • location telemetry is annotated as Historized, so changes to the location are also retained over time, recording property's location history with an audit trail.
    • temperature telemetry is not annotated with Historized, recording only the last known value another downstream persistence configured somewhere else.
    • serialNumber property is marked Validated using 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

  • 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"
    }