REST API reference

Overview

This guide provides users with a comprehensive set of API (Application Programming Interface) to interact with the Zementis microservice using REST (Representational State Transfer) over HTTP (Hypertext Transfer Protocol). The Zementis microservice API allows users to perform operations on models and custom resources, and process data by issuing a simple request using any HTTP client such as a web browser.

URI

A full path to the Zementis microservice API resource consists of a base path and a resource path.

The base path URI (Uniform Resource Identifier) for the Zementis microservice API is http://domain:port/service/zementis, where http or https is the protocol name, domain is the internet domain or network address, port is a non-negative integer representing the port number, and service/zementis represents the application context path. The base path is static and does not change between requests; it merely identifies the server with an application on the network.

Following the base path is the resource path. It may contain path or query parameters depending on the type of the request and available resources on the server. For example, a resource path /model/Iris_NN/source?annotated=true contains static path definitions such as model or source, path parameter Iris_NN for a dynamically allocated resource, and a query parameter annotated=true.

In the following examples, http://domain:port is represented as {{ url }}.

Request

The HTTP request is a combination of a simple URI, HTTP verb GET, POST, PUT, or DELETE, request parameters, which can be in the form of a path variable, query, body, or header parameters, and message body (content).

The path variable is a variable part of otherwise static URI that denotes a set of possible resource names on the server and is denoted with curly braces. For example, /model/{model_name}/source resource path specifies the PMML file for an arbitrary model denoted as {model_name}. Thus, the request path for the PMML file of model Iris_NN should be constructed as /model/Iris_NN/source.

Query parameters are appended to the URI with a question mark followed by a list of key/value pairs. A query variable annotated with the value true in the /model/Iris_NN?annotated=true resource path specifies that the returned PMML file should contain annotations as placed by Zementis Server, in case of errors or warnings.

Header parameters are HTTP message metadata in the form of key/value pairs containing information about the message such as content type, message encoding type, authorization, etc.

Body parameters appear only in POST or PUT requests and need to be encoded by the HTTP client.

In the following examples, {{ auth }} represents the base64-encoded tenant/username:password or username:password sent as Basic Authorization headers with HTTP requests.

Response

The HTTP response message is composed of a message header and a message body. All Zementis microservice response content types implement standard UTF-8 character set encoding.

The header contains response status code and header fields represented as list of key/value pairs, i.e. Content-Type:application/json. Every response from Zementis microservice contains a Content-Type header entry with one of following internet media types (aka MIME) as value.

Errors

In error cases, standard HTTP response codes are returned. The response body can contain more information about the error, see the error media type definition below.

The error interpretations are:

Code Name Description
400 Bad Request Invalid PMML or resource file was provided for uploading.
401 Unauthorized Authentication has failed, or credentials were required but not provided.
404 Not Found Model or resource was not found.
409 Conflict Model or resource already exists.
500 Internal Server Error An internal error has occurred and the request could not be processed.

Models

Operations on AI/Machine Learning models.

GET - List Available Models

{{url}}/service/zementis/models

Retrieves the model names of all the available PMML models. Use these model names as identifiers for all operations requiring the {model_name} path variable.

HEADERS
Authorization {{auth}}

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/models" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "models": [
     "Iris_CT",
     "Iris_ME_Classification",
     "Iris_NN"
  ]
}

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/models"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

GET - Get Model Information

{{url}}/service/zementis/model/{{model_name}}

Get model name, description, and information about input, output, or derived fields.

HEADERS
Authorization {{auth}}
PARAMS
model_name (string) required path variable for existing model name

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/model/Iris_ME_Classification" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "modelName": "Iris_ME_Classification",
  "description": "Model Ensemble (Decision Tree, Neural Network and Multinomial Logistic Regression) using the Iris dataset.",
  "creationDate": "Sep 29, 2011",
  "isActive": true,
  "inputFields": [
    {
      "usage": "ACTIVE",
      "name": "petal_length",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "petal_width",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "sepal_length",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "sepal_width",
      "type": "DOUBLE"
    }
  ],
  "outputFields": [
    {
      "usage": "OUTPUT",
      "name": "class",
      "type": "STRING"
    },
    {
      "usage": "OUTPUT",
      "name": "Probability_setosa",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Probability_versicolor",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Probability_virginica",
      "type": "DOUBLE"
    }
  ]
}

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/model/Iris_ME_Classification"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request GET "{{url}}/service/zementis/model/dummy" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Model 'dummy' not found."
  ]
}

GET - Get Model Source

{{url}}/service/zementis/model/{{model_name}}/source

Get annotated or original PMML file. Annotated source may contain warning or error messages embedded in XML comments that are useful for verifying that the PMML code is correct.

HEADERS
Authorization {{auth}}
PARAMS
model_name (string) required path variable for existing model name
annotated (boolean) optional query parameter used to request the annotated version of the PMML file

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/model/Iris_CT/source?annotated=true" --header "Authorization: {{auth}}"

Example Response

200 - OK 

