Content Properties in the REST API

What are content properties?

Content properties are a key-value storage associated with a piece of Confluence content, and are one of the forms of persistence available to you as an add-on developer. Content properties free you from having to use your own data store, by allowing you to store up to 32KB of JSON with each piece of content (a page, blog post, or an attachment). If you need to store metadata about a piece (or pieces) of content, for example, this is a great way to do it.

Content properties are accessible both by Java and REST APIs.

Query content properties with CQL

You can now use CQL to query content properties in your Confluence instance. For example, a plugin could store the number of likes on a page in a content property, then by creating an index schema module for that property you can query the values to see how many pieces of content have more than 20 likes. See the section on the CQL Search Extension for more information.

GET, POST, and DELETE content properties

To retrieve any existing content properties for a piece of content, perform a GET on the endpoint /rest/api/content/{content_ID}/property.

GET content properties
# Retrieves content properties associated with a piece of content with ID 12345
curl -u admin:admin -X GET "http://localhost:8080/confluence/rest/api/content/12345/property" | python -mjson.tool


To add content properties to a piece of Confluence content, perform a POST to the same endpoint. The key in your content property can be an arbitrary string (like "myprop"), whereas the value must be structured JSON.

POST new content properties
# Stores a JSON document under the key "myprop" against content with ID 12345
curl -i -u admin:admin -X POST -H "Content-Type: application/json" \
-d '{ "key" : "myprop", "value" : 
    "id": "507f1f77bcf86cd799439011",
    "editDate": "2000-01-01T11:00:00.000+11:00",
    "description": "If you have any questions please address them to",
    "content": {
        "likes": 5,
        "tags": ["cql", "confluence"]
 }' http://localhost:8080/confluence/rest/api/content/12345/property

If you need to delete content properties, you can perform a DELETE on the endpoint /rest/api/content/<CONTENT_ID>/property/<KEY>.

DELETE content properties
# Removes JSON document associated with key "myprop from content with ID 12345
curl -i -u admin:admin -X DELETE "http://localhost:8080/confluence/rest/api/content/12345/property/myprop"

Fetch content properties as an expansion when retrieving content

Content properties are now available as an expansion on the content resource. This allows content properties to be retrieved in the same REST call as fetching the content itself. This expansion is available from any resource that returns content, including the CQL search resource.

GET content properties as an expansion on content
# fetch properties at the same time as fetching content, note the
curl -u admin:admin -X GET 
	"http://localhost:8080/confluence/rest/api/content/12345?" | python -mjson.tool
    id: "12345",
    type: "page",
    status: "current",
    title: "New in the platform team? Read me first",
    metadata: {
        _expandable: {
            currentuser: "",
            labels: ""
            properties: {
                myprop: {
					"id": "507f1f77bcf86cd799439011",
    				"editDate": "2000-01-01T11:00:00.000+11:00",
    				"description": "If you have any questions please address them to",
    				"content": {
        					"likes": 5,
        					"tags": ["cql", "confluence"]

CQL search extension

To allow searching of content properties using CQL, you can enable indexing of data stored as content properties by defining an index schema. You can define an exclusive index schema for each content property key; then, whenever a content property is saved, Confluence checks if a schema was defined for its key. If a schema exists, indexable values are extracted from content property values and stored in an index. There can only be one index schema definition for a content property key, so any duplicates will be disabled. In the case of offending keys, an appropriate log message will be available.

Index schema definition

When defining an index schema for content properties, you need to provide a set of extraction expressions and field type pairs, which are used to retrieve a specific value from a JSON document and transform it into the desired representation. Supported index field types are: string, text number, and date.

See the below JSON document and its index schema as an example:

Example content property value
    "id": "507f1f77bcf86cd799439011",
    "editDate": "2000-01-01T11:00:00.000+11:00",
    "description": "If you have any questions please address them to",
    "content": {
        "likes": 5,
        "tags": ["cql", "confluence"]

Extraction definition for a P2 plugin Extracted value
<extract path="id" type="string" />
<extract path="editDate" type="date" /> 1st of Jan 2000 00:00:00.000 UTC
<extract path="content.tags" type="string" /> An array containing "cql", "confluence"
<extract path="content.likes" type="number" /> 5

Use dot-notation to access an embedded field in a document (as shown below). After successful validation, all extracted values are stored inside an index and you can address them in CQL queries.

Putting it all together, here's a sample index schema definition:


Example P2 add-on index schema definition
<content-property-index-schema key="module-key">
	<key property-key="attachments">
		<extract path="id" type="string" />
		<extract path="description" type="text" />
		<extract path="editDate" type="date" />
	<key property-key="metadata">
		<extract path="content.tags" type="string" />
		<extract path="content.likes" type="number" />


Example Connect add-on index schema definition
"confluenceContentProperties": [{
    "name": {
        "value" :"Attachments index",
        "i18n": "attachments.index"
    "keyConfigurations": [{
        "propertyKey" : "attachments",
        "extractions" : [{
            "objectName" : "id",
            "type" : "string"

Note : Index schemas for connect have not been released in 5.7-OD-42

Field type doesn't only specify how data is stored in the index, but also determines which CQL operators are available in your query.

Supported index field types

Type Description Supported CQL operators
string Entire extracted value will be indexed as a single token, without any filtering. When extraction expression evaluates to a JSON array, each element will be indexed separately. Enables searching for an exact value, e.g. unique identifier. IN, NOT IN, =, !=
text Extracted value will be tokenized before indexing, allowing searching for a particular words. ~, !~
number Extracted number will be indexed as a double value for efficient range filtering and sorting. <, <=, =, !=, >, >= 
date Two representation are possible, either a String following the ISO 8601 datetime format, or a long value in the Unix time. Enables efficient range filtering and sorting. <, <=, =, !=, >, >=

Querying with CQL

Indexed content properties can be addressed in a CQL query using the field handler. Any content that contains content properties matching the query are returned in the results.

The query syntax is as follows:[<KEY>].<PATH> <OPERATOR> value

Examples of CQL queries on content properties[attachments].editDate >= 2001-01-01[attachments].description ~ "questions"[metadata].content.tags IN ("cql", "help")[metadata].content.likes <= 5

(info) Note the dot notation when referencing embedded fields like 'content.likes'


Symbol Meaning
KEY The key of the content properties you're searching.
PATH The path to the value you'd like to search in the JSON document (use dot notation for embedded fields).
OPERATOR One of the supported CQL operators for the field type.
Was this page helpful?

Have a question about this article?

See questions about this article

Powered by Confluence and Scroll Viewport