Skip to content
OpenCms documentation
OpenCms documentation

Headless JSON API

The JSON API is a headless REST API for the delivery of CMS contents in the JSON format. It is suitable for modern frontend technologies such as single-page applications or progressive web applications.

A handler to explore and display all the contents available in an OpenCms installation. The folder handler allows to navigate the complete multi-site and multi-lingual tree of a website in any depth. On each level of the tree it informs about properties and attributes attached to a resource.

A handler to create detail views for individual contents. The content handler provides utility features for locale handling and linked contents.

Editors with OpenCms can create preconfigured content lists that collect items of a content type - or even mixed content types - taking into account various list options such as category filtering and sorting. The list handler allows to display such preconfigured lists with the possibility to dynamically change the configured list options by means of request parameters.

A handler to present a web page in the arrangement and formatting intended by the editor when a page was created. The page handler provides information about the arrangement of the contents on a web page as well as formatting and styling options of contents and content parts.

A basic security mechanism is provided to exclude content folders and content files as well as content properties that are not intended for the public.

  • The OpenCms JSON API is read-only for presentation purposes, content edition is not possible.
  • Only publicly available online contents without access restrictions are accessible.
  • There is no authentication mechanism yet to access offline contents or online contents with access restrictions.
  • The list handler is incomplete, e.g. it does not provide faceted browsing.

In order to experiment with the JSON REST API, there is a preconfigured OpenCms docker image with some React demo applications available.

Unlike with the demo docker image, the JSON API is not activated by default in a standard OpenCms distribution. This is because the JSON API makes all resources and resource properties of all sites publicly available.

Before activating the JSON API on a production server, you should consider the access policy.

In order to activate the JSON API, add the org.opencms.xml.xml2json.CmsJsonResourceHandler resource handler class at the end of the handler list in the opencms-system.xml configuration file.

<resourceinit>
    <resourceinithandler class="org.opencms.pdftools.CmsPdfResourceHandler" />
    <resourceinithandler class="org.opencms.jsp.userdata.CmsUserDataResourceHandler" />
    <resourceinithandler class="org.opencms.xml.xml2json.CmsJsonResourceHandler" />
</resourceinit>

If no access policy configuration file is given for the JSON resource handler, all resources and resource properties are publicly available. In order to restrict access, add a paramater access-policy with a path to an access policy file (path is in the virtual file system) to the resource handler.

<resourceinit>
    <resourceinithandler class="org.opencms.xml.xml2json.CmsJsonResourceHandler">
        <param name="access-policy">/shared/json-access.xml</param>
    </resourceinithandler>
</resourceinit>

The access policy configuration file has the following structure:

<json-access>
    <include>/path1.*</include>
    <include>/path2.*</include>
    <exclude>/path1.*</exclude>
    <exclude>/path2.*</exclude>
    <property-filter>(?i)^(?!.*(?:secret|api|password|key)).*$</property-filter>
    <cors>
        <allow-origin>*</allow-origin>
        <allow-methods>*</allow-methods>
        <allow-headers>*</allow-headers>
    </cors>
</json-access>
Parameter Description Default
include Access is granted only for resources matching the given regular expression. Access is granted for all resources if include is not present.
exclude Access is denied for resources matching the given regular expression. Access is granted for all resources if exclude is not present.
property-filter Property access is denied for properties matching the given regular expression. Access is granted for all properties except for property names containing "secret", "api", "password", and "key" if property-filter is not present
cors/allow-origin For each JSON response, the HTTP response header Access-Control-Allow-Origin with the given value is set. The HTTP response header is * if allow-origin is not present.
cors/allow-methods For each JSON response, the HTTP response header Access-Control-Allow-Methods with the given value is set. The HTTP response header is * if allow-methods is not present.
cors/allow-headers For each JSON response, the HTTP response header Access-Control-Allow-Headers with the given value is set. The HTTP response header is * if allow-headers is not present.
  • Resource. The resource type is the top level type of the JSON API. A resource can either be a file or a folder. For every resource requested, the JSON API responds with a resource wrapper containing metadata. See the section Resource Handler below for details about the JSON format.
    • Folder. Folder is a container for any of the types below (filecontentlistpageother).
    • File. File is either a content file or a file of some other type.
      • Content. The content type is the most relevant for the JSON API since it provides the actual website content. Whenever a content file is requested, a multi-lingual JSON wrapper with a defined inner content type is returned as described in section Content Handler below.
        • List. The list type is a special content type with no multi-lingual wrapper. It is a content configuration file that collects contents of any type according to user-defined filter and sort criteria.
        • Page. The page type is also a special content type with no multilingual wrapper. It provides display information to be used when rendering contents on a page. See the section Page Handler below.
      • Other. Files other than content files (images, audios, text files, binary files, etc.) can be streamed outside the JSON API. The JSON API in this case returns a resource wrapper only with metadata.