<?xml version="1.0" encoding="UTF-8"?>
<!--(Comment generated by ADAPA) PMML processed by ADAPA (Version : 4.4)--><PMML version="4.0" xsi:schemaLocation="http://www.dmg.org/PMML-4_0 http://www.dmg.org/v4-0/pmml-4-0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.dmg.org/PMML-4_0">
  <Header copyright="Copyright (c) 2008-2014 Zementis, Inc. (www.zementis.com)" description="Classification Tree using the Iris dataset">
    <Timestamp>Jun 15, 2008</Timestamp>
  </Header>
  <DataDictionary numberOfFields="5">
    <DataField dataType="double" name="sepal_length" optype="continuous"/>
    <DataField dataType="double" name="sepal_width" optype="continuous"/>
    <DataField dataType="double" name="petal_length" optype="continuous"/>
    <DataField dataType="double" name="petal_width" optype="continuous"/>
    <DataField dataType="string" name="target_class" optype="categorical">
      <Value property="valid" value="Iris-setosa"/>
      <Value property="valid" value="Iris-versicolor"/>
      <Value property="valid" value="Iris-virginica"/>
    </DataField>
  </DataDictionary>
  <TreeModel algorithmName="CART" functionName="classification" modelName="Iris_CT">
    <MiningSchema>
      <MiningField name="petal_length" usageType="active" invalidValueTreatment="asMissing"/>
      <MiningField name="petal_width" usageType="active" invalidValueTreatment="asMissing"/>
      <MiningField name="sepal_length" usageType="active" invalidValueTreatment="asMissing"/>
      <MiningField name="sepal_width" usageType="active" invalidValueTreatment="asMissing"/>
      <MiningField name="target_class" usageType="predicted"/>
    </MiningSchema>
    <Output>
      <OutputField dataType="string" feature="predictedValue" name="class" optype="categorical" />
      <OutputField dataType="double" feature="probability" name="Probability_setosa" optype="continuous" value="Iris-setosa"/>
      <OutputField dataType="double" feature="probability" name="Probability_versicolor" optype="continuous" value="Iris-versicolor"/>
      <OutputField dataType="double" feature="probability" name="Probability_virginica" optype="continuous" value="Iris-virginica"/>
    </Output>
    <Node id="0" recordCount="150" score="Iris-setosa">
      <True/>
      <ScoreDistribution recordCount="50" value="Iris-setosa"/>
      <ScoreDistribution recordCount="50" value="Iris-versicolor"/>
      <ScoreDistribution recordCount="50" value="Iris-virginica"/>
      <Node id="1" recordCount="50" score="Iris-setosa">
        <CompoundPredicate booleanOperator="surrogate">
          <CompoundPredicate booleanOperator="and">
            <True/>
            <SimplePredicate field="petal_length" operator="lessOrEqual" value="2.45"/>
          </CompoundPredicate>
          <CompoundPredicate booleanOperator="and">
            <True/>
            <SimplePredicate field="petal_width" operator="lessOrEqual" value="0.8"/>
          </CompoundPredicate>
          <CompoundPredicate booleanOperator="and">
            <True/>
            <SimplePredicate field="sepal_length" operator="lessOrEqual" value="5.45"/>
          </CompoundPredicate>
          <CompoundPredicate booleanOperator="and">
            <SimplePredicate field="sepal_width" operator="greaterThan" value="3.35"/>
            <True/>
          </CompoundPredicate>
          <False/>
        </CompoundPredicate>
        <ScoreDistribution recordCount="50" value="Iris-setosa"/>
        <ScoreDistribution recordCount="0" value="Iris-versicolor"/>
        <ScoreDistribution recordCount="0" value="Iris-virginica"/>
      </Node>
      <Node id="2" recordCount="100" score="Iris-versicolor">
        <CompoundPredicate booleanOperator="surrogate">
          <CompoundPredicate booleanOperator="and">
            <SimplePredicate field="petal_length" operator="greaterThan" value="2.45"/>
            <True/>
          </CompoundPredicate>
          <CompoundPredicate booleanOperator="and">
            <SimplePredicate field="petal_width" operator="greaterThan" value="0.8"/>
            <True/>
          </CompoundPredicate>
          <CompoundPredicate booleanOperator="and">
            <SimplePredicate field="sepal_length" operator="greaterThan" value="5.45"/>
            <True/>
          </CompoundPredicate>
          <CompoundPredicate booleanOperator="and">
            <True/>
            <SimplePredicate field="sepal_width" operator="lessOrEqual" value="3.35"/>
          </CompoundPredicate>
          <True/>
        </CompoundPredicate>
        <ScoreDistribution recordCount="0" value="Iris-setosa"/>
        <ScoreDistribution recordCount="50" value="Iris-versicolor"/>
        <ScoreDistribution recordCount="50" value="Iris-virginica"/>
        <Node id="3" recordCount="54" score="Iris-versicolor">
          <CompoundPredicate booleanOperator="surrogate">
            <CompoundPredicate booleanOperator="and">
              <True/>
              <SimplePredicate field="petal_width" operator="lessOrEqual" value="1.75"/>
            </CompoundPredicate>
            <CompoundPredicate booleanOperator="and">
              <True/>
              <SimplePredicate field="petal_length" operator="lessOrEqual" value="4.75"/>
            </CompoundPredicate>
            <CompoundPredicate booleanOperator="and">
              <True/>
              <SimplePredicate field="sepal_length" operator="lessOrEqual" value="6.15"/>
            </CompoundPredicate>
            <CompoundPredicate booleanOperator="and">
              <True/>
              <SimplePredicate field="sepal_width" operator="lessOrEqual" value="2.95"/>
            </CompoundPredicate>
            <True/>
          </CompoundPredicate>
          <ScoreDistribution recordCount="0" value="Iris-setosa"/>
          <ScoreDistribution recordCount="49" value="Iris-versicolor"/>
          <ScoreDistribution recordCount="5" value="Iris-virginica"/>
          <Node id="5" recordCount="48" score="Iris-versicolor">
            <CompoundPredicate booleanOperator="surrogate">
              <CompoundPredicate booleanOperator="and">
                <True/>
                <SimplePredicate field="petal_length" operator="lessOrEqual" value="4.95"/>
              </CompoundPredicate>
              <CompoundPredicate booleanOperator="and">
                <True/>
                <SimplePredicate field="sepal_length" operator="lessOrEqual" value="7.1"/>
              </CompoundPredicate>
              <True/>
            </CompoundPredicate>
            <ScoreDistribution recordCount="0" value="Iris-setosa"/>
            <ScoreDistribution recordCount="47" value="Iris-versicolor"/>
            <ScoreDistribution recordCount="1" value="Iris-virginica"/>
          </Node>
          <Node id="6" recordCount="6" score="Iris-virginica">
            <CompoundPredicate booleanOperator="surrogate">
              <CompoundPredicate booleanOperator="and">
                <SimplePredicate field="petal_length" operator="greaterThan" value="4.95"/>
                <True/>
              </CompoundPredicate>
              <CompoundPredicate booleanOperator="and">
                <SimplePredicate field="sepal_length" operator="greaterThan" value="7.1"/>
                <True/>
              </CompoundPredicate>
              <False/>
            </CompoundPredicate>
            <ScoreDistribution recordCount="0" value="Iris-setosa"/>
            <ScoreDistribution recordCount="2" value="Iris-versicolor"/>
            <ScoreDistribution recordCount="4" value="Iris-virginica"/>
            <Node id="9" recordCount="3" score="Iris-virginica">
              <CompoundPredicate booleanOperator="surrogate">
                <CompoundPredicate booleanOperator="and">
                  <True/>
                  <SimplePredicate field="petal_width" operator="lessOrEqual" value="1.55"/>
                </CompoundPredicate>
                <CompoundPredicate booleanOperator="and">
                  <True/>
                  <SimplePredicate field="sepal_width" operator="lessOrEqual" value="2.65"/>
                </CompoundPredicate>
                <CompoundPredicate booleanOperator="and">
                  <True/>
                  <SimplePredicate field="sepal_length" operator="lessOrEqual" value="6.5"/>
                </CompoundPredicate>
                <CompoundPredicate booleanOperator="and">
                  <True/>
                  <SimplePredicate field="petal_length" operator="lessOrEqual" value="5.7"/>
                </CompoundPredicate>
                <True/>
              </CompoundPredicate>
              <ScoreDistribution recordCount="0" value="Iris-setosa"/>
              <ScoreDistribution recordCount="0" value="Iris-versicolor"/>
              <ScoreDistribution recordCount="3" value="Iris-virginica"/>
            </Node>
            <Node id="10" recordCount="3" score="Iris-versicolor">
              <CompoundPredicate booleanOperator="surrogate">
                <CompoundPredicate booleanOperator="and">
                  <SimplePredicate field="petal_width" operator="greaterThan" value="1.55"/>
                  <True/>
                </CompoundPredicate>
                <CompoundPredicate booleanOperator="and">
                  <SimplePredicate field="sepal_width" operator="greaterThan" value="2.65"/>
                  <True/>
                </CompoundPredicate>
                <CompoundPredicate booleanOperator="and">
                  <SimplePredicate field="sepal_length" operator="greaterThan" value="6.5"/>
                  <True/>
                </CompoundPredicate>
                <CompoundPredicate booleanOperator="and">
                  <SimplePredicate field="petal_length" operator="greaterThan" value="5.7"/>
                  <True/>
                </CompoundPredicate>
                <False/>
              </CompoundPredicate>
              <ScoreDistribution recordCount="0" value="Iris-setosa"/>
              <ScoreDistribution recordCount="2" value="Iris-versicolor"/>
              <ScoreDistribution recordCount="1" value="Iris-virginica"/>
            </Node>
          </Node>
        </Node>
        <Node id="4" recordCount="46" score="Iris-virginica">
          <CompoundPredicate booleanOperator="surrogate">
            <CompoundPredicate booleanOperator="and">
              <SimplePredicate field="petal_width" operator="greaterThan" value="1.75"/>
              <True/>
            </CompoundPredicate>
            <CompoundPredicate booleanOperator="and">
              <SimplePredicate field="petal_length" operator="greaterThan" value="4.75"/>
              <True/>
            </CompoundPredicate>
            <CompoundPredicate booleanOperator="and">
              <SimplePredicate field="sepal_length" operator="greaterThan" value="6.15"/>
              <True/>
            </CompoundPredicate>
            <CompoundPredicate booleanOperator="and">
              <SimplePredicate field="sepal_width" operator="greaterThan" value="2.95"/>
              <True/>
            </CompoundPredicate>
            <False/>
          </CompoundPredicate>
          <ScoreDistribution recordCount="0" value="Iris-setosa"/>
          <ScoreDistribution recordCount="1" value="Iris-versicolor"/>
          <ScoreDistribution recordCount="45" value="Iris-virginica"/>
          <Node id="7" recordCount="3" score="Iris-virginica">
            <CompoundPredicate booleanOperator="surrogate">
              <CompoundPredicate booleanOperator="and">
                <True/>
                <SimplePredicate field="petal_length" operator="lessOrEqual" value="4.85"/>
              </CompoundPredicate>
              <False/>
            </CompoundPredicate>
            <ScoreDistribution recordCount="0" value="Iris-setosa"/>
            <ScoreDistribution recordCount="1" value="Iris-versicolor"/>
            <ScoreDistribution recordCount="2" value="Iris-virginica"/>
          </Node>
          <Node id="8" recordCount="43" score="Iris-virginica">
            <CompoundPredicate booleanOperator="surrogate">
              <CompoundPredicate booleanOperator="and">
                <SimplePredicate field="petal_length" operator="greaterThan" value="4.85"/>
                <True/>
              </CompoundPredicate>
              <True/>
            </CompoundPredicate>
            <ScoreDistribution recordCount="0" value="Iris-setosa"/>
            <ScoreDistribution recordCount="0" value="Iris-versicolor"/>
            <ScoreDistribution recordCount="43" value="Iris-virginica"/>
          </Node>
        </Node>
      </Node>
    </Node>
  </TreeModel>
</PMML>

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/model/Iris_ME_Classification/source?annotated=true"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request PUT "{{url}}/service/zementis/model/dummy/source" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Model 'dummy' not found."
  ]
}

GET - Get Model Serialized Source

{{url}}/service/zementis/model/{{model_name}}/serialized

Get binary file containing serialized representation of the model.

HEADERS
Authorization {{auth}}
PARAMS
model_name (string) required path variable for existing model name

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/model/Iris_ME_Classification/serialized" --header "Authorization: {{auth}}"

Example Response

200 - OK

Binary file

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/model/Iris_ME_Classification/serialized"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request GET "{{url}}/service/zementis/model/dummy/serialized" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Model 'dummy' not found."
  ]
}

GET - Model Metrics Information

{{url}}/service/zementis/model/{{model_name}}/metrics

Get the memory metrics and prediction metrics of an uploaded model.

