Our REST principles

This page outlines how we use REST in peace in the KEEP API. Not familiar with REST, check the tutorial

Pragmatism vs. Principle

We try to stick to the REST principles, but don’t let principles get in the way of pragmatic solution. You are free to disagree.


Our design goal here is to produce an API that is understandable and usable for a general developer audience, who might or might not have prior exposure to Domino terminology. Also we strive for freedom of choice for tools and methods, so you don’t need to suffer Domino Designer or Domino Admin client (You are free to disagree).

Methods used

These are the methods used in KEEP. Each method call has a corresponding named operationId. We tried to be as consistent as AHAD suffering developers could be.

For collections we use, as far as practical, plural names for resource parts, while individual resource are called with singular names. Deviating from an observed practise we don’t have POST methods for resource creation. So instead of POST /somepath/resources we use POST /somepath/resource to create one new unit of a resource.

This leaves us the option to extend the API for bulk creation at a later point in time.


Retrieve one resource or a collection of resources. Never changes data.

Successful GET returns HTTP 200

  • when retrieving a single resource (e.g. one document) the operationId start with get
  • when retrieving a collection the operationId start with fetch


This is the most flexible verb we use. It is used for:

  • Creating resources
  • Sending queries (DQL anyone)
  • Triggering actions (e.g inline script, run agents etc)
  • Authentication (which one could define as I query, if I can get in here

Successful POST returns HTTP 201 for resource creation and HTTP 200 for other operations. For operations that run asynchronously can return HTTP 202

  • The operationId for POST requests that create resources start with create
  • The operationId for POST requests that send queries start with query
  • The operationId for POST requests that revolve around authentication start with auth
  • The operationId for POST requests that run or execute actions start with execute
  • The operationId for POST requests that generate results start with generate


Updates an existing resource, completely replacing the server side information with data provided in the PUT request. The request must have the identifier in the path or query to clearly point to a single resource.

Successful PUT returns HTTP 200

  • The operationId for PUT requests start with replace or replaceCreate


Deletes an existing resource, completely. The request must have the identifier in the path or query to clearly point to a single resource.

Successful DELETE returns HTTP 200

  • The operationId for DELETE requests start with delete


Updates one or more resources on the server. The PATCH payload is NOT a replacement object (or collection), but a set of instruction what needs to change. E.g. a list of unids to update read status or a set of names to remove from an item.

You need to check the documentation of the individual patch method for details

Successful PATCH returns HTTP 200

  • The operationId for PATCH requests start with update

OperationId, Tag, Config and Class Names

The operationId gets mapped into a class name on Keep. The operationId gets the first letter in uppercase as class name within the context of the specific package. The other key piece of information from the OpenAPI spec is the tag. This is used to match against the config, to get the package name to use for the NSFHandler.

Pattern: Package.OperationId

The configuration) defines where to find the package.

WebHandler: Note the version mapping to this OpenAPI file in “versions” parameter in the config. Look under the “RestAPI.versions” parameter for this version.and look for the “package” parameter. If there is no class with the operationId in that package, the class in the “defaultClass” parameter will be used. Example: getAnswerToAllQuestions, package set as com.hcl.domino.keep.handlers.experimentalv0 -> com.hcl.domino.keep.handlers.experimentalv0.GetAnswerToAllQuestions.

NSFHandler: Look at the JSON objects under the “verticles” parameter in the config, and find the tag for this OpenAPI endpoint. This will give the package name. Example: getAnswerToAllQuestions with tag experimental, which has package name set as com.hcl.domino.keep.experimental -> com.hcl.domino.keep.experimental.GetAnswerToAllQuestions.