Each resource in OpenCms is available via a unique file system URI. The most relevant URIs are the following:

The JSON Endpoint URI

GET /json/?wrapper=false
{
  "shared": {},
  "sites": {},
  "system": {}
}

All JSON contents are available below the json endpoint. The JSON endpoint always returns the same three folders named sitesshared, and system.

  • sites contains all sites and sub-sites available in an OpenCms installation
  • shared is a folder for contents that can be shared by the sites
  • system contains a lot of OpenCms internal files, where only the content Schema files are relevant for the JSON API

Site and Sub-Site URIs

GET /json/sites/?wrapper=false&levels=3
{
  "alkacon": {
    "children": {
      ".content": {},
      "web": {
        "children": {
          ".content": {},
          "index.html": {}
        }
      },
      "intranet": {
        "children": {
          ".content": {},
          "index.html": {}
        }
      },
      "opencms": {
        "children": {
          ".content": {},
          "index.html": {}
        }
      }
    }
  }
}

The sites folder contains an arbitrary number of websites. Each site can have an arbitrary number of sub-sites. You can recognize site and sub-site folders by their child .content folder where all the contents of a (sub-)site live. Folders without a .content folder are usually no (sub-)sites but page levels.

The example shows a site called alkacon. The alkacon site has three sub-sites called webintranet, and opencms, identifiable by their .content folder.

Page URIs

GET /json/sites/{site}[/{sub-site}]/**/index.html

An index.html file inside a site or sub-site folder usually represents a page. Requesting an index.html file returns a page in a JSON format as described in the sections Page Handler below.

Sometimes, an index.html can be a redirect or a script. The JSON API resource wrapper informs about such special cases.

Content URIs

GET /json/sites/{site}[/{sub-site}]/.content/
{
  ".config": {},
  "article-m": {},
  "contact-m": {},
  "decoy-m": {},
  "event-m": {},
  "list-m": {},
  ...
}

You can find contents below the .content folders of sites and sub-sites.

Listing a .content folder gives an overview of the content types available for a site.

The example response shows some content types of OpenCms' standard template Mercury.

Content schema URIs

GET /json/system/modules/alkacon.mercury.template/schemas/?wrapper=false
{
  "article.xsd": {},
  "contact.xsd": {},
  "decoy.xsd": {},
  "event.xsd": {},
  "faq.xsd": {},
  "flexible.xsd": {},
  ...
}

OpenCms uses an easy to understand sub-set of the XML schema language to describe the models of content types.

The example response shows the Schema files of OpenCms' default template Mercury.

The JSON API currently supports the following request parameters:

  • content (boolean)
  • fallbackLocale (boolean)
  • levels (integer)
  • locale (string)
  • path (string)
  • rows (integer)
  • sort (enumeration)
  • start (integer)
  • wrapper (boolean)

Parameters have either boolean, integer, enumeration, or string values.

The wrappercontentlocale, and fallbackLocale parameters are available for the content type, the list type, the page type, as well as for the folder type.

Description