HEADERS
Authorization {{auth}}
PARAMS
model_name (string) required path variable for existing model name

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/model/Iris_ME_Classification/metrics" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "modelSize": ".04 MB",
  "usedMemory": "460.845 MB",
  "freeMemory": "2346.49 MB",
  "totalMemory": "2807.375 MB",
  "predictionMetrics": {
    "Iris-versicolor": 156,
    "Iris-virginica": 144,
    "Iris-setosa": 159
  }
}

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/model/Iris_ME_Classification/metrics"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request GET "{{url}}/service/zementis/model/dummy/metrics" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Model 'dummy' not found."
  ]
}

POST - Upload New Model

{{url}}/service/zementis/model

Upload new PMML model. If the PMML file is large, such as Random Forest model, we recommend compressing the file using ZIP/GZIP before uploading. This will reduce the upload time drastically.

Note that the size of the uploaded PMML file/zip must not exceed 500 MB.

HEADERS
Authorization {{auth}}
Content-Type required header parameter with two accepted values: application/octet-stream or multipart/form-data
PARAMS
file required query parameter for PMML file name, if Content-Type is application/octet-stream
or a body parameter for PMML file, if Content-Type is multipart/form-data
applyCleanser (boolean) optional parameter used to automatically perform comprehensive syntactic and semantic checks, correct known issues and convert your PMML file to version 4.4 (default is true)

Example Request

200 - OK

curl --request POST "{{url}}/service/zementis/model?applyCleanser=false" --header "Authorization: {{auth}}" --form "file=@Iris_KM.pmml"

Example Response

200 - OK

<?xml version="1.0" encoding="UTF-8"?>
<!--(Comment generated by ADAPA) There is at least 1 error in this PMML document.
 Detailed information can be found as comments embedded in the appropriate locations within this document.-->
<pmml:PMML version="4.1" xsi:schemaLocation="http://www.dmg.org/PMML-4_1 http://dmg.org/v4-1/pmml-4-1.xsd" xmlns="http://www.dmg.org/PMML-4_1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:pmml="http://www.dmg.org/PMML-4_4">
    <pmml:Header copyright="Copyright (c) 2009-2014 Zementis Inc. (www.zementis.com)" description="K-means Cluster Model using normalized Iris dataset">
        <pmml:Timestamp>Feb 26, 2009</pmml:Timestamp>
    </pmml:Header>
    <pmml:DataDictionary numberOfFields="5">
        <pmml:DataField dataType="double" name="SEPAL_LE" optype="continuous">
            <pmml:Interval closure="closedClosed" leftMargin="0.53" rightMargin="0.99"/>
        </pmml:DataField>
        <pmml:DataField dataType="double" name="SEPAL_WI" optype="continuous">
            <pmml:Interval closure="closedClosed" leftMargin="0.4" rightMargin="0.88"/>
        </pmml:DataField>
        <pmml:DataField dataType="double" name="PETAL_LE" optype="continuous">
            <pmml:Interval closure="closedClosed" leftMargin="0.2" rightMargin="1.38"/>
        </pmml:DataField>
        <pmml:DataField dataType="double" name="PETAL_WI" optype="continuous">
            <pmml:Interval closure="closedClosed" leftMargin="0.03" rightMargin="0.84"/>
        </pmml:DataField>
        <pmml:DataField dataType="string" name="CLASS" optype="categorical">
            <pmml:Value value="Iris-setosa"/>
            <pmml:Value value="Iris-versic"/>
            <pmml:Value value="Iris-virgin"/>
        </pmml:DataField>
    </pmml:DataDictionary>
    <pmml:ClusteringModel functionName="clustering" modelClass="centerBased" modelName="Iris_KM" numberOfClusters="3">
        <pmml:MiningSchema>
            <pmml:MiningField name="SEPAL_LE" invalidValueTreatment="asMissing"/>
            <pmml:MiningField name="SEPAL_WI" invalidValueTreatment="asMissing"/>
            <pmml:MiningField name="PETAL_LE" invalidValueTreatment="asMissing"/>
            <pmml:MiningField name="PETAL_WI" invalidValueTreatment="asMissing"/>
            <pmml:MiningField name="CLASS" usageType="predicted"/>
        </pmml:MiningSchema>
        <pmml:Output>
            <pmml:OutputField dataType="string" feature="predictedValue" name="CLASS" optype="categorical">
                <!--(Comment generated by ADAPA) Error: Field name duplicates existing [MiningField] name-->
    
            </pmml:OutputField>
            <pmml:OutputField dataType="string" feature="clusterId" name="Cluster ID" optype="categorical"/>
            <pmml:OutputField dataType="double" feature="clusterAffinity" name="Cluster Affinity for predicted" optype="continuous"/>
            <pmml:OutputField dataType="double" feature="clusterAffinity" name="Cluster Affinity for setosa" optype="continuous" value="Iris-setosa"/>
            <pmml:OutputField dataType="double" feature="clusterAffinity" name="Cluster Affinity for versic" optype="continuous" value="Iris-versic"/>
            <pmml:OutputField dataType="double" feature="clusterAffinity" name="Cluster Affinity for virgin" optype="continuous" value="Iris-virgin"/>
        </pmml:Output>
        <pmml:ComparisonMeasure kind="distance">
            <pmml:squaredEuclidean/>
        </pmml:ComparisonMeasure>
        <pmml:ClusteringField compareFunction="absDiff" field="SEPAL_LE"/>
        <pmml:ClusteringField compareFunction="absDiff" field="SEPAL_WI"/>
        <pmml:ClusteringField compareFunction="absDiff" field="PETAL_LE"/>
        <pmml:ClusteringField compareFunction="absDiff" field="PETAL_WI"/>
        <pmml:Cluster id="Iris-versic" size="51">
            <pmml:Array n="4" type="real">0.7398039215686276 0.548235294117647
                0.8541176470588238 0.4403921568627449</pmml:Array>
        </pmml:Cluster>
        <pmml:Cluster id="Iris-virgin" size="49">
            <pmml:Array n="4" type="real">0.8291836734693881 0.6016326530612247
                1.1134693877551018 0.6812244897959185</pmml:Array>
        </pmml:Cluster>
        <pmml:Cluster id="Iris-setosa" size="50">
            <pmml:Array n="4" type="real">0.6277999999999999 0.6836000000000001
                0.29280000000000006 0.08239999999999997</pmml:Array>
        </pmml:Cluster>
    </pmml:ClusteringModel>
</pmml:PMML>

Example Request

201 - Created

curl --request POST "{{url}}/service/zementis/model" --header "Authorization: {{auth}}" --form "file=@Iris_KM.pmml"

Example Response

201 - Created

{
  "modelName": "Iris_KM",
  "description": "K-means Cluster Model using normalized Iris dataset",
  "creationDate": "Feb 26, 2009",
  "isActive": true,
  "inputFields": [
    {
      "usage": "ACTIVE",
      "name": "SEPAL_LE",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "SEPAL_WI",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "PETAL_LE",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "PETAL_WI",
      "type": "DOUBLE"
    }
  ],
  "outputFields": [
    {
      "usage": "OUTPUT",
      "name": "predictedValue_CLASS",
      "type": "STRING"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster ID",
      "type": "STRING"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for predicted",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for setosa",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for versic",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for virgin",
      "type": "DOUBLE"
    }
  ]
}

Example Request

400 - Bad Request

curl --request POST "{{url}}/service/zementis/model" --header "Authorization: {{auth}}" --form "file=@Invalid.pmml"

Example Response

400 - Bad Request

{
  "errors": [
    "Invalid XML format."
  ]
}

Example Request

401 - Unauthorized

curl --request POST "{{url}}/service/zementis/model"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

409 - Conflict

curl --request POST "{{url}}/service/zementis/model" --header "Authorization: {{auth}}" --form "file=@Iris_KM.pmml"

Example Response

409 - Conflict

{
  "errors": [
    "A model with the name 'Iris_KM' already exists."
  ]
}

PUT - Activate an Existing Model

{{url}}/service/zementis/model/{{model_name}}/activate

Activates the model with name model_name if it was inactive. Activating an active model has no effect. After activation, the model is immediately available for handling data processing requests. Note that an active model consumes runtime resources, especially Heap.

HEADERS
Authorization {{auth}}
PARAMS
model_name (string) required path variable for existing model name

Example Request

200 - OK

curl --request PUT "{{url}}/service/zementis/model/Iris_KM/activate" --header "Authorization: {{auth}}"

Example Response

200 - OK 

{
  "modelName": "Iris_KM",
  "description": "K-means Cluster Model using normalized Iris dataset",
  "creationDate": "Feb 26, 2009",
  "isActive": true,
  "inputFields": [
    {
      "usage": "ACTIVE",
      "name": "SEPAL_LE",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "SEPAL_WI",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "PETAL_LE",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "PETAL_WI",
      "type": "DOUBLE"
    }
  ],
  "outputFields": [
    {
      "usage": "OUTPUT",
      "name": "predictedValue_CLASS",
      "type": "STRING"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster ID",
      "type": "STRING"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for predicted",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for setosa",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for versic",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for virgin",
      "type": "DOUBLE"
    }
  ]
}

Example Request

401 - Unauthorized

