API Documentation – Main app

Introduction

API stands for Application Programming Interface. An API allows you to programmatically interact with certain parts of RESPONSUM and exchange information. RESPONSUM provides API endpoints for core functionalities/data that can be useful for certain automations and integrations with other (operational) systems/tools.

These API endpoints will be updated/extended over time, but we will make sure that they stay backwards compatible so that created integrations continue to work. If you have any questions or enquiries for new endpoints, let us know via support@responsum.eu.

Quick Start

  1. Make sure APIs are turned on for your tenant. They are disabled by default, so you may need to contact support@responsum.eu.
  2. Once enabled, you can go to settings > setup > my organization clicking through on the top level will allow you to find your “tenant key” in the properties
  3. Now you can find our documentation under settings > integrations > API documentation
  4. Create an API token by going to settings > integrations > API tokens
  5. There is some Node.JS JavaScript code examples available here: https://github.com/RESPONSUM-BE/RESPONSUM-api-example – You can use the tenant key + API token generated earlier to give it a go.
  6. You can find a diagram in our Help Center explaining the main concepts in RESPONSUM. This will help you understand our basic structure so you can easily find concepts back.
  7. Here’s a quick intro into some important concepts – you can read more in depth about it below.
    1. UUIDs: You can make your own UUIDs or generate some RESPONSUM-formatted ones using https://api.responsum.app/v1/[tenant key]/uuids/[amount] – If you generate your own UUIDs, please make absolutely sure they are 100% unique, there are libraries out there if you need them, don’t go math.random 🙂
    2. Link Objects: RESPONSUM does NOT use typical relation-based modeling. Links between items are objects to us.
    3. Versioning: Just about all RESPONSUM models are versioned. This means we track changes for everything. There are some specific APIs available to deal with this or request info about any object’s version history & approval
    4. Calculated fields: RESPONSUM server-side calculates a bunch of fields. It does that automatically. When fetching an object, we will also give you our calculated fields. You won’t be able to update them manually.
    5. Event-driven: Anything that happens in RESPONSUM (create, update, delete, version, …) starts out as an event. You can use webhooks to subscribe to all sorts of events. Essentially, anything that happens in RESPONSUM can be reacted to using webhook APIs.
  8. It’s always recommended to read the full manual before you head out. It’s a dangerous world out there and you don’t want to hurt yourself – but armed with this quick start, I hope you make it work. Best of luck out there!

Getting started

Ensuring the API is enabled for your tenant

By default, the RESPONSUM API is disabled on a tenant level and hidden in our UI.

To enable the API for your tenant, you will need to contact our support team via support@responsum.eu who can enable and also answer questions you might still have after reading the available documentation and who can bring you in contact with the right people for more technical questions, discussions or implementation requests.

All further documentation will assume that the RESPONSUM API has been enabled for your tenant.

Your tenant key

When using the RESPONSUM API you will be required to use your actual tenant key as it is defined in our system for every request. This tenant key can be found in the application by navigating to settings > setup > my organization and open the highest organizational unit there as this reflects your tenant.

In the tenant “Meta data” details (Two arrows down at the top of the sidepanel), you will find the read-only “Tenant key” field.

This tenant key was set when your tenant was created and unlike the tenant name, can not be changed and is unique to this specific tenant.

OpenAPI specifications for your tenant’s API

The RESPONSUM API you will be using is generated specifically for your tenant and includes any customizations (Custom fields, custom relations, Business rules…) that might have been made. As such, the models provided can differ between tenants.

For ease of integration, we provide a specification json file according to the OpenAPI Specifications, you can load this by replacing the [tenant key] in the following url with your own tenant key found earlier: https://api.responsum.app/v1/[tenant key]/spec.json.

We also provide a visual documentation based on this specification file to allow for some simple testing while getting familiar with the API, this can be found in our app if you navigate to settings > integrations > API Documentation.

The first request in that API documentation is also to get the open API specifications and is one of the only requests you can do without authentication.

Authentication & authorization

All functional requests to the RESPONSUM API expect and API token to be passed as part of the request. This functions as both the authentication (by checking the token itself) and authorization (by checking the permissions of the user account linked to that token) (the user permission level link).

All actions taken via the API using this token will also be logged as being done by the user linked to the API token, as such, you are impersonating that user by using the API token.