With the content parameter, additional contents can be embedded in a JSON response document. Depending on the actual handler, the content embedded can have different origins. For the Folder Handler, content is embedded for all children files of a folder in line with the already present resource wrappers. For the List Handler, the content parameter causes the JSON API to evaluate the list configuration and appends the resulting list contents at the end of the JSON document. For the Content Handler and the Page Handler, the content parameter searches for all contents that are linked to the requested content or the requested page and embeds the linked contents. The content parameter in the end means "show me as much content as possible". It is an utility parameter shifting the complexity of the various content relations (content as list result, linked contents, file contents, etc.) from the client to the API.

Shows and hides the resource wrappers in a JSON document of the JSON response. This is especially useful to optimize the size of large JSON documents that contain a large number of content and resource files. The resource wrapper and the content are two independent parts of a JSON response document that can be turned on and off independently of each other depending on the actual requirements.

A frontend usually is not interested in all the locales a content is available for but in the locale currently selected by the client. Thus, it is common practice to always select a single locale with the locale parameter. Just like the wrapper parameter, the locale parameter can significantly reduce the size of the response document.

It is common practice to always use the locale parameter in combination with the fallbackLocale parameter to avoid empty results, i.e., to always have some default locale content available in the response document

The other parameters are handler specific:

The Folder Handler has an additional levels parameter to define the depth of folder recursion

The List Request supports the startrows, and sort parameters for result sorting and result paging.

Boolean parameters evaluate to true if the parameter value is either "true", or empty, or not present:

  • ?{paramName}=true
  • ?{paramName}=
  • ?{paramName}

Boolean parameters evaluate to false only if the parameter value is set to false

  • ?{paramName}=false

If a boolean parameter is not present at all, an internal default value is assumed as described below.

Applies if the requested JSON URL targets to a resource with no special type, or more specifically, if the targeted resource is not a content, a folder, a list, or a page.

Request URI scheme

/json/{dir}/{resource}

No parameters are supported.

Property Description JSON Type
attributes Technical metadata about the requested resource. Object
attributes.lastModified Timestamp when the requested resource was last modified. Number
attributes.type The internal type of the requested resource. String
isFolder Whether the requested resource is a folder. Boolean
isXmlContent Whether the requested resource is a content. Boolean
link The absolute path of the requested resource relative to the site root. String
own_properties The properties directly attached to the requested resource. Object
requestParams Just repeats the request parameters and informs which default value is used for each parameter. Object
path The full absolute path of the requested resource including the path of the site. String
properties The properties of the resource itself plus the properties inherited from the parent and descendant folders. Object

JSON format

{
  "attributes": {
    "lastModified": 1628004683200,
    "type": "binary" 
  },
  "isFolder": false,
  "isXmlContent": false,
  "link": "/mercury-demo/.galleries/Downloads/OpenCms-is-just-fun.pdf",
  "own_properties": {
    "Title": "OpenCms is just fun" 
  },
  "path": "/sites/default/mercury-demo/.galleries/Downloads/OpenCms-is-just-fun.pdf",
  "properties": {
    "Title": "OpenCms is just fun",
    "Description": "An advanced OpenCms Mercury template demo site, brought to you by Alkacon Software.",
    "NavPos": "0.12",
    "NavStartLevel": "1",
    "NavText": "Mercury Demo EN",
    "NavText_de": "EN" 
  },
  "requestParams": {}
}

Applies if the requested JSON URL targets to a content, i.e., it targets not to a page or list.

Request URI scheme

/json/{dir}/{content}?locale={locale}&fallbackLocale={boolean}&path={path}&wrapper={boolean}
Parameters Default Value Description Dependency
[none]   Returns a JSON representation of an XML content along with a wrapper containing metadata.  
?locale={locale} [not set] If set, returns the localized part of the XML content only without the wrapper.  
?fallbackLocale={boolean} false If set to true, falls back to another locale if the locale selected by {locale} does not exist. locale
?path={path} [not set] If set, returns a fragment of a localized part of an XML content. locale
?wrapper={boolean} false if locale or path is set, true otherwise If set, overwrites the default value.
Property Description
[Resource Wrapper] Since the content type is a sub-type of the resource wrapper type, it inherits all properties of the resource wrapper as explained above.
en, de, [locale] Locale names. As a default, OpenCms has locales en and de configured. If there are more locales configured, the names of the
configured locales appear as first level properties in line with en and de, see [locale].
[Locale Content] Can be any content of any content type available in a template. For the Mercury template, this is type article-mcontact-m,
event-m, and so on. Locale contents may link other contents, see [full path to the linked content].
localeContent Is a wrapper element where the [Locale Content] appears if a specific locale is requested with parameter locale.
locales The list of locales the requested resource is available for.
linkedContents Contents may link other contents. If such linked contents exist for a requested resource, they appear as a map in
the linkedContents property with the [full path to the linked content] as the key of the map and the linked content itself as the value of the map.