curl --request PUT "{{url}}/service/zementis/model/Iris_KM/activate"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request PUT "{{url}}/service/zementis/model/dummy/activate" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Model 'dummy' not found."
  ]
}

PUT - Deactivate an Existing Model

{{url}}/service/zementis/model/{{model_name}}/deactivate

Deactivates the model with name model_name by making it inactive. After deactivation, the model is still available, but it no longer consumes runtime resources, especially Heap. Deactivating an inactive model has no effect.

HEADERS
Authorization {{auth}}
PARAMS
model_name (string) required path variable for existing model name

Example Request

200 - OK

curl --request PUT "{{url}}/service/zementis/model/Iris_KM/deactivate" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "modelName": "Iris_KM",
  "description": "K-means Cluster Model using normalized Iris dataset",
  "creationDate": "Feb 26, 2009",
  "isActive": false,
  "inputFields": [
    {
      "usage": "ACTIVE",
      "name": "SEPAL_LE",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "SEPAL_WI",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "PETAL_LE",
      "type": "DOUBLE"
    },
    {
      "usage": "ACTIVE",
      "name": "PETAL_WI",
      "type": "DOUBLE"
    }
  ],
  "outputFields": [
    {
      "usage": "OUTPUT",
      "name": "predictedValue_CLASS",
      "type": "STRING"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster ID",
      "type": "STRING"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for predicted",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for setosa",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for versic",
      "type": "DOUBLE"
    },
    {
      "usage": "OUTPUT",
      "name": "Cluster Affinity for virgin",
      "type": "DOUBLE"
    }
  ]
}

Example Request

401 Unauthorized

curl --request PUT "{{url}}/service/zementis/model/Iris_KM/deactivate"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request PUT "{{url}}/service/zementis/model/dummy/deactivate" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Model 'dummy' not found."
  ]
}

DEL - Remove Model

{{url}}/service/zementis/model/{{model_name}}

Remove the specified model and list the remaining models.

HEADERS
Authorization {{auth}}
PARAMS
model_name (string) required path variable for existing model name

Example Request

200 - OK

curl --request DELETE "{{url}}/service/zementis/model/Iris_KM" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "models": [
     "Iris_CT",
     "Iris_ME_Classification",
     "Iris_NN"
  ]
}

Example Request

401 - Unauthorized

curl --request DELETE "{{url}}/service/zementis/model/Iris_KM"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request DELETE "{{url}}/service/zementis/model/dummy" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Model 'dummy' not found."
  ]
}

DEL - Remove All Models

{{url}}/service/zementis/models

Remove all available models and list the remaining models.

HEADERS
Authorization {{auth}}

Example Request

200 OK

curl --request DELETE "{{url}}/service/zementis/models" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "models": []
}

Example Request

401 - Unauthorized

curl --request DELETE "{{url}}/service/zementis/models"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Resources

Operation on resources.

GET - List Available Resources

{{url}}/service/zementis/resources

This operation retrieves information on all available resource files. Use file names as identifiers for all operations requiring a file_name path variable.

HEADERS
Authorization {{auth}}

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/resources" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "resources": [
    {
      "fileName": "custom-functions.jar",
      "resourceType": "Custom Functions",
      "resourceIdentifier": "Function Namespace",
      "resourceNames": [
        "fraud"
      ]
    },
    {
      "fileName": "customerAreaMappingTable.xls",
      "resourceType": "Lookup Tables",
      "resourceIdentifier": "Table Name",
      "resourceNames": [
        "AreaPoints"
      ]
    }
  ]
}

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/resources"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

GET - Get Resource Information

{{url}}/service/zementis/resource/{{file_name}}

Get information on the specified resource file.

HEADERS
Authorization {{auth}}
PARAMS
file_name (string) required path variable for an existing resource file name

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/resource/customerAreaMappingTable.xls" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "fileName": "customerAreaMappingTable.xls",
  "resourceType": "Lookup Tables",
  "resourceIdentifier": "Table Name",
  "resourceNames": [
    "AreaPoints"
  ]
}

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/resource/customerAreaMappingTable.xls"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request GET "{{url}}/service/zementis/resource/dummy" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Resource file 'dummy' not found"
  ]
}

GET - Get Resource File

{{url}}/service/zementis/resource/{{file_name}}/source

Download a resource file.

HEADERS
Authorization {{auth}}
PARAMS
file_name (string) required path variable for an existing resource file name

Example Request

200 OK

curl --request GET "{{url}}/service/zementis/resource/customerAreaMappingTable.xls/source" --header "Authorization: {{auth}}"

Example Response

200 - OK

Resource file

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/resource/customerAreaMappingTable.xls/source"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request GET "{{url}}/service/zementis/resource/dummy/source" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Resource file 'dummy' not found"
  ]
}

POST - Upload New Resource File

{{url}}/service/zementis/resource

Upload a new resource file. The file name in ‘file’ body parameter will be used to identify this resource. Note that the size of the uploaded resource file must not exceed 500 MB.

HEADERS
Authorization {{auth}}
Content-Type required header parameter with two accepted values: application/octet-stream or multipart/form-data
PARAMS
file required query parameter for resource file name, if Content-Type is application/octet-stream,
or a body parameter for resource file, if Content-Type is multipart/form-data

Example Request

201 - Created

curl --request POST "{{url}}/service/zementis/resource" --header "Authorization: {{auth}}" --form "file=@customerAreaMappingTable.xls"

Example Response

201 - Created

{
  "fileName": "customerAreaMappingTable.xls",
  "resourceType": "Lookup Tables",
  "resourceIdentifier": "Table Name",
  "resourceNames": [
    "AreaPoints"
  ]
}

Example Request

400 - Bad Request

curl --request POST "{{url}}/service/zementis/resource" --header "Authorization: {{auth}}" --form "file=@Empty.jar"

Example Response

400 - Bad Request

{
  "errors": [
    "Empty input stream."
  ]
}

Example Request

401 - Unauthorized

curl --request POST "{{url}}/service/zementis/resource" --form "file=@custom-functions.jar"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

409 - Conflict

curl --request POST "{{url}}/service/zementis/resource" --header "Authorization: {{auth}}" --form "file=@customerAreaMappingTable.xls"

Example Response

409 - Conflict

{
  "errors": [
    "A resource file with the name 'customerAreaMappingTable.xls' already exists."
  ]
}

DEL - Remove Resource File

{{url}}/service/zementis/resource/{{file_name}}

Remove the specified resource file and list all remaining resources.

HEADERS
Authorization {{auth}}
PARAMS
file_name (string) required path variable for an existing resource file name

Example Request

200 - OK

curl --request DELETE "{{url}}/service/zementis/resource/customerAreaMappingTable.xls" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "resources": [
    {
      "fileName": "custom-functions.jar",
      "resourceType": "Custom Functions",
      "resourceIdentifier": "Function Namespace",
      "resourceNames": [
        "fraud"
      ]
    }
  ]
}

Example Request

401 - Unauthorized

curl --request DELETE "{{url}}/service/zementis/resource/customerAreaMappingTable.xls"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request DELETE "{{url}}/service/zementis/resource/dummy" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Resource file 'dummy' not found"
  ]
}

DEL - Remove All Resource Files

{{url}}/service/zementis/resources

Remove all available resources and list the remaining resources.

HEADERS
Authorization {{auth}}

Example Request

200 - OK

curl --request DELETE "{{url}}/service/zementis/resources" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "resources": []
}

Example Request

401 - Unauthorized

curl --request DELETE "{{url}}/service/zementis/resources"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Prediction

Operations on applying model to input data.

GET - Apply Model to Single Record

{{url}}/service/zementis/apply/{{model_name}}?record={{record}}

Apply a model to a single JSON input record.

HEADERS
Authorization {{auth}}
PARAMS
model_name (string) required path variable for existing model name
record (string) JSON Record - a map of model input fields and their respective values

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/apply/Iris_NN record=%7B%22petal_length%22:%221.4%22,%22petal_width%22:%220.2%22,%22sepal_length%22:%225.1%22,%22sepal_width%22:%223.5%22%7D" \
  --header "Authorization: {{auth}}"

Example Response

200 - OK

{
  "model": "Iris_ME_Classification",
  "outputs": [
    {
      "Probability_setosa": 1,
      "Probability_versicolor": 0,
      "Probability_virginica": 0,
      "class": "Iris-setosa"
    }
  ]
}

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/apply/Iris_NN record=%7B%22petal_length%22:%221.4%22,%22petal_width%22:%220.2%22,%22sepal_length%22:%225.1%22,%22sepal_width%22:%223.5%22%7D"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request GET "{{url}}/service/zementis/apply/dummy record=%7B%22petal_length%22:%221.4%22,%22petal_width%22:%220.2%22,%22sepal_length%22:%225.1%22,%22sepal_width%22:%223.5%22%7D" \
  --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Model 'dummy' not found."
  ]
}

Example Request

500 - Internal server Error

curl --request GET "{{url}}/service/zementis/apply/Iris_NN record=%7B" --header "Authorization: {{auth}}"

Example Response

500 - Internal server Error

