# Update the definition of an existing Thing

`POST /api/2/things/{thingId}/migrateDefinition`

Updates the definition of the specified thing by providing a new definition URL along with an optional migration payload.

The request body allows specifying:
- A new Thing definition URL.
- A migration payload containing updates to attributes and features.
- Patch conditions to ensure consistent updates.
- Whether properties should be initialized if missing.

**Placeholders in migration payload:** String values in `migrationPayload` may use the thing-json
placeholder. Both brace `{{ thing-json:<json-pointer> }}` and legacy `${ thing-json:<json-pointer> }`
are supported. 

If the `dry-run` query parameter or header is set to `true`, the request will return the calculated migration result without applying any changes.

### Example:
```json
{
  "thingDefinitionUrl": "https://example.com/new-thing-definition.json",
  "migrationPayload": {
    "attributes": {
      "manufacturer": "New Corp"
    },
    "features": {
      "sensor": {
        "properties": {
          "status": {
            "temperature": {
              "value": 25.0
            }
          }
        }
      }
    }
  },
  "patchConditions": {
    "thing:/features/sensor": "not(exists(/features/sensor))"
  },
  "initializeMissingPropertiesFromDefaults": true
}
```

Authentication (security requirement alternatives):

```json
[
  {
    "OpenIDConnect": []
  },
  {
    "NginxBasic": []
  },
  {
    "Bearer": []
  }
]
```

- OpenIDConnect: openIdConnect. OpenID Connect Discovery URL. The placeholder is replaced by Swagger UI when configured.
- NginxBasic: http (basic). Eclipse Ditto sandbox demo user (demo1 ... demo9) + password (demo)
- Bearer: http (bearer). A JSON Web Token issued by a supported OAuth 2.0 Identity Provider.

Parameters:

