# Getting Started


# Introduction

## Overview on Datome

Mangrovia Blockchain Solutions is the leading Italian company in designing and developing enhanced services and fully integrated solutions based on blockchain technologies for more efficient, reliable and certified data and information flow management.

Datome is Mangrovia’s Platform As A Service for data modeling and data governance based on blockchain technology. Datome allows clients to easily integrate all the advantages of the blockchain into their existing data infrastructure without any need to understand the underlying technology and the complexity of smart contract development.

Datome combines blockchain technology (BC) , data management (DM) and business process management (BPM) to deliver a robust, secure and scalable Platform As A Service that you can easily configure in self provisioning.

Datome delivers a trustworthy database that can embed your processes and connect to your users, legacy applications and existing BPM or DM.

<figure><img src="/files/0Cpg9II9FBCPxKxt5HNR" alt="" width="324"><figcaption></figcaption></figure>

Traditional enterprise applications that leverage on the blockchain are difficult to configure and limited to tracking changes. Datome, whilst granting an easy configuration, adds the feature of validating such changes and provides trust by design.\
Picture a crossroad. The usual blockchain enterprise application is like a camera taking pictures of the traffic. Datome is like a traffic warden ruling which cars are allowed to pass.

Without Datome, data is passive and accepts any writing request depending on the scattered rules of each application or user. With Datome, data becomes intelligent, embeds the rules for validating its own updates and may guarantee complete integrity, traceability and lineage via a [Finite State Machine](https://en.wikipedia.org/wiki/Finite-state_machine).

Already have a BPM? Traditional Business Process Management (BPM) solutions focus on orchestrating processes and do not deal with validation. Datome connects to your critical steps so you can certify their integrity, traceability and lineage.

<figure><img src="/files/UnOW0CGtFJHKNVO6UzOM" alt=""><figcaption></figcaption></figure>

## Use it as you wish

Datome can be easily used in self-provisioning by the developers of your organization without any knowledge of blockchain technologies but simply configuring JSON APIs. Ask your dev team to subscribe to a free 30-days fully featured sandbox.

No in-house developers? No problem. If you wish to have a fully managed solution, our staff can provide the setup and maintenance you need.

Datome can also be embedded into third party solutions so that, if you are serving your clients via your own application, you can retrofit it in order to provide the added value of data certification. You can opt to fully manage Datome for your clients or let them deal with some settings such as creating their users and privileges.

## Benefits

* Safeguard the integrity and authenticity of the data when it is written by different applications.
* Validate incoming information from customers or suppliers.
* Protect your organization against third party claims (e.g. regulators challenging the correct execution of a process).
* Enable sharing of the same ledger between third parties (e.g. in case of supply agreements based on performance).
* Query your data as quickly as from a standard database.
* Design a process flow into one single environment to simplify its management and the interactions between different systems. This means avoiding risks of errors or duplications, easier management of security, easier compliance with third party certifications such as ISO/IEC 27001
* Track Assets along the supply chain or along any process and return consistent and valid information for all stakeholders.
* Simplify data orchestration when your company is leveraging data streaming (e.g. Kafka).

## Personas

<table><thead><tr><th width="176">Benefit</th><th width="203" align="center">Application Architect, CTO, CIO, CDO</th><th align="center">Quality manager</th><th align="center">Risk Manager, Legal, CEO</th><th align="center">CFO</th><th align="center">CMO</th></tr></thead><tbody><tr><td>Integrity of data</td><td align="center">x</td><td align="center">x</td><td align="center"></td><td align="center">x</td><td align="center"></td></tr><tr><td>Validating inputs</td><td align="center">x</td><td align="center">x</td><td align="center"></td><td align="center"></td><td align="center"></td></tr><tr><td>Protect against claims</td><td align="center"></td><td align="center"></td><td align="center">x</td><td align="center"></td><td align="center"></td></tr><tr><td>Share the same ledger</td><td align="center">x</td><td align="center"></td><td align="center"></td><td align="center">x</td><td align="center"></td></tr><tr><td>Quickly queryable</td><td align="center">x</td><td align="center"></td><td align="center"></td><td align="center">x</td><td align="center"></td></tr><tr><td>Simplify management of business logic</td><td align="center">x</td><td align="center">x</td><td align="center"></td><td align="center"></td><td align="center"></td></tr><tr><td>Track along the supply chain</td><td align="center">x</td><td align="center">x</td><td align="center">x</td><td align="center"></td><td align="center">x</td></tr><tr><td>Simplify data orchestration</td><td align="center">x</td><td align="center"></td><td align="center"></td><td align="center"></td><td align="center"></td></tr></tbody></table>

## Features

* Creates a certified database for your relevant processes.
* Quickly integrable into any IT ecosystem via REST services.
* Available in self-provisioning or with the consultancy of our staff.
* Interactable by people, software applications and/or IoT devices.
* Unlimited Assets, Models, Users.
* Real time monitoring.
* Advanced management of Users, groups and related privileges.
* Documents can be attached to Assets.
* Consortia-ready.
* Robust and scalable even across large organizations.
* Automation of compilations, verifications and operations.
* Free 30-days sandbox.
* Independent from underlying blockchain so, instead of Hyperledger Fabric, other technologies can be used.
* Public page look & feel customization (logo, colors, web domain).

Optional add-ons:

* multi organization management (retrofit your application to serve your clients);
* Document Management System;
* additional nodes and instances;
* premium support;
* consulting services.


# Quickstart Guide

This quick start guide will assist you in getting started with Datome, creating models, assets, and links between two models.

<figure><img src="/files/0La6gemB3Jx3xSMJzur0" alt=""><figcaption></figcaption></figure>

### Step 1: Log In to Your Datome Application

You can sign up for a free 30-day trial account at the bottom of [our website](https://www.datome.io/). During the registration process, you will generate a custom URL for your organization (i.e. https\://\[your\_organization].datome.io).

{% hint style="info" %}
The custom URL you create will be the URL to be used for logging in.
{% endhint %}

### Step 2: Create Models

At your first login, you’ll be taken to a wizard showing you the creation of two exemplary Models. Think of a Model as the blueprint for the rules and specifications of the Assets you want to track. An Asset can be a process, a digital object or a physical one.

The following steps will guide you to create two additional models that can later be linked.

#### Model 1 - Linen

1. Select the **Models** dropdown button.
2. Click + **new model** button.<br>

   <figure><img src="/files/BbEhe3MC9pZaOnmaXT7J" alt=""><figcaption></figcaption></figure>
3. Enter the Model’s **name** and **properties** or clone an existing model. In this example, we have specified the model’s name and properties as shown below:<br>

   <figure><img src="/files/9Tn6oLSecLGRQsrdy7bN" alt=""><figcaption></figcaption></figure>
4. Click **Save**.<br>

   <figure><img src="/files/lnPnw4pquqWAG5ZjivhM" alt=""><figcaption></figcaption></figure>

#### Model 2 - Denim

1. Select the **Models** dropdown button.
2. Click + **new model** button.<br>

   <figure><img src="/files/TYY4mYnanXjNK8YCYVME" alt=""><figcaption></figcaption></figure>
3. Enter the Model’s **name** and **properties**. In this example, we have specified the model’s name and properties as shown below:<br>

   <figure><img src="/files/hGBkiyyIsvXTE41RDV0U" alt=""><figcaption></figcaption></figure>

{% hint style="info" %}
A "**relation"** keyword is used and defined for Model 1 so that Model 2 and Model 1 can have a one-to-one relation.
{% endhint %}

4. Click **Save**.<br>

   <figure><img src="/files/8scq28Ez7UCMEvgyPtrm" alt=""><figcaption></figcaption></figure>

### Step 3: Create Assets

After successfully creating two models, you need to create an asset for each so that the models will have a one-to-one relation. Follow the steps below to create assets:

#### Model 1

1. Select the **Assets** **Search** dropdown button.
2. Click the newly created model **Linen**.<br>

   <figure><img src="/files/7ZEv4r9IxyOOu40uMz0h" alt=""><figcaption></figcaption></figure>
3. Click the + **Add new asset** button.<br>

   <figure><img src="/files/K568gJaBymVhlBM7QOQE" alt=""><figcaption></figcaption></figure>
4. Specify the required model **properties** as shown in the image below.<br>

   <figure><img src="/files/fJxlUa6rfCZ5hxe7znfC" alt=""><figcaption></figcaption></figure>
5. Click **Save**.<br>

   <figure><img src="/files/9qj1RojgPRoeCIoF9jX5" alt=""><figcaption></figcaption></figure>

#### Model 2

1. Select the **Assets** **Search** dropdown button.
2. Click the newly created model **Denim**.<br>

   <figure><img src="/files/CIbzsK7e3QwETsYLKBeM" alt=""><figcaption></figcaption></figure>
3. Click the + **Add new asset** button.<br>

   <figure><img src="/files/gD1QK5KHTE92dwC1Lozi" alt=""><figcaption></figcaption></figure>
4. Specify the required model **properties** as shown in the image below.<br>

   <figure><img src="/files/aWYeAELMbqhA985dyTSY" alt=""><figcaption></figcaption></figure>

> **Note**: As you can see in the image above, we can select Model 1’s asset that has just been created in the **relation** keyword.

5. Click **Save**.<br>

   <figure><img src="/files/R0AXHK84NUNWfLadiGPb" alt=""><figcaption></figcaption></figure>

### Step 4: View the Model Relation

You can see the Model’s relation with each other by clicking the **Relations** button on the main navigation menu.

<figure><img src="/files/BKhBRapxCDUJPYciTV5c" alt=""><figcaption></figcaption></figure>

The **Entity Relation-Diagram** between the models, can be seen in the relations window.

<figure><img src="/files/tzRpYRYsK8QyXB1OunyF" alt=""><figcaption></figcaption></figure>

### Step 5: Expanding the Features of Your Models

The Models we created above have no states (what you typically want to have to manage a process), no validation rules, nor authorized users. Check out the [Writing a Model](/writing-model) section to learn about all the features you can add.

The Datome UI, for the moment, only has a no-code tool for adding “properties” to a Model, but much more can be added using the JSON editor. You can also create and edit your models via Postman. Check the Swagger to learn how to get a Bearer token via a login and how to call a Model endpoint.

After you come to a version of your Model(s) that you’re happy with, you can create credentials for other users and have them create Assets. Users shall log in to your environment through your organization's custom URL. Alternatively, your users can create, edit, and read Assets via APIs. Users can be individuals, applications or IoTs.

Never hesitate to ask for support via our [discord](https://discord.com/invite/AT8DJJKFNw) channel or writing to <support@datome.io>


# Video Tutorial

In this video you can get an overview on how Datome works.

{% embed url="<https://www.youtube.com/watch?v=pe4nGbMlM04>" %}


# Product Architecture

### Users

Users are digital identities accessing the Datome web services. They are associated with a single purposed object, such as an IOT device, application, or individual.

A user owns a digital certificate signed by the internal Certificate Authority (CA), which is used to sign every blockchain operation and identifies univocally the user. Others cannot use it.

The ownership of a digital certificate does not automatically grant permission for all blockchain operations, as users must also be a member of a group (e.g. admin, model admin, or controller) to be permitted to carry out specific actions.

### Groups

Groups are clusters of users. A user is automatically a member of every sub-group and can belong to multiple groups. The group members acquire the permissions to access the data associated with the group.

### Models

A Model is the digital blueprint of the Assets we want to manage. One Model sets the rules for the N Assets that Datome shall manage. A Model describes the Asset’s properties (e.g., weight, materials), the relation with other Models (e.g., a blister can be part of a packaging), the actions that can be performed on the Asset data and the specific user groups that have permission to execute those actions.

Models can set powerful data flow control, defining a Finite State Machine (FSM), i.e. a system with a limited number of conditional states of being. It consists of a set of “states” along a process (e.g., “in progress”, “completed”, “shipped”) and a set of “transitions” that describe how the Asset moves from one state to another. A specific set of permissions and actions may characterize each state. The transition from one state to another is governed by a set of rules expressed in the Model and determines which state the machine will enter after any action.

The FSM implementation is optional, but every Model must include a default state. Each Model will always have at least one state and, optionally, additional states.

According to a custom JSON-schema syntax, administrators can create or update Models using any text editor enhanced with special keywords dedicated to Datome specification. Each saved Model comes with a version to track any updates.

### Assets

The asset is a representation in digital format of a process, a document, a physical object, a dataset or any other object. An Asset is created, updated or managed according to the specification, rules and constraints expressed by its Model. It can be linked to other Assets to describe provenance or composition. An Asset may have multiple blockchain registrations describing its history, and all the Asset registrations are cryptographically linked to the author’s digital certificate.

For example, Assets could be a car, the car’s ownership information, the maintenance details, or the car's insurance document.

### Model services

Datome provides web services for managing the Models.

### Document Services

Files can be linked to an Asset at any point in its lifecycle using the Document Services. Each document is transferred to a repository, while the description and hash value of the file are stored on the blockchain. When the document is read back, its content is compared to the hash information on the blockchain. The comparison between those two hash keys certifies the document's authenticity. The QA team can track all the certification phases together with the certification document.

### Blockchain Engine

Datome blockchain engine performs all the operations for maintaining the blockchain and executing all the user requests. Datome relies on the Hyperledger Foundation’s Fabric product for its internal blockchain.

### User/Group Services

Datome integrates user management software in which services are available via web services or web administration UI. Admin users manage groups, users and group memberships(roles). Group Admins are users that can perform administrative tasks inside a group boundary.

### Administrative Web Services

Datome offers a complete administration web environment for executing administrative tasks. These include all the tasks available via web services.

### User Web Services

User web services is a web-based environment users use for managing and browsing models and models information, according to their privileges.

### System Components

Datome platform is internally composed by:

* A Hyperledger Foundation Fabric custom installation with one or more blockchains (channels).
* Internal DBMS for services
* High-performance web server
* TLS certificates engine
* Datome application
* Datome fabric chaincodes (smart contracts)
* Datome stored procedures


# Writing Model


# Model Syntax

Models are written according to the [JSON-schema](https://json-schema.org/understanding-json-schema/reference/type.html) syntax.

A Model defines the asset's blueprint (data structure) we must manage with Datome. It is written according to the [JSON-schema](https://json-schema.org/understanding-json-schema/reference/type.html) Type-specific keyword documentation.


# Model Example

In this example, the Model syntax is introduced via the exemplary creation of a Model describing a Fabric (e.g. silk).

If you create a Model via API, a Post request is sent to an endpoint like https\://\[your\_organization].datome.io/api/models/fabric/. In this case, it will indicate that a new model named **Fabric** is being created. You will get a response with the following structure:

```jsx
{
  "$id": "string",
  "$schema": "string",
  "additionalProperties": boolean,
  "description": "string",
  "label": "string",
  "properties": {},
  "required": [],
  "search": [],
  "states": {
    "default_state": "string"
  },
  "title": "string",
  "type": "object",
}
```


# Model General Information

This section contains the Fabric model general information. Model general information will be defined as a JSON object with the following structure:

```jsx

curl --location 'https://[your_organization].datome.io/api/models/fabric/' \
--header 'Authorization: Bearer 74a6c88d-62fe-4c13-8b40-c21fabbae819' \
--header 'Content-Type: application/json' \
--data '
{
    "$id": "https://mangrovia.solutions/generic.json",
    "$schema": "https://json-schema.org/draft-07/schema",
    "title": "fabric",
    "description": "Fabric Model describes a fabric lot",
    "type": "object",
    "properties": {
        "unique_name": {
            "type": "string"
        },
        "id_technician": {
            "type": "number"
        },
        "id_employee": {
            "type": "number"
        },
        "available": {
            "type": "boolean"
        },
        "notes": {
            "type": "string"
        }
    },
    "required": [
    	"unique_name",
    	"id_technician",
    ],
    "additionalProperties": false,
    ...
}
```

\ <br>

> **Note**: The model name is set by the URL https\://\[your\_organization].datome.io/api/models/fabric, not by the “title” field.

\ <br>

| Fields               | Data Type | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| -------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| $id                  | String    | A fixed value required by JSON schema.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| $schema              | String    | A fixed value required by JSON schema.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| title                | String    | An optional field that defines the model’s name used in the UI.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| description          | String    | An optional field that describes the model and is shown in the UI.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| type                 | String    | A field that defines the Model type for backward compatibility. It must be equal to object.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| properties           | Object    | A list of the model’s characteristics.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| required             | Array     | An optional field that defines the mandatory properties at the creation of the model.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| search               | Array     | An optional field that defines the properties that can be used as search filters and will be listed in a column of the asset list.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| creation             | Array     | An optional field that defines the properties that will be asked at the moment of the asset’s creation.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ui order             | Array     | An optional field that defines the order that is used to display the asset’s properties.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| authorized\_groups   | Array     | An optional field that sets the privileges needed to create the Asset, update the Asset, change the Asset’s state.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| enum                 | Array     | An optional field that defines an array of values that a property can take on.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| states               | Object    | A field that defines the entry point of the Finite State Machine and every other possible state.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| transitions          | Object    | A field used to compose the transition map and define every other state besides the default\_state                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| mutations            | Object    | A field that defines a set of operations that modify the Asset’s Properties or State or log a new Event.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| additionalProperties | Boolean   | <p>A field that defines the JSON-schema keyword used to enhance the model with additional characteristics only during its creation. There are three possible values:<br><br>1. <strong>true</strong> - new properties can be declared directly in the API request without any kind of validation because they are defined “on-the-fly”.<br><br>2. <strong>Object</strong> - the additional properties are defined inside a JSON Object written using JSON-schema keywords. Hence, each new attribute can be optional or “required” (since the “object” is defined within a "properties" block).<br><br>3. <strong>false</strong> - Default, no additional properties have to be evaluated during the creation of the model.</p> |


# Keywords

### Identifier

Identifier sets a unique identifier for the model that will be used instead of the UUID produced by the platform. The value is a URI pointing to one of the properties (i.e. “unique\_name” in the example below). When each Asset is created, the platform will check that every new value for the identifier is unique. Setting an identifier in the Model is optional.

```jsx
"identifier": "#/properties/unique_name",
```

### Label

Label is a keyword that serves as a non-unique identifier for the model and is used solely in the user interface without any associated logic. The value consists of a URI that points to one of the properties.

To provide flexibility in defining labels, the JSON schema has been extended to allow the use of multiple labels. The `label` keyword is introduced, and it can be defined in two ways:

1. **As a String:**

   <pre class="language-json" data-title="nested in Root"><code class="lang-json">"label": "#/properties/serial_number"

   </code></pre>
2. **As an Object:**

   <pre class="language-json" data-title="nested in Root"><code class="lang-json"> "label": {
           "targets": [
               "#/properties/id",
               "#/properties/name"
           ],
           "separator": "_" 
       }
   </code></pre>

### Search

Search is an optional keyword used for listing the values addressable in the search endpoint.

```jsx
"search": [
    	"unique_name",
    	"type",
    	"meters",
    	"composition",
    	"manufacturer",
    	"invoice_number",
],
```

### Authorized Groups

**authorized\_groups**, when used at the first level, set the privileges needed to create the Asset. It identifies the entities with permission to create (and only create) the Asset. If this field is blank, everyone can create the Asset.

```jsx
"authorized_groups": [
    	"/root",
    	"/root/group1",
    	"/root/group2/sub-group",
],
```

> **Note**: **authorized\_groups** can be at the first level and/or within the **mutations** section. When it is inside the **mutations** section, it indicates which groups (roles) can launch that mutation and therefore **MODIFY** (only modify) the Asset.

### States

States define the entry point of the Finite State Machine and every other possible state. A Model does not need an FSM (i.e. more than one state), but each Model's declaration of a **default\_state** is mandatory. States are defined as a JSON object with the following structure:

```jsx
"states": {
    	"default_state": "created",
},
```

| Fields         | Data Type | Description                                               |
| -------------- | --------- | --------------------------------------------------------- |
| states         | Object    | A field that defines the model’s state.                   |
| default\_state | String    | A mandatory field that defines the default model’s state. |

### Transitions

Transition is nested inside the **states** block and is a Datome’s specific keyword used to compose the transition map and define every other state besides the **default\_state**.

It must contain at least one state besides the default state if specified. Transitions are defined as a JSON object with the following structure:

{% code title="nested in States " %}

```json
"transitions": {
        "send_to_quality_control": {
            "required_state": "manufacturing",
            "target_state": "quality_control"
        },
        "send_to_warehouse": {
            "required_state": "quality_control",
            "target_state": "warehouse"
        },
        "send_to_distribution": {
            "required_state": "warehouse",
            "target_state": "distribution"
        },
}
```

{% endcode %}

| Fields          | Data Type | Description                                                                                                |
| --------------- | --------- | ---------------------------------------------------------------------------------------------------------- |
| label           | Object    | A field that defines the label to transition to a new state.                                               |
| required\_state | String    | A field that defines the original state in which the model must be when the transition mutation is called. |
| target\_state   | String    | A field that defines the destination state.                                                                |

### Events

For each Asset, Datome shows the lists of the states it went through together with their timestamp. The sequence will follow the rules set in the transitions.

If there’s the need to log a situation at any point of the state's flow, we can add an **Event**. In the exemplary image below, the states are **issued**, **accepted**, and **shipped**, but an Event was logged between **accepted** and **shipped**. Authorized users can log any number of events.

<figure><img src="/files/v5LgpJoYr5PaQGjNXSHx" alt=""><figcaption></figcaption></figure>

If we want to add the possibility to log Events in the Model, we’ll have to include a section in “definitions” where we define the object “event” and its properties.

{% code title="nested in Root" %}

```json
"definitions": {
  	"event": {
     	"properties": {
        	"attachment": {
           	    "format": "file",
           	    "items": {
              	    "type": "object"
           	    },
           	    "type": "array"
        	},
        	"date": {
           	    "format": "date-time",
           	    "type": "string"
        	},
        	"description": {
           	    "format": "textarea",
           	    "type": "string"
        	},
        	"title": {
           	    "type": "string"
        	}
     	},
     	"type": "object"
  	}
}
```

{% endcode %}

### Mutations

**Mutations** is a Datome-specific keyword used to define a set of operations that modify the Asset’s Properties (i.e. an “update”) or State (i.e. a “transition”) or log a new Event. A Mutation also sets the privileges required to perform such changes. Declaring **mutations** on a Model is **optional** but, without a mutation, no change can be applied to an Asset after its creation. Setting the “mutations” within the Model ensures that only the defined updates, transitions or event logs can be actioned on a certain Asset by specific users. Nesting elements of Mutations are as follows:

* Level 1: mutation name (e.g. “send\_to\_confirmed”)
* Level 2: changes
  * target: a URI pointing to a certain transition in the state, update of properties or event.
  * type: equal to “transition” or “event” for such cases. It is “static” (i.e. set by the platform) or “dynamic” (i.e. set by the user) in case a change of a property
  * required: a boolean value in case it’s a dynamic change in a property
  * value: the value set by the platform in case it’s a static change in a property
* Level 2: authorized\_groups: sets which group can trigger the defined changes
* Level 2: external\_mutations: triggers a change to an Asset belonging to a different model (for details see [here](#external-mutation)).

Mutations are defined as a JSON object with the following structure:

{% code title="nested in Root" %}

```jsx
"mutations": {
        "add_event": {
            "authorized_groups": [
                "/root"
            ],
            "changes": [
              {
                 "target": "#/definitions/event",
                 "type": "event"
              }
            ]
        },
        "send_to_confirmed": {
            "changes": [
                {
                    "type": "transition",
                    "target": "#/states/transitions/send_to_confirmed"
                },
                {
                    "type": "dynamic", 
                    "required": true,
                    "target": "#/properties/id_technician"
                },
                {
                    "type": "dynamic",
                    "required": false,
                    "target": "#/properties/id_employee"
                },
                {
                    "type": "static",
                    "value": true,
                    "target": "#/properties/available"
                }
            ],
            "authorized_groups": [
		          "/root/group/…/admin",
		          "/root/group2/…/controller"
	          ],
            "external_mutations": [
                {
                  "model": "garment",
                  "target": "#/mutations/send_to_available"
                }
            ]
        }
}
```

{% endcode %}

<table><thead><tr><th width="194.33333333333331">Fields</th><th width="121">Data Type</th><th>Description</th></tr></thead><tbody><tr><td>custom name</td><td>Object</td><td>A field that defines a name to identify a mutation. This field is nested under the “mutation” keyword.</td></tr><tr><td>changes</td><td>Array</td><td><p>List of operations applied by the mutation. This field is mandatory and must contain at least one operation. This field has four possible values:<br><br>1. <strong>static</strong>: the “target” is always a property of the model. The new value is prefixed and defined within the definition of the StaticChange. Therefore, each time the mutation is executed, that specific property will always be updated with the same value.<br><br>2. <strong>dynamic</strong>: the “target” is always a property of the model. The new value is passed in the body of the API request, hence is defined by the authorized user who is calling the mutation. It contains a label “required” of type boolean. If set to true, the new value of the field must be expressed in the API request. Otherwise, it could be omitted (it answers the question, “Is there the necessity to check that in the body of the call to the Datome API there is a field (the target) valorized?”).<br><br>3. <strong>transition</strong>: the “type” used to change the state of a model. The “target” is always a state, identified by URI, defined within the "transitions" block.<br><br>4. <strong>events</strong>: the “target” is always a JSON object defined in a “definitions” block (JSON schema) inside the Model. Its behavior is equal to a DynamicChange, so the fields of the object needed to be updated have to be specified in the body of the API request.</p><p><br><br><br><br>Dynamic mutations and Events need the “params” key in the API requests payload to give the required values.</p></td></tr><tr><td>authorized_groups</td><td>Array</td><td>A field that contains the privileges needed to apply the defined mutation.</td></tr><tr><td>external_mutations</td><td>Array</td><td>An optional Datome-specific keyword that lets the user run a mutation that affects an Asset belonging to a different model. Whenever an external mutation is performed, the "authorized_groups" clause will be checked both on the current mutation (where the external is defined) and the one to which the external is linked.</td></tr></tbody></table>

To implement a mutation, it is necessary to contact the correct endpoint with the required input parameters via the URL and, if necessary, within the body of the API request. See the code example below:

```jsx
curl --location --request POST 'https://[your_organization].datome.io/api/models/fabric/silklot00456/mutations/send_to_confirmed//' \
--header 'Authorization: Bearer ....' \
--header 'Content-Type: application/json' \
--data-raw '{
    "params": {
       "id_technician": 987,
       "id_employee": 14005
    }
}'
```

A mutation can potentially be implemented an infinite number of times. However, mutations that involve the execution of a state "transition" may fail if re-executed because the model's "required\_state" has been altered.

### External Mutations

A Model B mutation may be activated by an **external mutation** performed within a Model A mutation. An External mutation shall tell:

* via the keyword **model**, the external Model it refers to;
* via the keyword **target**, the URI of the external mutation to trigger;

```json
"external_mutations": [
                {
                  "model": "engine",
                  "target": "#/mutations/send_to_unavailable"
                }
]
```

For example, if in Model Car we add an external mutation that triggers the mutation **send\_to\_unavailable** of Model Engine, we’ll set the following.

{% code title="Parent model "Engine"" %}

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://mangrovia.solutions/engine.json",
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "notes": {
      "type": "string"
      }
  },
  "mutations": {
    "send_to_unavailable": {
      "changes": [
        {
          "type": "transition",
          "target": "#/states/transitions/send_to_unavailable"
        },
        {
          "type": "dynamic",
          "target": "#/properties/notes",
          "required": false
        }
      ]
    }
  },
  "states": {
    ...
  }
}
```

{% endcode %}

{% code title="Child model "Car"" %}

```json
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "$id": "http://mangrovia.solutions/car.json",
    "type": "object",
    "additionalProperties": false,
    "properties": {
        ...
    },
    "mutations": {
        "set_relation": {
            "changes": [
                ...
            ],
            "external_mutations": [
                {
                    "model": "engine",
                    "target": "#/mutations/send_to_unavailable"
                }
            ]
        }
    },
    "states": ...
}
```

{% endcode %}

Given that the mutation **send\_to\_unavailable** in Model Engine requires, among other changes, the user to input a value for a property named **notes**, when we call the endpoint to trigger a mutation in Car that contains an external mutation to Engine, we will also need to provide a value for **notes**. This will be done within keyword **params** as follows:

```json
"external_mutations": {
        "engine": {
            "send_to_unavailable": {
                "engine001": {
                     "params": {
                         "notes": "invalid product"
                     }
                }
            }
        }
}
```

External Mutations can be nested one inside another producing what we call a Cascade Mutation.&#x20;

A cascade mutation is a sequence of external mutations set in different models, triggered subsequently to create a chain of events. Each external mutation triggers the next in line, forming a sequence that propagates changes across multiple models. Ensure that each model involved is configured to handle the external mutations and is set subsequently to maintain the desired sequence of mutations in your system.

The following is an example of a Cascade Mutation in a JSON object:

```jsx
curl --request POST 'https://[your_organization].datome.io/api/models/fabric/{{asset_id}}/mutations/send_to_confirm/' \
--header 'Authorization: Bearer ....' \
--header 'Content-Type: application/json' \
--data-raw '{
    "params": {
      ...
    },
    "external_mutations": {
      "{{target_model_name}}": {
        "{{target_mutation_name}}": {
          "{{target_asset_id}}": {
            "params": {
              ...
            },
            "external_mutations": {
              ...
            } 
          }
        }
      }
    }
}'
```

### Relations

A **relation** keyword is nested inside a property to tell that such a property is dedicated to storing the identifier of another Asset. For example, one of the properties of a Garment can be dedicated to storing the identifier of the fabric it was made of.

Suppose the Fabric Model was built with an identifier (i.e. a unique value identifying each Asset Fabric). In that case, the relevant property of the Garment will show the identifier of the related Fabric. If Fabric doesn’t have an identifier, the UUID of the fabric will be stored under the relevant property.

<table><thead><tr><th width="144">Asset</th><th width="121">Property 1</th><th width="131">Property 2</th><th>Property 3</th></tr></thead><tbody><tr><td>Garment 1</td><td>...</td><td>...</td><td>Fabric A identifier</td></tr><tr><td>Garment 2</td><td>...</td><td>...</td><td>Fabric B identifier</td></tr></tbody></table>

Relations are used to define ownership, provenance, composition etc. They can bring controls and validations to your processes.

The example above shows a one-to-one relation, but we can also have a one-to-many scenario like the following example (a Garment made out of two fabrics).

<table><thead><tr><th width="139">Asset</th><th width="129">Property 1</th><th width="132">Property 2</th><th>Property 3</th></tr></thead><tbody><tr><td>Garment 3</td><td>...</td><td>...</td><td>Fabric A identifier, Fabric B identifier</td></tr></tbody></table>

To specify a one-to-many relation, it is mandatory to declare a list (array) of **type** and the Model of the Assets to link. The following is an example of Models relation code:

```jsx
one-to-one    
    "{{relation_name}}": {
      "relation": {
        "model": "{{model_name}}"
      },
      "type": "string",
      "description": "Relation to a {{model_name}} model previously created"
    }
one-to-many    
    "{{relation_name}}": {
	      "type": "array",
	      "items": {
	        "type": "string"
	      }
       "relation": {
           "model": "{{model_name}}"
       },
}
```

| Fields         | Data Type | Description                                                                                                                                                                                                    |
| -------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| model          | String    | The label of the relation to the Model.                                                                                                                                                                        |
| description    | String    | The explanation of the model’s link.                                                                                                                                                                           |
| relation       | String    | A Datome-specific keyword used inside the “properties” block to declare the type of relation and the models involved.                                                                                          |
| relation\_name | String    | The name of the model’s relations.                                                                                                                                                                             |
| type           | String    | The field type that receives the relation (relation\_name) must be consistent with the type of the model’s ID (numbers or string) to which it refers. The type field can be specified with numbers or strings. |

### Constraints

When used with a relation, the keyword **constraint** sets a checking rule so that a relation is only set if a condition of the related asset is met. Based on the statement, a possible use case could be **Write Fabric A identifier in Property 3 of Garment 1 only if Property 5 of Fabric A equals 1.**

```jsx
"{{relation_name}}": {
    "relation": {
    "model": "{{model_name}}",
 "constraints": [
      {
        "target": "#/properties/{{property_name}}",
        "op": "eq",
        "value": "{{value}}"
      }
    ]
  },
  "type": "string",
  "description": "Relation to a {{model_name}} Asset previously created"
}
```

In the example above **target** sets the URI of the property to check, **op** sets **equal** as the operation, and **value** is the value to match.

The **target** can also be a state. In such a case, the URI will be **#/states/{{target\_state}}**. In the case of multiple constraints, all of them have to be satisfied.

### Dynamic properties

Dynamic properties offer a powerful way to dynamically calculate a property based on the values of other properties in related models. There are two main scenarios to consider: `trigger properties` and `computed properties`.

#### Trigger Properties

In this case, the "Stock" model has a computed property, "inStockQuantity," which is dynamically calculated based on the "Order" and "Restock" models. In the "Stock" model we define how each related model will affect the dynamic property. Possible operations include "add" for addition. "sub" for subtraction and "count".

Please note that the initial value of the triggered property will be set manually at the creation of the asset.

```json
// Model: Stock
{
  ...
  "properties": {
    "inStockQuantity": {
      "type": "number",
      "minimum": 0,
      "operations": [
        {
          "model": "order",
          "operation": "sub"
        },
        {
          "model": "restock",
          "operation": "add"
        }
      ]
    }
  }
  ...
}
```

The related models ("order" and "restock") define the property that will affect the "inStockQuantity" property through the "operation\_triggers" configuration. Here the relation between the models will also be defined.

```json
// Models: Order and Restock

{
  ...
  "properties": {
    "sold_quantity": {
      "type": "number",
      //here we declare the Model and the property that this Model will affect
      "operation_triggers": [
        {
          "target_property": "#/properties/inStockQuantity",
          "target_relation": "#/properties/belongs_to_stock"
        }
      ]
    }, 
    //here we define the relation
    "belongs_to_instock": {
      "type": "string",
      "relation": {
        "model": "stock"
      }
    }
  }
  ...
}
```

In this scenario, changes to "order" and "restock" models automatically trigger updates to the "inStockQuantity" property in the "Stock" model.

#### Computed Properties

In the `computed properties` scenario, the "pallet" model has a property, "pallet\_weight," which is dynamically calculated by summing the "weight" property of related "product" models.

```json
// Model: Pallet
{
  ...
  "properties": {
    "pallet_weight": {
      "type": "number",
      "computed": {
        "operands": [
          {
            "target_relation": "#/properties/contains_product",
            "target_property": "#/properties/weight"
          }
        ],
        "op": "add"
      }
    },
    "contains_product": {
      "type": "string",
      "relation": {
        "model": "product"
      }
    }
  }
  ...
}
```

In this case, the "pallet\_weight" property is calculated based on the sum of the "weight" property of related "product" models. The operation performed is "add". Possible operations include "add"  and "count".

```json
// Model: Product
{
  ...
  "properties": {
    "peso": {
      "type": "number"
    }
  }
  ...
}
```

The "product" model merely needs to declare the "weight" property, which is used in the computation of the "pallet\_weight" property in the "Pallet" model.

In summary, computed properties provide a flexible way to automate calculations based on related model properties, streamlining processes and reducing manual intervention.&#x20;

#### External Properties

`External properties` allow to automatically record user data when they create an asset.&#x20;

By implementing an external property, you can save time and effort by avoiding the need to manually enter your information each time you make a delivery.&#x20;

This not only streamlines the process but also ensures that the contact details are easily accessible without having to search for them in the carrier's information.

For instance, if you're a carrier delivering goods to a warehouse, you might want to save your contact information so that it's readily available for future deliveries.

In this example, the model "order" will have a property named "carrier mail" defined as follows:

```json
// Model: Order

{
...
	"properties": {
		"carrier_mail": {  
			"type": "string",  
			"from_source": {  
				"uri": "datome://users/me/", 
				"target": "email"
			}  
		}
	}
...
}

```

where:

`"uri": "datome://users/me/"` refers to the user who is creating or updating the asset

and

`"target": "email"` defines which field we want to retrieve the value from.


# Permissions

The "Permissions" section in Datome serves as a tool designed to provide precise control over user access to models and their assets. Whether you hold an admin or model admin role, this section equips you to establish Access Control Lists (ACLs), shaping interactions with your data.

To set a new rule:

1. Navigate to the "Permissions" section on the sidebar.
2. Click on "Add new rule".
3. Fill in the Rule details:
   * **Rule Name:** Assign a name to the rule.
   * **Models:** Select the target model for the rule.
   * **Groups:** Specify the groups affected by the rule. Note that each selection will affect the selected group and all its subgroups.
4. Select the action that the rule will enforce (accept/deny) by setting yes/no under the section "View".
5. Set the conditions that determine when the Visibility Rule should be applied. Conditions are based on asset properties or states. Here's how to define conditions:
   * **Add Condition:** Click on the "Add Condition" button fro the list of Actions.
   * **States:** Select the states required for the rule.
   * **Property:** Click on "Add new property" and choose the property of the asset you want to set a condition on (e.g. quantity).
   * **Operator:** Select a logical operator for the condition (e.g., equals, not equals).
   * **Value:** Specify the value that the property should match for the condition to be met.
6. Click on "Save".

All rules within Datome operate under the logical "OR" condition, meaning that if any of the defined conditions are met, the rule will be applied.

All conditions added within a Visibility Rule are defined with the logical "AND" operator. This ensures that all specified conditions must be met simultaneously for the rule to take effect.


# Model Example


# Model Example

Please see the sample below for a better understanding of the fabric lot and garment definitions.

The body of the POST request contains the Model:

```jsx
curl --location --request POST 
'https://[your_organization].datome.io/api/models/fabric/' \
--header 'Authorization: Bearer 74a6c88d-62fe-4c13-8b40-c21fabbae819' \
--header 'Content-Type: application/json' \
--data '{
    "$schema": "https://json-schema.org/draft-07/schema",
    "$id": "https://mangrovia.solutions/generic.json",
    "type": "object",
    "title": "fabric",
    "properties": {
        "unique_name": {
            "type": "string"
        },
        "id_technician": {
            "type": "number"
        },
        "id_employee": {
            "type": "number"
        },
        "available": {
            "type": "boolean"
        },
        "notes": {
            "type": "string"
        }
    },
    "required": [
	    "unique_name",
	    "id_technician"
    ],
    "identifier": "#/properties/unique_name",
    "additionalProperties": false,
    "mutations": {
        "send_to_processing": { 
            "changes": [
                {
                    "type": "transition",
                    "target": "#/states/transitions/send_to_processing"
                }
            ],
            "authorized_groups": [
        	    "/root/group/…/admin"
	        ]
        },
        
	"send_to_confirmed": {
            "changes": [
                {
                    "type": "transition",
                    "target": "#/states/transitions/send_to_confirmed"
                },
                {
                    "type": "dynamic", 
                    "required": true,
                    "target": "#/properties/id_technician"
                },
                {
                    "type": "dynamic",
                    "required": false,
                    "target": "#/properties/id_employee"
                },
                {
                    "type": "static",
                    "value": true,
                    "target": "#/properties/available"
                }
            ],
            "authorized_groups": [
		        "/root/group/…/admin",
		        "/root/group2/…/controller"
	        ],
            "external_mutations": [
                {
                  "model": "garment",
                  "target": "#/mutations/send_to_available"
                }
            ]
        },
	"send_to_recalled": {
            "changes": [
                {
                    "target": "#/states/transitions/send_to_recalled",
                    "type": "transition"
                },
                {
                    "target": "#/properties/notes",
                    "type": "dynamic",
                    "required": true
                },
                {
                    "type": "static",
                    "value": true,
                    "target": "#/properties/available"
                }
            ]
        }
    },
    "states": {
        "default_state": "open",
        "transitions": {
            "send_to_processing": {
                "required_state": "open",
                "target_state": "processing"
            },
            "send_to_confirmed": {
                "required_state": "processing",
                "target_state": "confirmed"
            },
	        "send_to_recalled": {
                "required_state": "confirmed",
                "target_state": "recalled"
            }
        }
    },
    "ui:order": [
        "unique_name",
        "available",
        "id_employee",
        "id_technician"
    ]
}
```

The same approach can be applied for the Model garment which has a **one-to-one relation** with the **fabric** Model that has been specified in the **properties** block using the **relation** keyword.

```jsx
{
    "$id": "https://mangrovia.solutions/garment.json",
    "$schema": "https://json-schema.org/draft-07/schema",
    "title": "garment",
    "description": "Garment Model describes the manufacturing process of a garment.",
    "type": "object",
    "properties": {
        "unique_name": {
           	"type": "string"
        },
   	    "serial_number": {
		    "type": "string"
    	},
    	"garment_type": {
      		"type": "string"
    	},
    	"size": {
      		"type": "string"
    	},
    	"available": {
        	"type": "boolean"
    	},
    	"fabric_relationship": {
		    "relation": {
	    	    "model": "fabric"
            },
            "type": "string",
            "description": "Relation to a fabric model previously created" 
    	}
    },
    "required": [
	    "unique_name",
	    "serial_number",
	    "garment_type",
	    "size",
	    "fabric_relationship"
    ],
    "additionalProperties": false,
    "identifier": "#/properties/serial_number",
    "label": "#/properties/garment_type",
    "states": {
        "default_state": "created",
        "transitions": {
            "send_to_available": {
                "required_state": "created",
                "target_state": "available"
            },
	        "send_to_recalled": {
                "required_state": "available",
                "target_state": "recalled"
            }
        }
    },
    "mutations": {
        "send_to_available": { 
            "changes": [
                {
                    "type": "transition",
                    "target": "#/states/transitions/send_to_available"
                },
                {
                    "type": "static",
                    "value": true,
                    "target": "#/properties/available"
                }
            ],
            "authorized_groups": [
        	     "/root/group2/…/controller"
	        ]
        },
        "send_to_recalled": {
            "changes": [
                {
                    "target": "#/states/transitions/send_to_recalled",
                    "type": "transition"
                }
            ],
            "external_mutations": [
                {
                    "model": "fabric",
                    "target": "#/mutations/send_to_recalled"
                }
            ]
        }
    }
}
```


# Model Analysis

Let’s analyze the *fabric* Model. It is composed of:

* 5 **properties**: *unique\_name*, *id\_technician*, *id\_employee*, *available*, *notes*.
* 3 **mutations**: *send\_to\_processing*, *send\_to\_confirmed*, *send\_to\_recalled*.
* 4 **states**: *open(default)*, *processing*, *confirmed*, *recalled*.

The required properties are ***id\_technician*** and ***unique\_name***.

The mutation **send\_to\_processing** contains only one transition change to shift the model from the **open** state to the **processing** state. This mutation can be executed only by a user who is a member of the **admin** group.

The mutation **send\_to\_confirmed** contains a collection of 5 changes:

1. **transition** type: changes the model state from processing to confirmed.
2. **dynamic** type: the id\_technician value will be updated with the one the user writes in the API request. The field **must** be valued in the request's body as it is marked as "required: 'true'".
3. **dynamic** type: the id\_employee value will be updated with the one the user writes in the API request. The field **may** be valued in the request as it is marked as "required: 'false'" (i.e. optional field).
4. **static** type: the value of the field available will be updated automatically by the system with the predetermined value true.
5. one **external mutation** invokes the send\_to\_available mutation defined in the garment Model. This implies that a model outside the fabric Model, the model garment, will also change due to the send\_to\_confirmed mutation.

\ <br>

> **Note**: The users authorized to call this mutation are the **admin** or **controller** group members.

\ <br>

The mutation **send\_to\_recalled** contains a collection of 3 changes:

1. **transition** type: changes the model state from confirmed to recalled.
2. **dynamic** type: the value of the notes will be updated with the one written by the user in the API request. The field must be valued in the request's body as it is marked as "required: 'true'".
3. **static** type: the value of the field *available* will be updated automatically by the system with the predetermined value *true*.


# Swagger

A generic swagger is available [here](https://trial.datome.io/swagger).&#x20;


# Examples of API requests

A generic swagger is available [here](https://trial.datome.io/swagger).&#x20;

1. To create a model, a POST request containing the model's required attributes is sent to the appropriate endpoint:

```jsx
curl --location --request POST 
'https://[your_organization].datome.io/api/models/fabric/' \
--header 'Authorization: Bearer 74a6c88d-62fe-4c13-8b40-c21fabbae819' \
--header 'Content-Type: application/json' \
--data '{
    "unique_name": "silklot00456",
    "id_technician": 965,
    "id_employee": 15264,
    "available": false
}'
```

2. After creating the model ***silklot00456***, the new Garment can be directly linked to it during the creation process:

```jsx
curl --location --request POST 
'https://[your_organization].datome.io/api/models/garment/' \
--header 'Authorization: Bearer 74a6c88d-62fe-4c13-8b40-c21fabbae819' \
--header 'Content-Type: application/json' \
--data '{
    "serial_number": "12345",
    "garment_type": "shirt",
    "size": "M",
    "fabric_relationship": "silklot00456",
    "available": false
}'
```

3. To call the mutation ***send\_to\_confirmed***, a POST request is sent to the correct endpoint containing all the parameters defined in the Model:

```jsx
curl --location --request POST 
'https://[your_organization].datome.io/api/models/fabric/silklot00456/mutations/send_to_confirmed' \
--header 'Authorization: Bearer 74a6c88d-62fe-4c13-8b40-c21fabbae819' \
--header 'Content-Type: application/json' \
--data '{
    "id_technician": 987,
    "id_amployee": 14005
}'
```

4. In this final API request example, the request body contains the required input parameter to call the second mutation ***send\_to\_recalled*** defined in the ***fabric*** Model, which in this case, updates the notes field of the ***silklot00456*** model.

```jsx
curl --location --request POST 
'https://[your_organization].datome.io/api/models/garment/12345/mutations/send_to_recalled' \
--header 'Authorization: Bearer 74a6c88d-62fe-4c13-8b40-c21fabbae819' \
--header 'Content-Type: application/json' \
--data '{
    "params": {},
    "external_mutations": {
        "fabric": {
            "send_to_recalled": {
                "silklot00456": {
                     "params": {
                         "notes": "invalid product"
                     }
                }
            }
        }
    }
}'
```

> **Note**: The values for the **send\_to\_recalled** mutation of the Model Garment should be listed in the first **params** field. In the case given above, it can be blank. The values needed for the **send\_to\_recalled** mutation of the Model Fabric are listed in the **params** section that comes after. In the case shown above, it gives a value for **notes**.


# Datome Specific Keywords

Datome enhances the JSON-schema syntax with a custom set of keywords listed below:

<table><thead><tr><th width="254">Datome-Specific Keywords</th><th>Description</th></tr></thead><tbody><tr><td>authorized_groups</td><td>The list of URIs designating the roles or groups whose permissions must be validated before an action can be executed. If declared at the first level, it sets the user that can create an Asset. If set within a mutation, it sets the user to apply it.</td></tr><tr><td>changes</td><td>The mandatory keyword if a mutation block is declared. It must contain at least one type of change. The possible types are static, dynamic, transition, and event.</td></tr><tr><td>constraints</td><td><p>It’s an optional keyword that defines a list of restrictions for a relation. The keyword target is required. For the moment, the only possible constraint is Equal, expressed using the JSON-schema keywords {“ op: “eq”} and value.<br>Example:<br></p><pre><code>constraints {
 "target": "#/properties/{{property}}",
 "op": "eq",
 "value": "{{value}}"
}
</code></pre></td></tr><tr><td>external_mutations</td><td>It’s a mandatory keyword that defines the list of possible actions that can affect an Asset belonging to a different Model from the one that is calling the external_mutation. The keywords target and model are mandatory. It has to be declared inside a mutation block.</td></tr><tr><td>identifier</td><td>It’s an optional keyword that sets a unique identifier for the Asset to be used instead of the UUID produced by the platform. The value is a URI pointing to one of the properties (i.e. “unique_name” in the example above). When a new Asset is created, the platform checks that the identifier was not previously used.</td></tr><tr><td>properties</td><td>A list of the Model’s characteristics.</td></tr><tr><td>label</td><td>It’s an optional field that serves as a non-unique identifier for the Asset and is used solely in the user interface without any associated logic. The value consists of a URI that points to one of the properties.</td></tr><tr><td>model</td><td>When declared, specifies the Model name on which the operation has to be performed.</td></tr><tr><td>mutation</td><td>It’s an optional keyword that defines the list of possible actions that can affect the Asset. If declared, it must contain the keyword changes. The nested keywords authorized_groups and external_mutation are optional.</td></tr><tr><td>relation</td><td>It’s a mandatory keyword that defines a one-to-one or one-to-many relation between two Models. The keyword constraints are optional.</td></tr><tr><td>search</td><td>It’s an optional keyword used for listing the values addressable in the Model search functions.</td></tr><tr><td>states</td><td>It’s a mandatory keyword that defines the list of states of an Asset. Each Model definition must contain at least one default_state, i.e. the state that will be assigned to an Asset at its creation. It represents the initial state of the Finite State Machine. Every other state must be defined using the “transition” keyword.</td></tr><tr><td>target</td><td>Specifies the URI of the properties, states, or event object to be used to satisfy the action requirement when declared.</td></tr><tr><td>transition</td><td>Defines the list of states that follow the default_state. The keywords “required_state”, and “target_state” are mandatory.</td></tr><tr><td>ui:order</td><td>An optional keyword. Sets the order in which the Model properties are displayed in the UI.</td></tr></tbody></table>

[<br>](https://doc.datome.io/Examples%20of%20API%20requests)