{
  "timestamp": 1554299687990,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "com.fasterxml.jackson.core.io.JsonEOFException",
  "message": "Unexpected end-of-input: expected close marker for Object (start marker at [Source: {; line: 1, column: 1])\n at [Source: {; line: 1, column: 3]",
  "path": "/apply/Iris_ME_Classification"
}

GET - Apply Model to Single Record and Explain Result

{{url}}/service/zementis/apply/{{model_name}}/explain?record={{record}}

Apply a model to a single JSON input record and get the result with details of the performed computation in plain text.

HEADERS
Authorization {{auth}}
PARAMS
model_name (string) required path variable for existing model name
record (string) JSON Record - a map of model input fields and their respective values

Example Request

200 - OK

curl --request GET \
     "{{url}}/service/zementis/apply/Iris_NN/explain record=%7B%22petal_length%22:%221.4%22,%22petal_width%22:%220.2%22,%22sepal_length%22:%225.1%22,%22sepal_width%22:%223.5%22%7D" \  
     --header "Authorization: {{auth}}"

Example Response

200 - OK  

[petal_length] := 1.4 (DOUBLE)
[petal_width] := 0.2 (DOUBLE)
[sepal_length] := 5.1 (DOUBLE)
[sepal_width] := 3.5 (DOUBLE)
 
[MiningSchema]
[petal_length] := 1.4 (DOUBLE)
[petal_width] := 0.2 (DOUBLE)
[sepal_length] := 5.1 (DOUBLE)
[sepal_width] := 3.5 (DOUBLE)
 
 
[ModelEnsemble]
 
Process segment model [1]:
The predicate of segment model [1] evaluates [True]
 
[MiningSchema]
[petal_length] := 1.4 (DOUBLE)
[petal_width] := 0.2 (DOUBLE)
[sepal_length] := 5.1 (DOUBLE)
[sepal_width] := 3.5 (DOUBLE)
 
 
[DecisionTree]
Evaluation of node [0] is [True].
Evaluation of node [1] is [True].
The confidence of the category [Iris-versicolor (STRING)] is [0].
The confidence of the category [Iris-setosa (STRING)] is [1].
The confidence of the category [Iris-virginica (STRING)] is [0].
 
[Output]
The predicted value of segment model [1] is [Iris-setosa (STRING)]
 
 
Process segment model [2]:
The predicate of segment model [2] evaluates [True]
 
[MiningSchema]
[sepal_length] := 5.1 (DOUBLE)
[sepal_width] := 3.5 (DOUBLE)
[petal_length] := 1.4 (DOUBLE)
[petal_width] := 0.2 (DOUBLE)
 
[LocalTransformations]
[derived_sepal_length] := 0.22222222222222213 (DOUBLE)
[derived_sepal_width] := 0.6818181818181818 (DOUBLE)
[derived_petal_length] := 0.07017543859649121 (DOUBLE)
[derived_petal_width] := 0.04166666666666667 (DOUBLE)
 
[BackPropagationNetwork]
Value of neural input [0] is [0.222].
Value of neural input [1] is [0.682].
Value of neural input [2] is [0.07].
Value of neural input [3] is [0.042].
Value of hidden layer neuron [4] is [-1].
Value of hidden layer neuron [5] is [0.955].
Value of hidden layer neuron [6] is [0.996].
Value of hidden layer neuron [7] is [-0.886].
Value of hidden layer neuron [8] is [0.397].
Value of hidden layer neuron [9] is [-0.541].
Value of hidden layer neuron [10] is [-0.345].
Value of output neuron [11] in the last neural layer is [1].
Value of output neuron [12] in the last neural layer is [0].
Value of output neuron [13] in the last neural layer is [0].
 
[Output]
The predicted value of segment model [2] is [Iris-setosa (STRING)]
 
 
Process segment model [3]:
The predicate of segment model [3] evaluates [True]
 
[MiningSchema]
[sepal_length] := 5.1 (DOUBLE)
[sepal_width] := 3.5 (DOUBLE)
[petal_length] := 1.4 (DOUBLE)
[petal_width] := 0.2 (DOUBLE)
 
[LocalTransformations]
[derived_sepal_length] := 0.22222222222222213 (DOUBLE)
[derived_sepal_width] := 0.6818181818181818 (DOUBLE)
[derived_petal_length] := 0.07017543859649121 (DOUBLE)
[derived_petal_width] := 0.04166666666666667 (DOUBLE)
 
[Regression]
Processing [RegressionTable] [targetCategory: Iris-versicolor (STRING)]:
Applied [Intercept], the value is [-14.897].
Applied [NumericPredictor] [coefficient: 61.867, exponent: 1] on field(s) [derived_sepal_length], the value is [13.748].
Applied [NumericPredictor] [coefficient: -137.017, exponent: 1] on field(s) [derived_sepal_width], the value is [-93.421].
Applied [NumericPredictor] [coefficient: 90.432, exponent: 1] on field(s) [derived_petal_length], the value is [6.346].
Applied [NumericPredictor] [coefficient: 11.529, exponent: 1] on field(s) [derived_petal_width], the value is [0.48].
 
Processing [RegressionTable] [targetCategory: Iris-virginica (STRING)]:
Applied [Intercept], the value is [-202.201].
Applied [NumericPredictor] [coefficient: -120.94, exponent: 1] on field(s) [derived_sepal_length], the value is [-26.875].
Applied [NumericPredictor] [coefficient: -129.401, exponent: 1] on field(s) [derived_sepal_width], the value is [-88.228].
Applied [NumericPredictor] [coefficient: 284.914, exponent: 1] on field(s) [derived_petal_length], the value is [19.994].
Applied [NumericPredictor] [coefficient: 251.754, exponent: 1] on field(s) [derived_petal_width], the value is [10.49].
 
Processing [RegressionTable] [targetCategory: Iris-setosa (STRING)]:
Applied [Intercept], the value is [0].
 
The predicted value of the regression table with category [Iris-versicolor (STRING)] is [-87.743]. Value after normalization is [0].
The predicted value of the regression table with category [Iris-virginica (STRING)] is [-286.82]. Value after normalization is [0].
The predicted value of the regression table with category [Iris-setosa (STRING)] is [0]. Value after normalization is [1].
 
[Output]
The predicted value of segment model [3] is [Iris-setosa (STRING)]
 
 
[Output]
The [predictedValue] is [Iris-setosa (STRING)]
[class] := Iris-setosa (STRING)
The [probability] of [Iris-setosa (STRING)] is [1.0 (DOUBLE)]
[Probability_setosa] := 1.0 (DOUBLE)
The [probability] of [Iris-versicolor (STRING)] is [0.0 (DOUBLE)]
[Probability_versicolor] := 0.0 (DOUBLE)
The [probability] of [Iris-virginica (STRING)] is [0.0 (DOUBLE)]
[Probability_virginica] := 0.0 (DOUBLE)

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/apply/Iris_NN/explain record=%7B%22petal_length%22:%221.4%22,%22petal_width%22:%220.2%22,%22sepal_length%22:%225.1%22,%22sepal_width%22:%223.5%22%7D"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request GET "{{url}}/service/zementis/apply/dummy/explain record=%7B%22petal_length%22:%221.4%22,%22petal_width%22:%220.2%22,%22sepal_length%22:%225.1%22,%22sepal_width%22:%223.5%22%7D" \
  --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
  "errors": [
    "Model 'dummy' not found."
  ]
}

Example Request

500 - Internal server Error

curl --request GET "{{url}}/service/zementis/apply/Iris_NN/explain record=%7B" --header "Authorization: {{auth}}"

Example Response

500 - Internal server Error

{
  "timestamp": 1554299924722,
  "status": 500,
  "error": "Internal Server Error",
  "exception": "com.fasterxml.jackson.core.io.JsonEOFException",
  "message": "Unexpected end-of-input: expected close marker for Object (start marker at [Source: {; line: 1, column: 1])\n at [Source: {; line: 1, column: 3]",
  "path": "/apply/Iris_ME_Classification/explain"
}

POST - Apply Model to Multiple Records

{{url}}/service/zementis/apply/{{model_name}}

Apply a model to multiple records. This provides two kinds of operations. Generally, if a predictive model without binary type input is applied, this will be a batch ‘apply’ operation that streams multiple input records to Zementis microservice. Zementis microservice will automatically detect CSV (Comma Separated Value) or JSON records formatted input and stream results back in the same format unless otherwise specified in the Accept request header parameter with text/csv or application/json values. Compressing input data with ZIP or GZIP will result in the same compression method for the returned output stream.

Note that if the records are specified in a file then the size of the uploaded file should not exceed 500 MB.

If a predictive model with a binary type input is applied, this will be a single ‘apply’ operation that processes a single binary source as input to Zementis Server.

