# Straatos Interact API

Straatos Interact API enables 3rd party applications and web services to interact with Straatos to create new tasks, upload documents, update existing tasks, return values of tasks to the 3rd party application.

To know more about how two programs connect using web services, please refer to [FAQs](#faqs).

Click highlighted areas for more information:

* [Create a new Task in Straatos](#sample-code-1-create-a-new-task-in-straatos).
* [Create a new Task in Straatos with Index fields](#sample-code-2-create-a-new-task-in-straatos-with-index-fields).
* [Create a new Task in Straatos with Index fields and JPG Files / Pages](#sample-code-3-create-a-new-task-with-index-fields-and-jpg-files-pages).
* [Forward a Task in the workflow and update field values](#sample-code-4-forward-a-task-in-the-workflow-and-update-field-values).
* [Upload a PDF File](#sample-code-5-upload-a-pdf-file).
* [Polling](#sample-code-6-polling).
* [Usage of getDocumentInfo](#sample-code-7-usage-of-getdocumentinfo).
* [Get additional stored documents](#sample-code-8-get-additional-stored-documents).
* [Uploading a PDF as additional data](#sample-code-9-uploading-a-pdf-as-additional-data).
* [XML without namespaces](#sample-code-10-xml-without-namespaces).
* [XML with namespaces](#sample-code-11-xml-with-namespaces).
* [Securing the interact script](#sample-code-12-securing-the-interact-script).

#### References

* [FAQs](#faqs).
* [API DOCS](#api-documentation).

***

### Benefits

* Straatos accepts web service calls from any POST/GET web service call, regardless of parameters, headers, or body.
* Reduce development time of integration from weeks to days.
* No additional hosting fees and third-party service provider.
* Control functionality and data available through the web service.
* Control security of the web service.

***

### How Does it Work

Straatos Interact API allows you (or the CumulusPro Professional Services team) to define your own Straatos API in a simple JavaScript. Hosting of API is done on Straatos Platform and API can be accessed through Admin Panel.

***

### Web Service URL

Every organisation in Straatos has its own URL. The URL is unique to specific organisation and cannot be changed.

Example:

* `https://effektifconnector.cumuluspro.net/ConnectorService.svc/json/Interact/`&#x20;

{% hint style="info" %}
Actual URL can change based on your organisation and geographical location.
{% endhint %}

#### Configuration of the Web Service

JavaScript is used to define the web service. To define a new web service, go to Admin Panel > Organisation > Interact Script.

How to create a new task in a Straatos process.

<table><thead><tr><th width="123.54541015625">Name</th><th width="141.1817626953125">Where to look</th><th>Description</th></tr></thead><tbody><tr><td>createTask</td><td>Line 1</td><td><p>New web service is defined.</p><p></p><p>Web service calls are checked if it is for web service.createTask.</p></td></tr><tr><td></td><td>Line 4</td><td>New task in Straatos created for the process ‘Test QA Workflow’ and Start Event ‘Start’.</td></tr><tr><td></td><td>Line 6</td><td>Response provided to calling web service.</td></tr></tbody></table>

#### Sample Code

```javascript
if (request.pathSegments[1] == 'createTask') {

// Create a new Task in the workflow named 'Test QA Workflow' at the Start Event 'Start'

// and returns the documentId of the newly created task

var documentId = straatos.addDocument('Test QA Workflow', 'Start');

// response of the webservice with the DocumentID

response.body = "Finished request of type " + request.pathSegments[1] + " DocumentID: " + documentId;

}
```

For easier development and troubleshooting, Admin Panel provides a Log where `console.log` can write logging data.

To call this web service from a 3rd party application, the following URL can be used:

Example:

* <https://effektif-connector.cumuluspro.net/ConnectorService.svc/json/Interact//createTask>

***

### API Documentation

This section describes how to use Straatos interact API to create new tasks, upload documents, update existing tasks, return values of tasks to 3rd party application.

#### API Server and Base URL

<table><thead><tr><th width="165.8182373046875">Region</th><th>URL</th></tr></thead><tbody><tr><td>Europe</td><td><code>https://effektifconnector.cumuluspro.net/ConnectorService.svc/json/Interact/</code></td></tr><tr><td>Switzerland</td><td><code>https://effektifconnector-ch.cumuluspro.net/ConnectorService.svc/json/Interact/</code></td></tr><tr><td>Asia</td><td><code>https://effektifconnector-asia.cumuluspro.net/ConnectorService.svc/json/Interact/</code></td></tr></tbody></table>

To know more about Organisation ID, refer to [FAQs](#faqs).

#### Request and Response Parameter

Request and response parameter contain information sent to web service and response sent by web service to web service call. Refer to [Sample Code](#sample-code) section for more details.

#### Request

<table><thead><tr><th width="170.272705078125">Name</th><th width="161.63629150390625">Type</th><th>Description</th></tr></thead><tbody><tr><td>pathSegments</td><td>string</td><td>Path segments. for example:</td></tr><tr><td>URL</td><td>pathSegments</td><td></td></tr><tr><td>https://domain.net/Connector.svc/json/Interact/A3B23-GUID-E76B/P2/P3</td><td>['A3B23-GUID-E76B', 'P2', 'P3']</td><td></td></tr><tr><td>queryParameters</td><td></td><td>For example: URL: <code>https://domain.net/Connector.svc/json/Interact/A3B23-GUID-E76B/P2/P3?id=123&#x26;type=b</code></td></tr><tr><td>headers</td><td>?</td><td><p>Request headers as passed into the Interact call, for example, </p><p></p><p>{ 'Accept': 'application/json', 'X-Header': '123' }</p></td></tr><tr><td>contentType</td><td>string</td><td>Request content type as passed into the Interact call, for example, application/json</td></tr><tr><td>body</td><td></td><td>Request body as passed into the Interact call as byte [] or string using UTF-8 encoding. Not available for multipart requests (Content-Type starts with 'multipart/').</td></tr><tr><td>multipart</td><td>MultiPartRequest</td><td>Parsed parts of the multipart, only available if the request is a multipart request (Content-Type starts with 'multipart/')</td></tr></tbody></table>

#### Response

<table><thead><tr><th width="167.18182373046875">Name</th><th width="142.727294921875">Type</th><th>Description</th></tr></thead><tbody><tr><td>status</td><td>number</td><td>HTTP status code to return to the client, 200 by default</td></tr><tr><td>headers</td><td></td><td><p>Response headers that are returned to the client.</p><p></p><p>For example: { 'Accept': 'application/json', 'X-Header': '123' }</p></td></tr><tr><td>body</td><td></td><td>Response body as byte[] or MultiPart. To convert a string to byte[], you can use straatos.getBytes(stringVariable). A MultiPart object can be created using straatos.newFormData()</td></tr></tbody></table>

***

### Straatos Functions

Straatos contains functions to interact with the platform.

<table><thead><tr><th width="202.6363525390625">Name</th><th width="247.4544677734375">Attribute</th><th>Description</th></tr></thead><tbody><tr><td>findDocuments</td><td>fn(workflowName: string, activityName: string, variables: ?) -> [number]</td><td>Find documents in the specified workflow step that match the variables (for example, { 'InvoiceNumber': 'IN12345' }). Returns an array with document ids.</td></tr><tr><td>messageWorkflow</td><td>fn(workflowName: string, activityName: string, documentIds: [number], variables: ?)</td><td>Send a message to the specified documents (usually acquired through straatos.findDocuments()) in the specified workflow step. The specified (workflow) variables (for example, { 'Status': 'Verified' }) will be updated.</td></tr><tr><td>addDocument</td><td>fn(workflowName: string, startEventName: string) -> number</td><td>Create a document, required for startWorkflow. Returns the document id.</td></tr><tr><td>addComment</td><td>fn(documentId: number, comment: string, commentDateTimeIso8601: string)</td><td>Adds a document comment. commentDateTimeIso8601 should be in ISO datetime format (YYYYMMDDThhmmss ie 2021-04-10T16:56:02Z)</td></tr><tr><td>startWorkflow</td><td>fn(documentId: number, variables: ?)</td><td>Start the workflow / start event for the specified document (created with addDocument). The specified (workflow) variables (for example, { 'Status': 'Verified' }) will be assigned.</td></tr><tr><td>getVariables</td><td>fn(documentId: number) -> ?</td><td>Get the workflow field values for the specified document (for example, { 'Name': 'John', 'InvoiceNumber': 'IN12345' })</td></tr><tr><td>setDocumentContent</td><td>fn(documentId: number, files: [?], filetype: string, createPagePreviews: bool, createPDFPreviews: bool)</td><td>Add content to the document. The filetype parameters must be 'tif', 'pdf' or 'jpg' Each entry in the files parameter array should be a binary (byte[]), either a single (multi page) TIF, a single (multi page) PDF or one or more JPG files.</td></tr><tr><td>ajax</td><td>fn(parameters: AjaxParameters) -> jqXHR</td><td>Perform a synchronous HTTP (Ajax) request.</td></tr><tr><td>getString</td><td>fn(data: ?) -> string</td><td>Convert byte[] to string using UTF-9 encoding</td></tr><tr><td>getBytes</td><td>fn(data: string) -> ?</td><td>Convert string to byte[] using UTF-8 encoding</td></tr><tr><td>decodeBase64</td><td>fn(data: string) -> ?</td><td>Decode base64 string to byte[]</td></tr><tr><td>encodeBase64</td><td>fn(data: ?) -> string</td><td>Encode base64 byte[] to string</td></tr><tr><td>newFormData</td><td>fn() -> MultiPart</td><td>Create a new MultiPart object</td></tr><tr><td>newXMLDocument</td><td>fn(documentElementName: string, documentElementNamespace: string) -> JsXmlDocument</td><td>Create a new XML document. The documentElementName can contain a namespace prefix (for example, 'ns:company') if a documentElementNamespace is provided. The documentElementNamespace is optional, for elements without namespace this parameter should not be specified.</td></tr><tr><td>parseXML</td><td>fn(data: ?) -> JsXmlDocument</td><td>Parses the data parameter (either a byte[] or string containing the XML and returns the XML document</td></tr><tr><td>transformXSL</td><td>fn(xslDocument: JsXmlDocument, inputDocument: JsXmlDocument) -> JsXmlDocument</td><td>Transforms the inputDocument using the xslDocument XSL. Returns the result as XML document</td></tr></tbody></table>

***

### XML

#### XML Document (JsXmlDocument)

To create an XML Document, use the following straatos methods:

* newXMLDocument.
* prseXML and.
* transformXSL.

<table><thead><tr><th width="208.0909423828125">Name</th><th width="242.6363525390625">Attribute</th><th>Description</th></tr></thead><tbody><tr><td>documentElement</td><td>JsXmlElement</td><td>The root element of the XML document</td></tr><tr><td>xml</td><td>string</td><td>Pretty printed XML string</td></tr><tr><td>xmlBytes</td><td>fn(encoding: string) -> ?</td><td>Returns a byte[] of the pretty printed XML, using the specified encoding. If no encoding is specified, UTF-8 is used.</td></tr></tbody></table>

#### XML Element (JsXmlElement)

XML Elements can be accessed throught the documentElement property of the XML Document and the XML Element methods selectElements, selectSingleElement and created with addElement.

<table><thead><tr><th width="209.90911865234375">Name</th><th width="240.818115234375">Attribute</th><th>Description</th></tr></thead><tbody><tr><td>text</td><td>string</td><td>Text value of the element, for example, CumulusPro would return 'CumulusPro'. Can also be updated, e.g. element.text = 'new value';</td></tr><tr><td>nodeName</td><td>string</td><td>Name of the element, for example, CumulusPro would return 'company'</td></tr><tr><td>namespacePrefix</td><td>string</td><td>If the element has a namespace, returns the prefix used for example, <a href="ns:company">ns:company</a>CumulusPro&#x3C;/ns:company> would return 'ns'</td></tr><tr><td>namespace</td><td>string</td><td>If the element has a namespace returns the namespace URI, for example, &#x3C;ns:company xmlns:ns="urn:my-urn">CumulusPro&#x3C;/ns:company> would return 'urn:my-urn'</td></tr><tr><td>attributes</td><td>?</td><td>Returns an object containing properties representing the attributes of the element, e.g. &#x3C;ns:company ns:attr1="1" attr2="2">CumulusPro&#x3C;/ns:company> would return { 'ns:attr1': '1', '{urn:my-urn}:attr1': '1', 'attr2': '2' }</td></tr><tr><td>xml</td><td>string</td><td>Pretty printed XML string</td></tr><tr><td>addAttribute</td><td>fn(name: string, value: string, namespaceURI: string)</td><td>Adds a new attribute to the element. If namespaceURI is specified, name can contain a prefix, e.g. 'ns:attr1'. For attributes without a namespace, no namespaceURI should be specified.</td></tr><tr><td>removeAttribute</td><td>fn(name: string)</td><td>Removes the attribute by name.</td></tr><tr><td>addElement</td><td>fn(name: string, namespaceURI: string) -> JsXmlElement</td><td>Adds a child element to the current element. If namespaceURI is specified, name can contain a prefix, for example, 'ns:company'. For elements without a namespace, no namespaceURI should be specified.</td></tr><tr><td>remove</td><td>fn()</td><td>Remove the element from the document</td></tr><tr><td>selectElements</td><td>fn(xPath: string, namespaces: ?) -> [JsXmlElement]</td><td>Select elements using the given xPath expression, relative to the current element. Optionally, namespaces can be specified for example, { 'ns': 'urn:my-urn', 'ns2': 'urn:my-urn-2' }</td></tr><tr><td>selectSingleElement</td><td>fn(xPath: string, namespaces: ?) -> JsXmlElement</td><td>Select the first element matching the given xPath expression, relative to the current element. Optionally, namespaces can be specified for example, { 'ns': 'urn:my-urn', 'ns2': 'urn:my-urn-2' }</td></tr><tr><td>stringValue</td><td>fn(xPath: string, namespaces: ?) -> string</td><td>Evaluates the xPath expression relative to the current element. Optionally, namespaces can be specified for example, { 'ns': 'urn:my-urn', 'ns2': 'urn:my-urn-2' }</td></tr></tbody></table>

***

### AJAX Utility Function

<table><thead><tr><th width="207.81829833984375">Name</th><th width="540.727294921875">Description</th></tr></thead><tbody><tr><td>jqXHR</td><td>done: fn(callback: fn(data: ?, response: ?)) -> jqXHR fail: fn(callback: fn(response: ?, error: string)) -> jqXHR</td></tr><tr><td>AjaxParameters</td><td>GG4HPafC3gA7</td></tr><tr><td>MultiPart</td><td>nvqmhbnJhIlx</td></tr><tr><td>MultiPartFile</td><td>F7EoVe62tTIc</td></tr><tr><td>MultiPartRequest</td><td>FB2k6jQOgjbD</td></tr></tbody></table>

#### Sample Code

Simple process flow in Straatos as follows:

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

Start Event:

* It must have a name. For example, in the above case 'Start'.

Wait:

* Once a task is formed in the system, we use a 'Message Receive' task called 'Wait' to wait for some input.

***

### Sample Code 1 - Create a new Task in Straatos

In this sample, a webservice is created that adds a new task in the workflow.

<table><thead><tr><th width="205.3636474609375">Name</th><th width="153.727294921875">Where to look</th><th>Description</th></tr></thead><tbody><tr><td>createTask</td><td>Line 1</td><td>We must check for which webservice the call is. In this case, we expect the webservice to have a /createTask at the end. This allows us to create multiple webservices.</td></tr><tr><td>straatos.addDocument</td><td>Line 4</td><td>The straatos.addDocument creates the task. The parameters specified are the workflow name (Test QA Workflow) and the Start Event Name (Start). The function returns the Straatos DocumentID.</td></tr><tr><td>response.body</td><td>Line 9</td><td>We return the webservice response with a message and the DocumentID. The default Status is always 200 (unless set differently). The default Content-Type is text/plain. This can be overruled by e.g. response.headers['Content-Type'] = 'application/json';</td></tr></tbody></table>

#### Sample

```javascript
if (request.pathSegments[1] == 'createTask') {

  // Create a new Task in the workflow named 'Test QA Workflow' at the Start Event 'Start';
  // and returns the documentId of the newly created task

  var documentId = straatos.addDocument('Test QA Workflow', 'Start');

  straatos.startWorkflow(documentId, {});

  // response of the webservice with the DocumentID
  response.body = "Finished request of type " + request.pathSegments[1] + " DocumentID: " + documentId;
}
```

***

### Sample Code 2 - Create a new Task in Straatos with Index fields

This sample shows submitting index field values as part of the webservice. The body may be multipart.

Key points:

* FirstName:
  * Example getting value from multipart body.
* LastName:
  * Example getting value from header.
* InvoiceNumber:
  * Example getting value from query parameter.

#### Sample

```javascript
if (request.pathSegments[1] == 'createTask') {

  var documentId = straatos.addDocument('Test QA Workflow', 'Start');

  // Adding Index fields values
  straatos.startWorkflow(documentId, {
    'FirstName': request.multipart.parameters.FirstName, // value from multipart body
    'LastName': request.headers.LastName,                // value from header
    'InvoiceNumber': request.queryParameters.InvoiceNumber // value from URI parameters
  });

  response.body = "Finished request of type " + request.pathSegments[1] + " DocumentID: " + documentId;
}
```

***

### Sample Code 3 - Create a new Task with Index fields and JPG Files / Pages

This sample attaches image files uploaded as multipart to a new Straatos Task.

{% hint style="info" %}
If files are uploaded as part of multipart, this works for multipage JPGs where each page is a separate JPG file.
{% endhint %}

#### Sample

```javascript
if (request.pathSegments[1] == 'createTask') {

  var documentId = straatos.addDocument('Test QA Workflow', 'Start');

  // Adding a document (multipart form post should contain JPG files)
  var files = request.multipart.files.map(function (file) { return file.content; });

  straatos.setDocumentContent(documentId, files, 'jpg', true, false);

  // Adding Indexfields values
  straatos.startWorkflow(documentId, {
    'FirstName': request.multipart.parameters.FirstName,
    'LastName': request.headers.LastName,
    'InvoiceNumber': request.queryParameters.InvoiceNumber
  });

  response.body = "Finished request of type " + request.pathSegments[1] + " DocumentID: " + documentId;
}
```

***

### Sample Code 4 - Forward a Task in the workflow and update field values

Find documents in the 'Wait' step for a workflow and forward them by updating index fields.

<table><thead><tr><th width="180.8182373046875">Name</th><th width="136.6363525390625">Where to look</th><th>Description</th></tr></thead><tbody><tr><td>forward</td><td>Line 1</td><td>We created a new webservice called 'forward' as this is a completely different action to the create task.</td></tr><tr><td>Test QA Workflow</td><td>Line 2</td><td>We want to find a specific document in the workflow 'Test QA Workflow' in the process step 'Wait'.</td></tr><tr><td>InvoiceNumber</td><td>Line 2</td><td>We want to find a (all) documents where the invoice Number is the same as submitted in the header.</td></tr><tr><td>PaymentStatus</td><td>Line 6</td><td>Here we update the document in the workflow.<br><br>The '<code>PaymentStatus</code>' is an index field in the workflow that gets updated and the document gets routed to the next stage.</td></tr></tbody></table>

#### Sample

```javascript
if (request.pathSegments[1] == 'forwardTask') {

  var documentIds = straatos.findDocuments('Test QA Workflow', 'Wait', {
    'InvoiceNumber': request.headers.InvoiceNumber
  });

  straatos.messageWorkflow('Test QA Workflow', 'Wait', documentIds, {
    'PaymentStatus': 'paid'
  });

  response.body = "Finished request of type " + request.pathSegments[1];
}
```

***

### Sample Code 5 - Upload a PDF File

This sample handles both PDF (raw body) and JPG (multipart) uploads.

```javascript
if (request.pathSegments[1] == 'createTask') {

  var documentId = straatos.addDocument('Test QA Workflow', 'Start');

  if (typeof(request.multipart) == 'undefined') {
    // assumes the body to contain a PDF file
    straatos.setDocumentContent(documentId, [request.body], 'pdf', true, false);
  } else {
    // assumes the multi part files to be JPG
    var files = request.multipart.files.map(function (file) { return file.content; });
    straatos.setDocumentContent(documentId, files, 'jpg', true, false);
    straatos.startWorkflow(documentId, {});
  }
}
```

***

### Sample Code 6 - Polling

3rd party application may want to poll Straatos for documents. This example finds documents by index field and returns variables (index fields) for the first match.

```javascript
if (request.pathSegments[1] == 'poll') {

  var documentIds = straatos.findDocuments('Test QA Workflow', 'Wait', {
    'LastName': request.headers.Name
  });

  if (documentIds.length > 0) {
    response.body = JSON.stringify(straatos.getVariables(documentIds[0]));
  } else {
    response.body = 'Sorry, no documents found';
  }
}
```

{% hint style="info" %}
If you have the exact documentID (for example, when the document was created with the API further up in the sample), then you can use that particular ID directly in the get Variables call.
{% endhint %}

***

### Sample Code 7 - Usage of getDocumentInfo

The script below uses the getDocumentInfo method on the Adapter and outputs the contents to the console.

```javascript
try {
  var documentInfo = straatos.getDocumentInfo(straatos.documentId);
  console.log(documentInfo);
  response.body = 'Ok!';
} catch(err) {
  response.body = 'Error: ' + err;
  console.log('error: ' + err);
}
```

***

### Sample Code 8 - Get additional stored documents

The following script gets the merge-pages-pdf additional data (the result of a Merge PDF pages=activity) of a certain document and returns that pdf to the browser.

```javascript
try {
  var documentInfo = straatos.getDocumentInfo(straatos.documentId);

  // Return only the additionalData objects with a merge-pages-pdf key
  var additionalDataObj = documentInfo.additionalData.filter(function(additionalData) {
    return additionalData.key == 'merge-pages-pdf';
  });

  if (additionalDataObj && additionalDataObj.length > 0) {
    var mergeUrl = additionalDataObj[0].url + '?w=' + straatos.webServiceKey;
    straatos.ajax({
      url : mergeUrl,
      dataType : 'binary'
    }).done(function(pdfRes) {
      response.body = pdfRes;
      response.headers['Content-Type'] = 'application/pdf';
    });
  } else {
    response.body = 'No merge-pages-pdf data found';
  }
} catch(err) {
  response.body = 'Error: ' + err;
  console.log('error: ' + err);
}
```

***

### Sample Code 9 - Uploading a PDF as 'additional data'

This Script does not show the pdf in the browser, but it uploads the pdf as additional data with a different key, in this case, binary-test-pdf.

```javascript
try {
  var documentInfo = straatos.getDocumentInfo(straatos.documentId);

  var additionalDataObj = documentInfo.additionalData.filter(function(additionalData) {
    return additionalData.key == 'merge-pages-pdf';
  });

  if (additionalDataObj && additionalDataObj.length > 0) {
    var mergeUrl = additionalDataObj[0].url + '?w=' + straatos.webServiceKey;
    straatos.ajax({
      url : mergeUrl,
      dataType : 'binary'
    }).done(function(pdfRes) {
      // Add the document as Additional Data
      var output = straatos.addAdditionalData(_documentId, pdfRes, '.pdf','binary-test-pdf');
      console.log('uploaded document link: ' + JSON.stringify(output));
      response.body = 'File uploaded!';
    }).fail(function(jqXHR, error){
      response.body = 'An error occurred: ' + error;
    });
  } else {
    response.body = 'No merge-pages-pdf data found';
  }
} catch (err) {
  response.body = 'error: ' + err;
  console.log('error: ' + err);
}
```

***

### Sample Code 10 - XML without namespaces

```javascript
var xmlDocument = straatos.newXMLDocument('root');
var rootElement = xmlDocument.documentElement;
rootElement.addAttribute('attr', 'attribute value');

var element1 = rootElement.addElement('element');
element1.text = 'element value 1';

var element2 = rootElement.addElement('element');
element2.addAttribute('elementAttr', '25');
element2.text = 'element value 2';

console.log(xmlDocument.xml);
console.log('xpath string attr: ' + rootElement.stringValue('@attr'));
console.log('xpath string query by attr: ' + rootElement.stringValue('element[@elementAttr = "25"]'));

var elements = rootElement.selectElements('/root/element');
elements.forEach(function (element, index) {
  console.log('element at index ' + index + ': ' + element);
});
```

***

### Sample Code 11 - XML with namespaces

This script shows how to create a simple XML document with one namespace with a single prefix used on all elements and attributes.

```javascript
var xmlDocument = straatos.newXMLDocument('ns:root', 'https://www.cumuluspro.com/api/1.0');
var rootElement = xmlDocument.documentElement;
rootElement.addAttribute('ns:attr', 'attribute value', 'https://www.cumuluspro.com/api/1.0');

var element1 = rootElement.addElement('ns:element', 'https://www.cumuluspro.com/api/1.0');
element1.text = 'element value 1';

var element2 = rootElement.addElement('ns:element', 'https://www.cumuluspro.com/api/1.0');
element2.addAttribute('ns:elementAttr', '25', 'https://www.cumuluspro.com/api/1.0');
element2.text = 'element value 2';

console.log(xmlDocument.xml);
console.log('xpath string attr: ' + rootElement.stringValue('@ns:attr', { 'ns': 'https://www.cumuluspro.com/api/1.0' }));
console.log('xpath string query by attr: ' + rootElement.stringValue('ns:element[@ns:elementAttr = "25"]', { 'ns': 'https://www.cumuluspro.com/api/1.0' }));

var elements = rootElement.selectElements('/ns:root/ns:element', { 'ns': 'https://www.cumuluspro.com/api/1.0' });
elements.forEach(function (element, index) {
  console.log('element at index ' + index + ': ' + element);
});
```

***

### Sample Code 12 - Securing the interact script

When you create an interact script, it is open to the web and anyone can access it. A webservice key can be used to secure it for server-to-server interaction.

A webservice key cannot be used to secure the interact API when it is called from a website. The following script shows how an existing authenticated session can be used to check the authentication and roles.

This script assumes that the authentication took place outside of the interact API, for example via the MyHome Login. The interact script below could then be called from a Custom UI.

The session ID must be given as part of the header when calling from the custom Ui. In this script, we also want to check if the user has the right to do the action. As a result, if the user has that role, the calling action will be checked. For example, if a user wants to submit a task, we want to see if the user has the role 'New Job' assigned to him.

```javascript
//The interact API is looking for the 'submitTask'
if (activityName == 'submitTask') {
  try {
    var userId = straatos.validateSession(request.headers['X-Session-Id']);
    if (userId > 0) {
      var reqBody = JSON.parse(straatos.getString(request.body));
      var authRoles = straatos.adapter.getAccount({id: userId}).Roles;
      var authOk = false;

      authOk = authRoles.some(function(record){
        return record.Name === reqBody.wfstep;
      });

      if (authOk == true) {
        straatos.messageWorkflow('Production Line Process', reqBody.wfstep, [reqBody.taskId], {
          'taskListData': JSON.stringify(reqBody.taskListData),
          'taskDetails': JSON.stringify(reqBody.taskDetails),
          'action': reqBody.action
        });
      } else {
        response.body = '';
        response.status = 401;
      }
    } else {
      response.body = '';
      response.status = 401;
    }
  } catch(err) {
    console.log('Error: ' & err.message);
    response.status = 501;
    response.body = err;
  }
}
```

***

## FAQs

<details>

<summary>What are the usual challenges when two applications try to interact via web services?</summary>

Each application has its own set of web services with its own parameters, headers, body requirements. The challenge is to make them talk to each other.

There are three ways to make that happen:

* 3rd party application makes changes to their push web service API calls.
* Straatos makes changes to its API definitions.
* Use of a 3rd party web service (or Platform) that makes the two web service calls to talk to each other (example: Zapier, Mulesoft).

</details>

<details>

<summary>What are the challenges of traditional approaches?</summary>

* Knowledge & skills to change the API:
  * Changes affect other users of the web service.
  * 3rd party product which can not be changed or requires the vendor to make changes.
  * Effort and cost to make the changes.

* Changes affecting other users:
  * Duration, cost, and effort to develop a customer-specific web service (days to weeks).
  * Agility to change Webservices.
  * No customer self-service to change the Webservices.

* 3rd Party Platform (such as Zapier/Mulesoft).

* Different geolocation:
  * Not the feature set required.
  * Additional subscription/cost.
  * Additional service/company.

* Dedicated web service.
  * Effort & cost to build an entire/independent web service.
  * Hosting & monitoring of the web service
  * Code maintenance
  * Extensive testing.

</details>

<details>

<summary>What incoming web service calls are supported?</summary>

* The Straatos Interact API supports POST and GET calls.
* All parameters, header, and body information are passed to the Interact Script and can be used in the script to determine what to do with the incoming call.

</details>

<details>

<summary>Can more than one web service call be defined?</summary>

Yes, there is no limit on the number of different web service calls that can be defined in a single Straatos Interact Script.

Example for 3 web service calls:

* CreateTask.
* ForwardTask.
* RetrieveTaskInfo.

</details>

<details>

<summary>Security: how does a web service call get authorised?</summary>

The security can be built into the Straatos Interact Script. Options:

* No authentication: open web service.
* Web service Key/API Key: check the key in the script.
* OAuth2:&#x20;
  * Use ajax to obtain tokens and validate outside Straatos.

Authentication can be as secure and restrictive as needed.

</details>

<details>

<summary>Is data between web service calls encrypted?</summary>

Yes, all communication uses SSL encryption.

</details>

<details>

<summary>Can payload encryption be used?</summary>

Yes. The Interact Script can decrypt incoming encrypted payloads (if needed) or pass encrypted data through the workflow. Decryption and handling depend on processing needs.

</details>

<details>

<summary>What is Organisation ID?</summary>

The Organisation ID is a unique identifier that defines your organization and is used as part of the request URL when consuming the API.

How to find your Organisation ID:

1. Log in to the CumulusPro Admin Panel with your credentials. The CumulusPro Admin dashboard will appear.
2. In the dashboard, click Create Organisation.

{% hint style="info" %}
If the organisation is already available, please proceed to step 4.
{% endhint %}

3. Select the desired template. and click Next.
   1. The new organisation will appear on the dashboard.
4. From the dashboard, click the newly created organisation. A new dashboard will appear.
5. Click the organisation settings to view the organisation details. The organisation Settings page contains the Unique ID and all relevant information about the organization.

</details>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.cumuluspro.net/developer-guide/straatos-api/straatos-interact-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