- `thingId` (path, string, required) - The ID of a thing needs to follow the namespaced entity ID notation (see [Ditto documentation on namespaced entity IDs](https://www.eclipse.dev/ditto/basic-namespaces-and-names.html#namespaced-id)).
  Type: string

- `dry-run` (query, boolean, optional) - If set to `true`, performs a dry-run and returns the migration result without applying changes.
  Type: boolean
  
  default: false

Request body: application/json (required)

JSON payload containing the new definition URL, migration payload, patch conditions, and initialization flag.

Type: MigrateThingDefinitionRequest

JSON payload to migrate the definition of a Thing.

Schema: [MigrateThingDefinitionRequest](https://sourcey-ditto.pages.dev/http-api-doc/models/migratethingdefinitionrequest.md)

- `thingDefinitionUrl` (required)
  Type: string, uri
  
  The URL of the new Thing definition to be applied.
  
  Example:
  
  ```json
  "https://models.example.com/thing-definition-1.0.0.tm.jsonld"
  ```

- `migrationPayload` (optional)
  Type: object
  
  Optional migration payload with updates to attributes and features.
  String values may contain {{ thing-json:<json-pointer> }} placeholders to reference
  existing Thing data (e.g. attributes/location, features/sensor/properties/temp).
  Resolved values keep their JSON type; missing paths cause the request to fail.
  
  
  - `attributes` (optional)
    Type: object
    
    Attributes to be updated in the thing.
    
    Example:
    
    ```json
    {
      "manufacturer": "New Corp",
      "location": "Berlin, main floor"
    }
    ```
    
    Additional properties: true
  
  - `features` (optional)
    Type: object
    
    Features to be updated in the thing.
    
    Example:
    
    ```json
    {
      "thermostat": {
        "properties": {
          "status": {
            "temperature": {
              "value": 23.5,
              "unit": "DEGREE_CELSIUS"
            }
          }
        }
      }
    }
    ```
    
    Additional properties: 
      Type: object
      
      - `properties` (optional)
        Type: object
        
        Additional properties: true

- `patchConditions` (optional)
  Type: object
  
  Optional conditions to apply the migration only if the existing thing matches the specified values.
  
  Example:
  
  ```json
  {
    "thing:/features/thermostat": "not(exists(/features/thermostat))"
  }
  ```
  
  Additional properties: 
    Type: string

- `initializeMissingPropertiesFromDefaults` (optional)
  Type: boolean
  
  Flag indicating whether missing properties should be initialized with default values.
  
  default: false
  
  Example:
  
  ```json
  true
  ```

Responses:

- 200: The thing definition was successfully updated, and the updated Thing is returned.

Content type: application/json

Type: MigrateThingDefinitionResponse

Response payload after applying or simulating a migration to a Thing.

Schema: [MigrateThingDefinitionResponse](https://sourcey-ditto.pages.dev/http-api-doc/models/migratethingdefinitionresponse.md)

- `thingId` (required)
  Type: string
  
  Unique identifier representing the migrated Thing.

- `patch` (required)
  Type: object
  
  The patch containing updates to the Thing.
  
  - `definition` (optional)
    Reference: [Definition](https://sourcey-ditto.pages.dev/http-api-doc/models/definition.md); Type: Definition
    
    A single fully qualified identifier of a definition in the form '<namespace>:<name>:<version>' or a valid HTTP(s) URL
    
    pattern: "([_a-zA-Z0-9\\-.]+):([_a-zA-Z0-9\\-.]+):([_a-zA-Z0-9\\-.]+)"
  
  - `attributes` (optional)
    Reference: [Attributes](https://sourcey-ditto.pages.dev/http-api-doc/models/attributes.md); Type: Attributes
    
    An arbitrary JSON object describing the attributes of a thing.
  
  - `features` (optional)
    Reference: [Features](https://sourcey-ditto.pages.dev/http-api-doc/models/features.md); Type: Features
    
    List of features where the key represents the `featureId` of each feature.
    The `featureId` key must be unique in the list.

- `mergeStatus` (required)
  Type: string
  
  Indicates the result of the migration process.
  - `APPLIED`: The migration was successfully applied.
  - `DRY_RUN`: The migration result was calculated but not applied.
  
  
  enum: ["APPLIED","DRY_RUN"]
  
  Example:
  
  ```json
  "APPLIED"
  ```

- 202: Dry-run successful. The migration result is returned without applying changes.

Content type: application/json

Type: MigrateThingDefinitionResponse

Response payload after applying or simulating a migration to a Thing.

Schema: [MigrateThingDefinitionResponse](https://sourcey-ditto.pages.dev/http-api-doc/models/migratethingdefinitionresponse.md)

- `thingId` (required)
  Type: string
  
  Unique identifier representing the migrated Thing.

- `patch` (required)
  Type: object
  
  The patch containing updates to the Thing.
  
  - `definition` (optional)
    Reference: [Definition](https://sourcey-ditto.pages.dev/http-api-doc/models/definition.md); Type: Definition
    
    A single fully qualified identifier of a definition in the form '<namespace>:<name>:<version>' or a valid HTTP(s) URL
    
    pattern: "([_a-zA-Z0-9\\-.]+):([_a-zA-Z0-9\\-.]+):([_a-zA-Z0-9\\-.]+)"
  
  - `attributes` (optional)
    Reference: [Attributes](https://sourcey-ditto.pages.dev/http-api-doc/models/attributes.md); Type: Attributes
    
    An arbitrary JSON object describing the attributes of a thing.
  
  - `features` (optional)
    Reference: [Features](https://sourcey-ditto.pages.dev/http-api-doc/models/features.md); Type: Features
    
    List of features where the key represents the `featureId` of each feature.
    The `featureId` key must be unique in the list.

- `mergeStatus` (required)
  Type: string
  
  Indicates the result of the migration process.
  - `APPLIED`: The migration was successfully applied.
  - `DRY_RUN`: The migration result was calculated but not applied.
  
  
  enum: ["APPLIED","DRY_RUN"]
  
  Example:
  
  ```json
  "APPLIED"
  ```

- 400: The request could not be processed due to invalid input.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

- 401: Unauthorized request due to missing authentication.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

- 404: The specified thing could not be found.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

- 412: The update conditions were not met.

Content type: application/json

Type: AdvancedError

Schema: [AdvancedError](https://sourcey-ditto.pages.dev/http-api-doc/models/advancederror.md)

- `status` (required)
  Type: integer
  
  The HTTP status of the error

- `error` (required)
  Type: string
  
  The error code of the occurred exception

- `message` (required)
  Type: string
  
  The message of the error - what went wrong

- `description` (optional)
  Type: string
  
  A description how to fix the error or more details

- `href` (optional)
  Type: string
  
  A link to further information about the error and how to fix it

## Examples

### cURL

```bash
curl -X POST 'https://ditto.eclipseprojects.io/api/2/things/string/migrateDefinition?dry-run=false' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'Content-Type: application/json' \
  --data-raw '{
  "thingDefinitionUrl": "https://models.example.com/thing-definition-1.0.0.tm.jsonld",
  "migrationPayload": {
    "attributes": {
      "manufacturer": "New Corp",
      "location": "Berlin, main floor"
    },
    "features": {
      "thermostat": {
        "properties": {
          "status": {
            "temperature": {
              "value": 23.5,
              "unit": "DEGREE_CELSIUS"
            }
          }
        }
      }
    }
  },
  "patchConditions": {
    "thing:/features/thermostat": "not(exists(/features/thermostat))"
  },
  "initializeMissingPropertiesFromDefaults": true
}'
```

### JavaScript

```javascript
const body = `{
  "thingDefinitionUrl": "https://models.example.com/thing-definition-1.0.0.tm.jsonld",
  "migrationPayload": {
    "attributes": {
      "manufacturer": "New Corp",
      "location": "Berlin, main floor"
    },
    "features": {
      "thermostat": {
        "properties": {
          "status": {
            "temperature": {
              "value": 23.5,
              "unit": "DEGREE_CELSIUS"
            }
          }
        }
      }
    }
  },
  "patchConditions": {
    "thing:/features/thermostat": "not(exists(/features/thermostat))"
  },
  "initializeMissingPropertiesFromDefaults": true
}`;

const response = await fetch('https://ditto.eclipseprojects.io/api/2/things/string/migrateDefinition?dry-run=false', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN',
    'Content-Type': 'application/json',
  },
  body,
});

const data = await response.text();
```

### Python

```python
import requests

body = '''{
  "thingDefinitionUrl": "https://models.example.com/thing-definition-1.0.0.tm.jsonld",
  "migrationPayload": {
    "attributes": {
      "manufacturer": "New Corp",
      "location": "Berlin, main floor"
    },
    "features": {
      "thermostat": {
        "properties": {
          "status": {
            "temperature": {
              "value": 23.5,
              "unit": "DEGREE_CELSIUS"
            }
          }
        }
      }
    }
  },
  "patchConditions": {
    "thing:/features/thermostat": "not(exists(/features/thermostat))"
  },
  "initializeMissingPropertiesFromDefaults": true
}'''

response = requests.post(
    'https://ditto.eclipseprojects.io/api/2/things/string/migrateDefinition?dry-run=false',
    data=body.encode('utf-8'),
    headers={
        'Authorization': 'Bearer YOUR_TOKEN',
        'Content-Type': 'application/json',
    },
)
print(response.text)
```