HEADERS
Authorization {{auth}}
Content-Type required header parameter with two accepted values: application/octet-stream or multipart/form-data
Accept optional header parameter for explicitly specifying text/csv or application/json output format
PARAMS
file (file) data file in CSV with header format or as JSON array [Record]. Only applicable when Content-Type is multipart/form-data
model_name (string) required path variable for the name of the model to be applied
maxThreads optional query parameter for specifying the maximum number of concurrent threads (default value is twice the number of processor cores). No impact if a predictive model with a binary type input was applied
maxRecordsPerThread optional query parameter for specifying the maximum number of records processed by a thread in batch (default value is 5000). No impact if a predictive model with a binary type input was applied

Example Request

200 - OK

curl --request POST "{{url}}/service/zementis/apply/Iris_ME_Classification " \
     --header "Authorization: {{auth}}" --header "Content-Type: multipart/form-data" --header "Accept: text/csv" \
     --form "file=@Iris_ME_Classification.csv"

Example Response

200 - OK 

class,Probability_setosa,Probability_versicolor,Probability_virginica
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-setosa,1.0,0.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.2,0.8,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,0.8,0.2
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-virginica,0.0,0.3,0.7
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,0.5,0.5
Iris-versicolor,0.0,0.8,0.2
Iris-versicolor,0.2,0.8,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-versicolor,0.0,1.0,0.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-versicolor,0.0,0.5,0.5
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-versicolor,0.0,0.7,0.3
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-versicolor,0.0,0.5,0.5
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0
Iris-virginica,0.0,0.0,1.0

Example Request

400 - Bad Request

curl --request POST "{{url}}/service/zementis/apply/Iris_ME_Classification " \
  --header "Authorization: {{auth}}" --header "Content-Type: multipart/form-data" --form "file=@Invalid.csv"

Example Response

400 - Bad Request

{
  "errors": [
    "Failed to parse input at record 1."
  ]
}

Example Request

401 - Unauthorized

curl --request POST "{{url}}/service/zementis/apply/Iris_ME_Classification " \
     --header "Content-Type: multipart/form-data" --header "Accept: text/csv" \
     --form "file=@Iris_ME_Classification.csv"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --location --request POST "{{url}}/service/zementis/apply/dummy " \
  --header "Authorization: {{auth}}" \
  --header "Content-Type: multipart/form-data" \
  --header "Accept: application/json" \
  --form "file=@dummy.csv"

Example Response

404 - Not Found

{
  "errors": [
    "Model 'dummy' not found."
  ]
}

Time series

Operations for time series data/model.

Info: An active subscription of Nyoka microservice is required to leverage the time series API.

Domain Model

TimeSeries

Name Type Description
series array The time series data specified as an array of values representing multiple observations.
observationInterval TimePeriod The time interval between consecutive observations.
startDate DateTime The timestamp of the first observation in UTC format.
seasonality TimePeriod Optional parameter to specify the seasonal period in the data, if present.

TimePeriod

Name Type Description
timeUnit ChronoUnit The value has to be a valid ChronoUnit – “SECONDS”, “MINUTES”, “HOURS”, “DAYS”, “MONTHS”, “YEARS” etc.
periodLength Number Length of the period.

POST – Generate time series model using time series data

{{url}}/service/zementis/timeseries

Upload the time series data to generate a model. This is an asynchronous call which returns a status URL that can be used to check the status of model creation.

HEADERS
Authorization {{auth}}
Content-Type required header parameter with value application/json

BODY

{
    "series": [<value1>, <value2>, ...., <valueN>],
    "observationInterval": {
       "timeUnit": "<timeUnit>",
        "periodLength": <periodLength>
    },
    "startDate": "<startDate>",
    "seasonality": {
        "timeUnit": "<timeUnit>",
        "periodLength": <periodLength>
    }
}

Example Request

200 - OK

curl --request POST “{{url}}/service/zementis/timeseries” --header “Authorization: {{auth}}” \
	--header “Content-Type: application/json”

{
    "series": [
       112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118, 115,
       126, 141, 135, 125, 149, 170, 170, 158, 133, 114, 140, 145, 150,
       178, 163, 172, 178, 199, 199, 184, 162, 146, 166, 171, 180, 193,
       181, 183, 218, 230, 242, 209, 191, 172, 194, 196, 196, 236, 235,
       229, 243, 264, 272, 237, 211, 180, 201, 204, 188, 235, 227, 234,
       264, 302, 293, 259, 229, 203, 229, 242, 233, 267, 269, 270, 315,
       364, 347, 312, 274, 237, 278, 284, 277, 317, 313, 318, 374, 413,
       405, 355, 306, 271, 306, 315, 301, 356, 348, 355, 422, 465, 467,
       404, 347, 305, 336, 340, 318, 362, 348, 363, 435, 491, 505, 404,
       359, 310, 337, 360, 342, 406, 396, 420, 472, 548, 559, 463, 407,
       362, 405, 417, 391, 419, 461, 472, 535, 622, 606, 508, 461, 390,
       432
    ],
    "observationInterval": {
       "timeUnit": "MONTHS",
       "periodLength": 1
    },
    "startDate": "2019-01-01T00:00:00+05:30",
    "seasonality": {
        "timeUnit": "YEARS",
        "periodLength": 1
    }
}

Example Response

200 - OK 

{
	“modelName”: “TimeSeries_11-12-2019_11-03-33”,
	“statusUrl”: "/service/zementis/timeseries/TimeSeries_11-12-2019_11-03-33/status"
}

Example Request

400 - Bad Request

curl --request POST “{{url}}/service/zementis/timeseries” --header “Authorization: {{auth}}” \
	--header “Content-Type: application/json”

{
    "series": [
       112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118, 115,
       126, 141, 135, 125, 149, 170, 170, 158, 133, 114, 140, 145, 150,
       178, 163, 172, 178, 199, 199, 184, 162, 146, 166, 171, 180, 193,
       181, 183, 218, 230, 242, 209, 191, 172, 194, 196, 196, 236, 235,
       229, 243, 264, 272, 237, 211, 180, 201, 204, 188, 235, 227, 234,
       264, 302, 293, 259, 229, 203, 229, 242, 233, 267, 269, 270, 315,
       364, 347, 312, 274, 237, 278, 284, 277, 317, 313, 318, 374, 413,
       405, 355, 306, 271, 306, 315, 301, 356, 348, 355, 422, 465, 467,
       404, 347, 305, 336, 340, 318, 362, 348, 363, 435, 491, 505, 404,
       359, 310, 337, 360, 342, 406, 396, 420, 472, 548, 559, 463, 407,
       362, 405, 417, 391, 419, 461, 472, 535, 622, 606, 508, 461, 390,
       432
    ],
    "observationInterval": {
       "timeUnit": "MONTHS",
       "periodLength": 1
    },
    "startDate": "2019-01-01T00:00:00+05:3012",
    "seasonality": {
        "timeUnit": "YEARS",
        "periodLength": 1
    }
}

Example Response

400 - Bad Request

{
    "errors": [
        "Invalid start date. Provide start date in yyyy-MM-dd'T'HH:mm:ss.SSSXXX format"
    ]
}

Example Request

401 - Unauthorized

curl --request POST “{{url}}/service/zementis/timeseries” --header “Content-Type: application/json”

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "No auth information found",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

500 - Internal Server Error

curl --request POST “{{url}}/service/zementis/timeseries” --header “Authorization: {{auth}}” \
	--header “Content-Type: application/json”

{
    "series": [
       112, 118, 132, 129, 121, 135, 148, 148, 136, 119, 104, 118, 115,
       126, 141, 135, 125, 149, 170, 170, 158, 133, 114, 140, 145, 150,
       178, 163, 172, 178, 199, 199, 184, 162, 146, 166, 171, 180, 193,
       181, 183, 218, 230, 242, 209, 191, 172, 194, 196, 196, 236, 235,
       229, 243, 264, 272, 237, 211, 180, 201, 204, 188, 235, 227, 234,
       264, 302, 293, 259, 229, 203, 229, 242, 233, 267, 269, 270, 315,
       364, 347, 312, 274, 237, 278, 284, 277, 317, 313, 318, 374, 413,
       405, 355, 306, 271, 306, 315, 301, 356, 348, 355, 422, 465, 467,
       404, 347, 305, 336, 340, 318, 362, 348, 363, 435, 491, 505, 404,
       359, 310, 337, 360, 342, 406, 396, 420, 472, 548, 559, 463, 407,
       362, 405, 417, 391, 419, 461, 472, 535, 622, 606, 508, 461, 390,
       432
    ],
    "observationInterval": {
       "timeUnit": "MONTHS",
       "periodLength": 1
    },
    "startDate": "2019-01-01T00:00:00+05:30",
    "seasonality": {
        "timeUnit": "YEARS",
        "periodLength": 1
    }
}

Example Response

500 - Internal Server Error

{
    "errors": [
        "Nyoka microservice is unsubscribed. Subscribe to Nyoka microservice to upload timeseries model."
    ]
}

GET – Get status of generated time series model

{{url}}/service/zementis/timeseries

Get the status of the generation of a specific time series model. The status can either be IN_PROGRESS, SUCCESS or FAILURE.
If the status is FAILURE, the errorMessage attribute in the response holds the reason for the failure.

HEADERS
Authorization {{auth}}
PARAMS
model_name (string) required path variable for time series model name