JSON format

{
  [Resource Wrapper]
  "en": {
    [Locale Content]
    "Link": {
      "path": "[full path to a linked content]" 
    }
  },
  "de": {
    [Locale Content]
  },
  "[locale]": {
    [Locale Content]
  }
  "localeContent": {
    [Locale Content]
  },
  "locales": [
    "en",
    "de",
    "[locale]" 
  ],
  "linkedContents": {
    "[full path to a linked content]": [Content]
  }
}

Applies if the requested JSON URL targets to a folder.

Request URI scheme

/json/{folder}/?levels={number}&content={boolean}&locale={locale}&fallbackLocale={boolean}&wrapper={boolean}
Parameters Default Value Description Dependency
[none]   Returns a directory listing with all child directories and child files contained in {folder}.  
?levels={number} 1 For a given number of levels, returns a nested directory tree with all child directories and child files contained in {folder}.  
?content={boolean} false If set to true, embeds all XML contents inside the folder listing or the folder tree.  
?locale={locale} [not set] If set, embeds all XML contents but only the localized parts of the contents selected by {locale}. content
?fallbackLocale={boolean} false If set to true, falls back to another locale if the selected locale does not exist. locale
?wrapper={boolean} false if locale or path is set, true otherwise If set, overwrites the default value.
Property Description JSON Type
[folder name], [file name] For a requested folder resource, all child folders and child files are returned in the form of a map with the [folder name] or [file name]
as the key of the map and at least with the [Resource Wrapper] as the value of the map. With the content parameter, also the [Content]
can be embedded in the folder response for child files of type content.
Object
children If a child resource of the requested folder is a folder itself there may be a children property that recursively embeds the children of a child folder
of the requested resource. The children property appears if a value greater than 1 is choosen for the levels request parameter.

JSON format

{
  "[folder name]": {
    [Resource Wrapper]
    "children": {
      "[folder name]": {
        [Resource Wrapper]
      },
      "[file name]": {
        [Resource Wrapper]
        [Content]
      }
    }
  },
  "[file name]": {
    [Resource Wrapper]
    [Content]
  }
}

Applies if the requested JSON URL targets to a list.

Request URI scheme

/json/{dir}/{listconfig}?content={boolean}&locale={locale}&fallbackLocale={boolean}&start={number}&rows={number}&sort={sort}
Parameters Default Value Description Dependency
[none]   Returns the list configuration.  
?content false Evaluates the list configuration and appends the content list to the result along with list information.  
?locale={locale} [not set] If set, returns the localized part of the XML contents only without the wrapper. content
?fallbackLocale={boolean} false If set to true, falls back to another locale if the locale selected by {locale} does not exist. locale
?wrapper={boolean} false if locale is set, true otherwise If set, overwrites the default value. content
?start={start} 0 If set, returns a part of the list only, i.e., the list items starting at index {start}. content
?rows={rows} 600 If set, returns a part of the list only, i.e., the a maximum of {rows} list items. content
?sort={sort} [configured sort order] If set, overwrites the configured sort order; possible values are DATE_ASC, DATE_DESC, TITLE_ASC, TITLE_DESC, ORDER_ASC, ORDER_DESC.

The list response contains the list configuration and the list result. The list results appear when the content parameter is set to true.

