How to use the API

The actual API is (will be) documented mainly using Swagger. However, we have a standardized way of communicating with the back-end. This page is about some of our core principles.

All entities have their own base path. Time records, for example, have a base path /api/1.0/companies/cloudware/timeRecords. The base path is implied in the rest of this document.

Cloudware in the path shown above is the company code for the database you want to access, replace this with what is correct for your database. You will always find this in the URL when you are logged in to Moment.

CRUD - Create, Read, Update, Delete

  • Create: POST to /

  • Read a single entity: GET from /{id}

  • Read a list of entities: GET from /

  • Update: PUT or PATCH to /{id}. They both work the same way, but PATCH is a more logical method to use if you only want to update parts of an object, and thus only submit the changed parts.

  • Delete: DELETE from /{id}.


Moment uses an "includes" concept. This is done primarily to increase the speed of the requests. The main idea was taken from GraphQL: return only the data that is really needed. It:

  • works faster than the usual GET method

  • provides a standard way of getting additional metadata for requested data

  • helps us create pure inline-editing of single fields in our objects

How do includes work?

In some API requests you can specify which fields, parts of entities or what metadata you want get in the response.

Part - it is a group of fields that commonly uses together

Metadata - it is a data that contains additional information about entities that was return


  • Parts and metadata must be defined and implemented on back-end manually.

  • Fields within objects can be requested without any changes in the code.

  • The id field of all objects is always returned.

  • Fields of inner objects can be requested with .. Example: field will be returned as customerName.

  • Includes support Create (POST), Read (GET) and Update (PUT) methods.

Get a collection of objects

Here is an example request, asking for the base information in addition to currencyCode and metadata for the overviewPage, for offers:

GET <entities>/include/{parts:.+}

// Example 
GET /offers/include/base+currencyCode+metadata.overviewPage

// Response
    "content": [
        { "id": 1, "name": "Offer 1", "issueDate":"2018-01-01", "currencyCode": "USD", }, ...
    "metadata": {
        "totalSumInCompanyCurrency": 1726.50

POST/PUT entity

Here is an example request where we update the customer for an offer by POSTing a customer id. Using includes, we will get only a small portion of the customer info in return.

POST <entities>/include/{parts:.+}
PUT <entities>/{id}/include/{parts:.+}

// Example
PUT /offers/666999/include/
BODY { "customerId": 3333777 }

// Response
    "id": 666999,
    "customerId": 3333777,
    "customerName": "Richest AS"

Batch processing

Sometimes it's useful to do multiple things at once. For performance reasons, or because we want to keep all the actions within the same transaction, and make sure everything is rolled back if anything goes wrong.

Batch: POST to /batch, passing along an object containing all the instructions. The input JSON structure is as follows:

  "create": [object1, object2, ...],
  "update": {
    "id1": { object1 },
    "id2": { object2 },
  "delete": [id1, id2, ...]

Here are a few examples (posted to /batch):

  • Create multiple entities: {"create":[{"projectId":4598,"name":"First entry"},{"projectId":4598,"name":"Second entry"}]}

  • Update multiple entities: {"update":{"11362":{"name":"New name 1"},"11361":{"name":"New name 2"}}}

  • Delete multiple entities: {"delete":[11357,11356]}

Here is an example of the returned JSON after a successful POST:

   "created": [{
      "projectId": 4598,
      "name": "First entry",
      "projectMembershipId": null,
      "id": 11321
   "updated": [],
   "createOrderIntact": true


There are limits to amount of data that is returned. The result will then contain an attribute "limitWasExceeded". We do offer an option to get more data - to get this added the parameter "noLimit" and set this to true.

There is still a limit that can not be overruled. The maximum number of records to be returned is 30 000.

If the request returns more than this, the filter needs to be adjusted so that amount of records will be below this limit.

Last updated