Example Request

200 - OK 

curl --request GET “{{url}}/service/zementis/timeseries/TimeSeries_11-12-2019_11-03-33/status” --header “Authorization: {{auth}}”

Example Response

200 - OK

{
    "status": "IN_PROGRESS",
    "errorMessage": "null"
}

Example Request

401 – Unauthorized

curl --request GET “{{url}}/service/zementis/timeseries/TimeSeries_11-12-2019_11-03-33/status” 

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "No auth information found",
    "info": "https://cumulocity.com/reference/rest-implementation/#error_reporting"
}

Example Request

404 – Not Found

curl --request GET “{{url}}/service/zementis/timeseries/dummy/status” --header “Authorization: {{auth}}”

Example Response

404 – Not Found

{
    "errors": [
        "Model 'dummy' not found."
    ]
}

Example Request

500 – Internal Server Error

curl --request GET “{{url}}/service/zementis/timeseries/TimeSeries_11-11-2019_11-22-33/status” --header “Authorization: {{auth}}”

Example Response

500 – Internal Server Error

{
    "errors": [
        "Model generation failed, try again"
    ]
}

Jobs

Operations on jobs scheduled for processing device data.

Domain Model

JobConfiguration

Name Type Description
jobName String Name of the job.
jobDescription String Description of the job.
associatedGroupOrDeviceId Number Id of the device or device group whose measurements will be
processed when the job executes.
associatedModel String Name of the model which will process the device measurements.
modelToDeviceMappings Map Map with the model’s inputs as the keys and the measurements as the
corresponding values. These mappings ensure which measurement
reading maps to which model input.
jobSchedule JobSchedule Information about when the job should be scheduled for executions.

JobSchedule

Name Type Description
frequency String Frequency of job execution. Can be either periodic or once.
cronExpression String CRON expression to specify the execution schedule for a periodic job. Follow
http://www.quartz-scheduler.org/documentation/quartz-2.3.0/tutorials/crontrigger.html
for more info on CRON.
dataFromPreviousNSeconds Number Number of seconds in the past from which
data should be fetched for processing. The value must not exceed 86400 i.e. 24 hours.
timeZone String Time zone in which the periodic job should be scheduled.
scheduleAt String Datetime string in the future when the job should be scheduled.
dataFrom String Datetime string from the past which should be considered as the starting point
for data to be fetched for processing.
dataTo String Datetime string from the past which should be considered as the ending point
for data to be fetched for processing.

Info:
1. For periodic frequency, cronExpression, dataFromPreviousNSeconds and timeZone fields are mandatory.
2. For once frequency, scheduleAt, dataFrom and dataTo fields are mandatory and should adhere to the ISO-8601 date-time format
  i.e. “yyyy-MM-dd’T’HH:mm:ss.SSSXXX”, for instance “2019-12-30T22:59:50.235+05:30”.
  The difference between dataFrom and dateTo must not exceed 24 hours.

POST - Create New Job

{{url}}/service/zementis/job

Create a new job for scheduled data processing.

On creation, a jobId is automatically assigned to the job and jobCreationDate will also be added to the response.

HEADERS
Authorization {{auth}}
Content-Type application/json

BODY

{
   "jobName": "<jobName>",
   "jobDescription": "<jobDescription>",
   "associatedGroupOrDeviceId" : <associatedGroupOrDeviceId>,
   "associatedModel": "<associatedModel>",
   "modelToDeviceMappings": {
      "<Model_Input1>": "<measurementType>.<seriesName1>.value",
      "<Model_Input2>": "<measurementType>.<seriesName2>.value",
      "<Model_Input3>": "<measurementType>.<seriesName3>.value"
   },
   "jobSchedule": {
      "frequency": "<periodic | once>",
      "cronExpression": "<cronExpression>",
      "dataFromPreviousNSeconds": <dataFromPreviousNSeconds>,
      "timeZone":"<timeZone>",
      "scheduleAt": "<scheduleAt>",
      "dataFrom": "<dataFrom>",
      "dataTo": "<dataTo>"
   }
}

Example Request

201 - Created

curl --request POST "{{url}}/service/zementis/job" --header "Authorization: {{auth}}"

{
   "jobName": "SampleJob",
   "jobDescription": "SampleDescription",
   "associatedGroupOrDeviceId" : 123456,
   "associatedModel": "ActivityRecognitionModel",
   "modelToDeviceMappings": {
      "accelerationX": "c8y_Acceleration.c8y_AccelerationX.value",
      "accelerationY": "c8y_Acceleration.c8y_AccelerationY.value",
      "accelerationZ": "c8y_Acceleration.c8y_AccelerationZ.value"
   },
   "jobSchedule": {
      "frequency": "periodic",
      "cronExpression": "10 * * ? * *",
      "dataFromPreviousNSeconds": 10,
      "timeZone":"Asia/Kolkata"
   }
}

Example Response

201 - Created

{
   "jobId": 11058170, 
   "jobName": "SampleJob",
   "jobDescription": "SampleDescription",
   "jobCreationDate": "2019-10-05T08:12:21.340Z",
   "associatedGroupOrDeviceId" : 123456,
   "associatedModel": "ActivityRecognitionModel",
   "modelToDeviceMappings": {
      "accelerationX": "c8y_Acceleration.c8y_AccelerationX.value",
      "accelerationY": "c8y_Acceleration.c8y_AccelerationY.value",
      "accelerationZ": "c8y_Acceleration.c8y_AccelerationZ.value"
   },
   "jobSchedule": {
      "frequency": "periodic",
      "cronExpression": "10 * * ? * *",
      "dataFromPreviousNSeconds": 10,
      "timeZone":"Asia/Kolkata",
      "scheduleAt": null,
      "dataFrom": null,
      "dataTo": null
   }
}

Example Request

400 - Bad Request

curl --request POST "{{url}}/service/zementis/job" --header "Authorization: {{auth}}"

{
   "jobName": "SampleJob",
   "jobDescription": "SampleDescription",
   "associatedGroupOrDeviceId" : 123456,
   "associatedModel": "ActivityRecognitionModel",
   "modelToDeviceMappings": {
      "accelerationX": "c8y_Acceleration.c8y_AccelerationX.value",
      "accelerationY": "c8y_Acceleration.c8y_AccelerationY.value",
      "accelerationZ": "c8y_Acceleration.c8y_AccelerationZ.value"
   },
   "jobSchedule": {
      "frequency": "Invalid",
      "cronExpression": "10 * * ? * *",
      "dataFromPreviousNSeconds": 10,
      "timeZone":"Asia/Kolkata"
   }
}

Example Response

400 - Bad Request

{
    "errors": [
        "frequency can be either once or periodic."
    ]
}

Example Request

401 - Unauthorized

curl --request POST "{{url}}/service/zementis/job"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request POST "{{url}}/service/zementis/job" --header "Authorization: {{auth}}"

{
   "jobName": "SampleJob",
   "jobDescription": "SampleDescription",
   "associatedGroupOrDeviceId" : 123456,
   "associatedModel": "Dummy",
   "modelToDeviceMappings": {
      "accelerationX": "c8y_Acceleration.c8y_AccelerationX.value",
      "accelerationY": "c8y_Acceleration.c8y_AccelerationY.value",
      "accelerationZ": "c8y_Acceleration.c8y_AccelerationZ.value"
   },
   "jobSchedule": {
      "frequency": "once",
      "scheduleAt": "2019-10-05T14:14:56.235+05:30",
      "dataFrom": "2019-10-04T12:01:55.235+05:30",
      "dataTo": "2019-10-05T12:01:55.235+05:30"
   }
}

Example Response

404 - Not Found

{
    "errors": [
        "Model 'Dummy' not found."
    ]
}

GET - List Available Jobs

{{url}}/service/zementis/jobs

Retrieves all the available jobs. Use the jobId of these jobs as identifiers for all operations requiring the {jobId} path variable.

HEADERS
Authorization {{auth}}

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/jobs" --header "Authorization: {{auth}}"

Example Response

200 - OK

[
    {
        "jobId": 10979435,
        "jobName": "Job1",
        "jobDescription": "DemoJob",
        "jobCreationDate": "2019-09-30T15:58:20.749Z",
        "associatedModel": "IsolationForest",
        "associatedGroupOrDeviceId": 10417743,
        "modelToDeviceMappings": {
            "accelerationY": "c8y_Acceleration.accelerationY.value",
            "accelerationX": "c8y_Acceleration.accelerationX.value",
            "accelerationZ": "c8y_Acceleration.accelerationZ.value",
            "gyroX": "c8y_Gyroscope.gyroX.value",
            "gyroY": "c8y_Gyroscope.gyroY.value",
            "gyroZ": "c8y_Gyroscope.gyroZ.value"
        },
        "jobSchedule": {
            "frequency": "periodic",
            "cronExpression": "0 0 5 1/1 * ? *",
            "timeZone": "Asia/Calcutta",
            "dataFromPreviousNSeconds": 18000,
            "scheduleAt": null,
            "dataFrom": null,
            "dataTo": null
        },
        "jobStatus": "Warning",
        "lastExecutionDuration": "63"
    },
    {
        "jobId": 10852249,
        "jobName": "Job2",
        "jobDescription": "DemoJob",
        "jobCreationDate": "2019-09-30T05:47:33.772Z",
        "associatedModel": "IsolationForest",
        "associatedGroupOrDeviceId": 9304033,
        "modelToDeviceMappings": {
            "var1": "s7aFlowC.F.value",
            "var2": "s7aFlowC.F.value"
        },
        "jobSchedule": {
            "frequency": "periodic",
            "cronExpression": "5 18 11 1/1 * ? *",
            "timeZone": "Asia/Calcutta",
            "dataFromPreviousNSeconds": 3456000,
            "scheduleAt": null,
            "dataFrom": null,
            "dataTo": null
        },
        "jobStatus": "Failure",
        "lastExecutionDuration": "728339"
    }
]

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/jobs"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