Property Description JSON Type
List Configuration
Category, CategoryFolderFilter, CategoryMode Categories configured to restrict the list result. String
SearchFolder Folders configured to search contents in. Array
ShowExpired Whether to list expired contents. Boolean
SortOrder The configured default list sort order. One of DATE_ASC, DATE_DESC, TITLE_ASC, TITLE_DESC, ORDER_ASC, ORDER_DESC. Can be overwritten with the sort parameter. String
Title The internal name of the list. String
TypesToCollect Content types configured that shall be collected. Array
List Result
linkedContents Contents that are linked by one of the contents in the result list. Object
listInfo Information about the list result. Object
listInfo.numFound Total number of list items found. Number
list The contents found.

JSON format

{
  "Category": "",
  "CategoryFolderFilter": [],
  "CategoryMode": "OR",
  "SearchFolder": [
    {
      "link": "https://my-def-demo.alkacon.com/mercury-demo/.content/article-m/",
      "path": "/sites/default/mercury-demo/.content/article-m/" 
    }
  ],
  "ShowExpired": true,
  "SortOrder": "DATE_DESC",
  "Title": "Basic Blog List (with elaborate teasers)",
  "TypesToCollect": [
    "m-article:m/display/article-elaborate" 
  ],
  "linkedContents": {},
  "list": [
    {
      [Resource Wrapper]
      [Content]
    },
    {
      [Resource Wrapper]
      [Content]
    }
  ],
  "listInfo": {
    "numFound": 76
  }
}

Applies if the requested JSON URL targets to a page.

Request URI scheme

/json/{dir}/{page}?content={boolean}&wrapper={boolean}&locale={locale}&fallbackLocale={boolean}
Parameters Default Value Description Dependency
[none]   Returns a JSON representation of the of the page informing about the referenced contents and their structure.  
?content={boolean} false If set to true, expands all referenced contents and appends them at the end of the JSON document.  
?locale={locale} [not set] If set, appends all contents at the end of the JSON document, but only the localized parts of the contents selected by {locale}. content
?fallbackLocale={boolean} false If set to true, falls back to another locale for the embedded contents if the selected locale does not exist for an embedded content. locale
?wrapper={boolean} false if locale or path is set, true otherwise If set, shows the expanded contents with wrapper.

The page type is a tree with two nested types Container and Element.

Page is the root node of the tree model. It may contain one or more Containers.
Container is a wrapper for a collection of arbitrary elements in a defined order.
Element contains a content with additional formatting settings informing about how to display the content in this specific context.

Property Description JSON Type
Page
containers The list of containers the requested page contains. List
linkedContents linkedContents is the property where all the contents or model groups the requested page links to in its elements are embedded. List
Container
elements The list of elements this container contains. List
isNestedContainer Whether this container is a nested container. Boolean
isRootContainer Whether this container is a root level container. Boolean
name The name of this container. String
type A comma-separated list of type names that are allowed as children in this container. String
Element
formatterKey Formatter key of this element indicating how the content of this element should be displayed. String
path The full path of the content this element links to. The path link is resolved in the linkedContents
property of the page.
String
settings Additional styling information for content formatting such as CSS classes, margins or colors. Object

JSON format

{
  [Resource Wrapper]
  "containers": [
    {
      "elements": [
        {
          "containers": [],
          "formatterKey": "m/layout/group",
          "path": "/sites/default/.content/modelgroup/modelgroup-00001.html",
          "settings": {
            "addBottomMargin": "true",
            "fixedheader": "fixed",
            "showBreadcrumbs": "true" 
          }
        },
        {
          "containers": [
            [more containers and elements]
          ],
          "formatterKey": "m/layout/area-simple",
          "path": "/system/shared/mercury/template/layout-area/la_00001.xml",
          "settings": {
            "bgColor": "none",
            "bgSpacing": "none" 
          }
        },
      ],
      "isDetailOnlyContainer": false,
      "isNestedContainer": false,
      "isRootContainer": true,
      "name": "mercury-page",
      "type": "area" 
    }
  ],
  "linkedContents": {
    "/system/shared/mercury/template/layout-area/la_00001.xml": {
      [Content]
    },
    "/sites/default/.content/modelgroup/modelgroup-00001.html": {
      [Modelgroup]
    }
  }
}