Creating an API token

API tokens can only be managed through our app by going to settings > integrations > API Tokens.

An API token consists of:

  • A name for your ease of recognizing it in the list and differentiating the tokens from each other;
  • A token string, generated for you and to be used in each request to the API;
  • A user permission level, linking to a user account that will be impersonated when using this API token. As such, if you want to grant or deny permissions to this API token, you do that by granting or denying them to the user account linked here;
  • An expiration date, if this is set, the token will no longer work after this date.

Once created, the token string in an API token should be available for use right away. If your token string is compromised for some reason, regenerating the token string and saving the updated API token will invalidate the old token string right away.

Passing API token with requests

Once you have a valid API token string, you can pass it to the RESPONSUM API by adding an extra header to your requests Api-Token the value of which is your API token string.

Utility requests

UUID’s

There are various standards for Universally Unique IDentifiers currently in use and the RESPONSUM API should accept most as our validation consists of:

  • At least 5 characters long
  • Only consists of the characters:
    • a to z: abcdefghijklmnopqrstuvwxyz
    • 0 to 9: 0123456789
    • dash: -

Further we expect the UUID to be unique, but will only do limited checking on this, in the sense that trying to create a new model or links with a UUID that already exists for that specific model or link will return an error.

RESPONSUM itself uses a variant of the cuid2 algorithm modified to be easier to recognize and to fit our preferred format.

To make it easier for you to use UUID’s that follow this RESPONSUM format, we added an API endpoint that you can use to generate between 1 and 1000 UUID’s that are guaranteed unique and indistinguishable from the ones generated internally by RESPONSUM.

Replace the tenant key and amount in https://api.responsum.app/v1/[tenant key]/uuids/[amount] and do a GET request with it, ensuring to include the Api-Token header and as return value you will get a JSON array containing the UUID’s as string values.

The example project contains an example operation that does this: https://github.com/RESPONSUM-BE/RESPONSUM-api-example/blob/main/src/operations/getUuids.ts

Links in RESPONSUM are handled a bit different than most common solutions out there, in that each link is stored as it’s own object in the link collection, referencing the various models that are linked together, instead of references on the models linking to other models.

Links are also never updated, they can only be created or deleted as changing a linked model is considered deleting the old link and creating a new link.

All links are based on various link definitions, some of these are hardcoded and some can be custom created by the user. When getting the link definitions using the GET https://api.responsum.app/v1/[tenant key]/link-definitions endpoint, you’ll get a JSON containing a large object, which can be seen as a dictionary of all link definitions.

An example snippet for reference:

{
  "stakeholder-stakeholderContact-contacts": {
    "stakeholder": {
      "modelType": "stakeholder",
      "oneOrMany": "one",
      "isRequired": false,
      "relationBehaviour": "reference-same-object"
    },
    "contact": {
      "modelType": "stakeholder-contact",
      "oneOrMany": "many",
      "isRequired": false,
      "relationBehaviour": "reference-same-object"
    }
  },
  <snipped-for-size>
}

A linkType is an unique descriptive key for this specific link definition. In this example you can see that each object key (“stakeholder-stakeholderContact-contacts”) is the specific link definition’s linkType.

A role is a descriptive key, unique within the link definition, to identify the various branches of the link definition. In this case, “stakeholder” and “contact” are the two roles, as you can see, these do not have to match the model type. Another example is for a self referencing link, these roles might be “parent” and “child”.

Also be aware that while most links only have two branches, more than two are allowed and we have at least one case already where we have three way links.

Under the role you have a branch definition, which describes some properties of this particular branch:

  • The modelType describes which modelTypes are allowed, this can be:
    • A single modelType
    • An array of modelTypes
    • The constant “all-models”
  • The oneOrMany describes if there should only be one link allowed to link to this model type & uuid combination, or if there can be many
  • The isRequired describes if this link is required on this side of the link. If true, every model of the type(s) defined in modelType should have at least one link of this linkType
  • The relationBehaviour is mainly used internally to decide what to do with this link when duplicating models.

Based on the above link definition, we can find the same back in actual links.

An example link object might look as follows:

{
  "uuid": "0fc0ea83-88df-49ec-a681-1ced0a6c0683",
  "type": "link",
  "linkType": "stakeholder-stakeholderContact-contacts",
  "links": [
    {
      "modelType": "stakeholder",
      "modelUuid": "55092a14-4d95-4665-ac50-eb687e535222",
      "role"     : "stakeholder"
    },
    {
      "modelType": "stakeholder-contact",
      "modelUuid": "ad95eded-3168-4a12-968d-456bc031af7e",
      "role"     : "contact"
    }
  ]
}

The uuid and type “link” properties are always present on each object to uniquely identify it.

The linkType matches to one of the link definitions, in this case the one in the link definitions example.

The links properties is an array of the various branches. The amount of items in this array will always match the amount of roles in the link definition, as for each role we expect a linked model.

  • The role matches one of the roles as defined in the matching link definition
  • The modelType matches one of the allowed model types for the matching link definition and role definition
  • The uuid then identifies which specific model of the given model type this link references

Further there can also be a metaData property that can contain a free form data object with some extra meta data about this specific link, though this is rarely used.

Most of the time you will get links as part of models, and similarly create or change links when creating or updating models.

A link property on a model, when filled in, will be considered the new list of links for that property, replacing any already existing links for that model’s property. As such, when adding a new link to a model, be sure to also include any existing links that you want to keep.

Next to this, there are also three endpoints to interact with links directly.

The GET https://api.responsum.app/v1/[tenant key]/links endpoint allows you to get all links filtered by several filters:

  • uuids, the uuids of the link objects
  • model-uuids, the uuids of the models referenced in the link objects
  • relation-names, the linkTypes of the link objects

These can be supplied as query parameters containing a json string array as values.

The POST https://api.responsum.app/v1/[tenant key]/create endpoint, while mainly used to create models, also accepts link objects and can thus be used to create new links.

The DELETE https://api.responsum.app/v1/[tenant key]/link endpoint allows you to directly delete one or more links for which you know the link object uuid.

Model requests

Al data in RESPONSUM is stored in models, as such, most of the API operations will be done towards these models.

Each model must have a type and uuid, both of which are required and cannot be changed after creation.

The type is one of our predefined models, such as “processing-activity” or “risk”.

Model definition

This refers to a model definition with all available fields, including the custom ones defined in the application. For type it will contain the expected type as a string, be sure to use these exact string values.

For basic fields it will contain their data type and if they are required or not.

For link fields, it will contain an array of link objects.

Listing models

For each model type, we have a separate GET endpoint in the API to get all or a filtered list of models for that type.

For filtering, you can add a uri encoded query parameter “param-filter” to the GET url that contains a JSON object with the filter. This filter has as property the name of the property you want to filter on and as value an array of all property values you want to match on.

For example, if you want to filter “advice” to find any models where the status is “new” or “ongoing”, you would create a json filter object as follows: {"status": ["new", "ongoing"]}. After that, uri encode it as the value for the param-filter query parameter, giving you GET request as follows: https://api.responsum.app/v1/[tenant key]/advice?param-filter=%7B%22status%22%3A%20%5B%22new%22%2C%20%22ongoing%22%5D%7D

You can also combine filters on multiple properties by adding extra properties to the json filter object, like so: {"status": ["new", "ongoing"], "isObsolete": [false]}. This will return an array of matching models or an empty array if no models are found.

The example project contains an example operation that does this: https://github.com/RESPONSUM-BE/RESPONSUM-api-example/blob/main/src/operations/getCountriesByFilter.ts

Getting a single model

For each model type, we have a separate GET endpoint in the API to get a specific model for that type, based on it’s uuid, just append the uuid to the model type url, giving you a GET request as follows: https://api.responsum.app/v1/[tenant key]/advice/raou8qtt-60od-n7t5-g8el-c0sy99r0ppag

This will return that single model or a 404 ‘no model found’ error.

To create models and links between those models, we have one generic POST https://api.responsum.app/v1/[tenant key]/create endpoint since we want to make it possible to create a set of multiple related models and the links between them in one go, to reduce the chance of partial sets due to failing validation or similar.

The create endpoint accepts an array of models, each of which should have the type, a uuid and any required properties for that model type.

For the link properties on the models you can also include an array of link objects, of which we will take the union across the provided models and insert those. This means that if you have two models which link to each other, our API only requires the link object connecting those two on one of the models to understand that it should be added, however adding it on both models won’t make a difference.