GET - Get Job Information

{{url}}/service/zementis/job/{{jobId}}

Get information about a specific job.

Apart from JobConfiguration, the information contains the status of the job. If there is no ongoing execution, then the status is fetched from the job’s last execution.

Note that the unit of lastExecutionDuration is milliseconds.

HEADERS
Authorization {{auth}}
PARAMS
jobId (string) required path variable for job id

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/job/10979435" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
    "jobId": 10979435,
    "jobName": "Job1",
    "jobDescription": "DemoJob",
    "jobCreationDate": "2019-09-30T15:58:20.749Z",
    "associatedModel": "IsolationForest",
    "associatedGroupOrDeviceId": 10417743,
    "modelToDeviceMappings": {
        "accelerationY": "c8y_Acceleration.accelerationY.value",
        "accelerationX": "c8y_Acceleration.accelerationX.value",
        "accelerationZ": "c8y_Acceleration.accelerationZ.value",
        "gyroX": "c8y_Gyroscope.gyroX.value",
        "gyroY": "c8y_Gyroscope.gyroY.value",
        "gyroZ": "c8y_Gyroscope.gyroZ.value"
    },
    "jobSchedule": {
        "frequency": "periodic",
        "cronExpression": "0 0 5 1/1 * ? *",
        "timeZone": "Asia/Calcutta",
        "dataFromPreviousNSeconds": 18000,
        "scheduleAt": null,
        "dataFrom": null,
        "dataTo": null
    },
    "jobStatus": "Warning",
    "lastExecutionDuration": "63"
}

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/job/10979435"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request GET "{{url}}/service/zementis/job/000000" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
    "errors": [
        "Zementis job ID '00000' not found."
    ]
}

GET - Job Execution History

{{url}}/service/zementis/job/{{jobId}}/history

Get execution history of a particular job. Lists all executions of that specific job. Use the jobExecutionNumber of these executions as identifiers for all operations requiring the {executionId} path variable.

HEADERS
Authorization {{auth}}
PARAMS
jobId (string) required path variable for job id

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/job/10979435/history" --header "Authorization: {{auth}}"

Example Response

200 - OK 

[
    {
        "jobId": 10979435,
        "jobExecutionNumber": 1,
        "isExecutionForDeviceGroup": true,
        "jobExecutionStartTime": "2019-09-23T15:39:15Z",
        "jobExecutionEndTime": "2019-09-23T15:39:19.051Z",
        "jobExecutionDuration": "4051",
        "jobExecutionStatus": "Success",
        "jobExecutionStatusMessage": []
    },
	{
        "jobId": 10979435,
        "jobExecutionNumber": 2,
        "isExecutionForDeviceGroup": true,
        "jobExecutionStartTime": "2019-09-30T23:30:00.009Z",
        "jobExecutionEndTime": "2019-09-30T23:30:00.401Z",
        "jobExecutionDuration": "392",
        "jobExecutionStatus": "Warning",
        "jobExecutionStatusMessage": [
            "The device 107742 was not active or sending any measurements during the time specified for data range"
        ]
    }
]

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/job/10979435/history"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request PUT "{{url}}/service/zementis/job/00000/history" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
    "errors": [
        "Zementis job ID '00000' not found."
    ]
}

GET - Job Execution Detail

{{url}}/service/zementis/job/{{jobId}}/history/{{executionId}}

Get details of a specific job execution.

Note that the unit of jobExecutionDuration is milliseconds.

HEADERS
Authorization {{auth}}
PARAMS
jobId (string) required path variable for job id
executionId (string) required path variable for execution id

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/job/10979435/history/1" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
    "jobId": 10979435,
    "jobExecutionNumber": 1,
    "isExecutionForDeviceGroup": true,
    "jobExecutionStartTime": "2019-09-23T15:39:15Z",
    "jobExecutionEndTime": "2019-09-23T15:39:19.051Z",
    "jobExecutionDuration": "4051",
    "jobExecutionStatus": "Success",
    "jobExecutionStatusMessage": []
}

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/job/10979435/history/1"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request GET "{{url}}/service/zementis/job/10979435/history/0" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
    "errors": [
        "Job Execution number 0 does not exist."
    ]
}

GET - Job Execution Results

{{url}}/service/zementis/job/{{jobId}}/history/{{executionId}}/inferences

Get the results/inferences generated in a single job execution. These inferences are the predictions of the machine learning model against the data from the associated device/device group.

HEADERS
Authorization {{auth}}
PARAMS
jobId (string) required path variable for job id
executionId (string) required path variable for execution id
currentPage (string) optional parameter for specifying which page to fetch; each page will contain maximum 2000 inferences

Example Request

200 - OK

curl --request GET "{{url}}/service/zementis/job/10979435/history/1/inferences" --header "Authorization: {{auth}}"

Example Response

200 - OK

{
    "inferenceCollection": [
        {
            "recordCollection": {
                "normalizedAnomalyScore": [0.30919784638525916, 0.5981812541231656, 0.36394405330406093, 0.36394405330406093, 0.5981812541231656],
                "decisionFunction": [-0.30709038523208043, -0.237037401162047, -0.277037401162047, -0.277037401162047, -0.22561825856400746],
                "rawAnomalyScore": [4.68, 8.968584665454545, 5.52, 5.52, 9.205437462877498],
                "outlier": [false, true, false, false, true]
            },
            "deviceId": 103030
        },
        {
            "recordCollection": {
                "normalizedAnomalyScore": [0.30919784638525916, 0.5981812541231656, 0.36394405330406093, 0.36394405330406093, 0.2981812541231656],
                "decisionFunction": [-0.30709038523208043, -0.237037401162047, -0.277037401162047, -0.277037401162047, -0.29561825856400746],
                "rawAnomalyScore": [4.68, 8.968584665454545, 5.52, 5.52, 4.29],
                "outlier": [false, true, false, false, false]
            },
            "deviceId": 107742
        }
    ],
    "currentPage": 1
}

Example Request

401 - Unauthorized

curl --request GET "{{url}}/service/zementis/job/10979435/history/1/inferences"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request GET "{{url}}/service/zementis/job/10979435/history/0/inferences" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
    "errors": [
        "Job Execution number 0 does not exist."
    ]
}

DEL - Remove Job

{{url}}/service/zementis/job/{{jobId}}

Remove the specified job.

HEADERS
Authorization {{auth}}
PARAMS
jobId (string) required path variable for job id

Example Request

200 - OK

curl --request DELETE "{{url}}/service/zementis/job/11058170" --header "Authorization: {{auth}}"

Example Response

200 - OK

[]

Example Request

401 - Unauthorized

curl --request DELETE "{{url}}/service/zementis/job/11058170"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Example Request

404 - Not Found

curl --request DELETE "{{url}}/service/zementis/job/00000" --header "Authorization: {{auth}}"

Example Response

404 - Not Found

{
    "errors": [
        "Zementis job ID '00000' not found."
    ]
}

DEL - Remove All Jobs

{{url}}/service/zementis/jobs

Remove all available jobs and list the remaining jobs, if any.

HEADERS
Authorization {{auth}}

Example Request

200 OK

curl --request DELETE "{{url}}/service/zementis/jobs" --header "Authorization: {{auth}}"

Example Response

200 - OK

[]

Example Request

401 - Unauthorized

curl --request DELETE "{{url}}/service/zementis/jobs"

Example Response

401 - Unauthorized

{
    "error": "general/internalError",
    "message": "Not authorized!",
    "info": "https://www.cumulocity.com/reference-guide/#error_reporting"
}

Using Postman

Graphical REST clients such as Postman are a convenient way to explore REST interfaces and the Cumulocity database content.

If you are already using the Cumulocity API collection in Postman and the environment to access the Cumulocity collection for your tenant is setup, then you can directly import the Zementis microservice collection (see below).

If you are doing a fresh setup of Postman for using the Zementis microservice collection, first follow the steps described under “Using Postman” in Using the Rest interface in the Microservice SDK guide.

Import the Zementis microservice collection in Postman

Import the APIs as a JSON file.

Alternatively click: Run in Postman After importing, you will see a new collection “Zementis Microservice API” in the Collections tab in Postman.