The example project contains an example operation that does this.

To update models and links between those models, we have one generic PATCH https://api.responsum.app/v1/[tenant key]/update endpoint since we want to make it possible to update a set of multiple related models and the links between them in one go.

The update endpoint accepts an array of models, each of which should have only the type, uuid and the fields being updated.

For the link properties on the models, these are once again an array of link objects, of which we will take the union across the provided models and then delete any links that are not part of this union, before adding any links in this union that are not yet in the database. This means that if you want to add a link to a model property, you should also include the link objects of the existing model property or these existing links will be deleted.

The example project contains an example operation that does this.

Model versioning

Most RESPONSUM models have versioning enabled, meaning that every change done to these models is recorded and these versions can be frozen and approved etc.

Getting all versions for a model

You can get all version changes for a given model with the following GET request: https://api.responsum.app/v1/[tenant key]/version/[model type]/[model uuid]. This will return both “unversioned” (Draft) and each frozen version with the extra info about that version such as the version status, who created the version, who approved it, etc.

Version lifecycle

Unversioned changes

All changes start as unversioned changes. Every time a model is created or updated, we record the previous and new value for the changed properties. Who and when made the change and what kind of operation it was.

The list of operations has some common values such as ‘create’, ‘update’, ‘delete’, ‘merge’, ‘import’, ‘history-restoration’ and ‘update-link’ but can also contain special values such as ‘V2-create’ for our legacy import and at any time new values can be added depending on future developments.

Freeze

At any time the changes for a model can be frozen with POST https://api.responsum.app/v1/[tenant key]/version/[model type]/[model uuid]/freeze which will create a new version with reviewStatus ‘frozen’ and include any unversioned changes that there where. If there where no unversioned changes, no new version will be created.

You can also provide a version name when freezing, but if none is provided, one will be calculated based on the currently existing versions.

At this point certain people with the right permission can already approve or reject this version, but the most important thing is that any new changes will be added as unversioned changes, but any changes in this version will never change.

Request approval

To get a version approved or rejected, you can request specific people to review it. For this you can PUT https://api.responsum.app/v1/[tenant key]/version/[model type]/[model uuid]/request-approval with a version uuid & “accountable user” uuid. This will trigger notifications for this person to review this version and either approve or reject.

Approve or Reject

You can also approve or reject versions through the API if the user linked to your token has sufficient permissions.

This can be done with the two PUT endpoints https://api.responsum.app/v1/[tenant key]/version/[model type]/[model uuid]/approve or https://api.responsum.app/v1/[tenant key]/version/[model type]/[model uuid]/reject, once again requiring the version uuid you want to approve or reject.

Webhooks

Sometimes you also want to be notified of models being created or updated, for this we have webhooks which you can configure by going to settings > integrations > webhooks.

For ease of use, webhooks can be enabled or disabled, only enabled webhooks will trigger calls.

The name is purely used for distinguishing the webhooks.

The give URL will be called with the given headers, this will be a POST request that contains a json body with the changeAction, modelType and uuids (an array of uuids).

You can select from the following change actions, only for selected once will the webhook be called:

  • ‘link-deleted’: when a link is removed from one or more of the properties
  • ‘link-created’: when a link is added for one or more of the properties
  • ‘item-deleted’: when the item is deleted
  • ‘item-meta-data-updated’: when calculated properties are updated, eg. last updated by, review status, etc.
  • ‘item-base-data-updated’: when the base properties are updated, eg. name, isObsolete, etc.
  • ‘item-created’: when the item is created

You can select the sub-module for which the webhook should trigger, this can be as refined as a single model type or as broad as every model in the application.

Based on our internal logic, you might receive multiple webhook calls for the same model type & uuid shortly after each other, after a user saves. Adding a link and setting a property for example will trigger an ‘item-base-data-updated’, ‘item-meta-data-updated’ and ‘link-created’ call.

Example application

https://github.com/RESPONSUM-BE/RESPONSUM-api-example

See the readme to get started, once you get it running and open http://localhost:3000 you should see something like this:

As you then do the various operations, you will see a log of the operations on the right side of the page.

You can also find all these operations in the src\operations\ folder

Was this article helpful?