Content properties in the REST API

What are content properties?

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

Content properties are accessible both by Java and REST APIs.

Query content properties with CQL

You can use CQL to query content properties in your Confluence instance. For example, a plugin can store the number of likes on a page in a content property. You can create an index schema module for that property, and then you can query the values to see how many pieces of content have more than 20 likes.

GET, POST, and DELETE content properties

GET 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.

1
2
# 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

POST new content properties

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 a structured JSON.

1
2
3
4
5
6
7
8
9
10
11
12
13
# 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 admin@example.com",
    "content": {
        "likes": 5,
        "tags": ["cql", "confluence"]
    }
}
 }' http://localhost:8080/confluence/rest/api/content/12345/property

DELETE content properties

If you need to delete content properties, you can perform a DELETE on the endpoint.

1
2
# 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 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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# fetch properties at the same time as fetching content, note the expand=metadata.properties.myprop
curl -u admin:admin -X GET 
    "http://localhost:8080/confluence/rest/api/content/12345?expand=metadata.properties.myprop" | 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 admin@example.com",
                    "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 is 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 are disabled. In the case of offending keys, an appropriate log message is 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.

For an example, see the JSON document and its index schema later on this page.

Example of content property value.

1
2
3
4
5
6
7
8
9
{
    "id": "507f1f77bcf86cd799439011",
    "editDate": "2000-01-01T11:00:00.000+11:00",
    "description": "If you have any questions please address them to admin@example.com",
    "content": {
        "likes": 5,
        "tags": ["cql", "confluence"]
    }
}
Extraction definition for a P2 pluginExtracted value
<extract path="id" type="string" />"507f1f77bcf86cd799439011"
<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

To access an embedded field in a document, use dot notation as shown in the following example. 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:

atlassian-plugin.xml

Example of P2 add-on index schema definition

1
2
3
4
5
6
7
8
9
10
11
<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>
    <key property-key="metadata">
        <extract path="content.tags" type="string" />
        <extract path="content.likes" type="number" />
    </key>
</content-property-index-schema>

atlassian-connect.json

Example of connect add-on index schema definition.

1
2
3
4
5
6
7
8
9
10
11
12
13
"confluenceContentProperties": [{
    "name": {
        "value" :"Attachments index",
        "i18n": "attachments.index"
    },
    "keyConfigurations": [{
        "propertyKey" : "attachments",
        "extractions" : [{
            "objectName" : "id",
            "type" : "string"
        }]
    }]
}]

Note that index schemas for connect were not 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

TypeDescriptionSupported CQL operators
stringEntire 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, =, !=
textExtracted value will be tokenized before indexing, allowing searching for a particular words.~, !~
numberExtracted number will be indexed as a double value for efficient range filtering and sorting.<, , ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object]
dateTwo 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.<, , ,[object Object],, ,[object Object],, ,[object Object],, ,[object Object]

Querying with CQL

You can address indexed content properties in a CQL query using the content.property field handler. Any content that contains content properties matching the query is returned in the results.

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

Examples of CQL queries on content properties.

1
2
3
4
content.property[attachments].editDate >= 2001-01-01
content.property[attachments].description ~ "questions"
content.property[metadata].content.tags IN ("cql", "help")
content.property[metadata].content.likes <= 5

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

Legend

SymbolMeaning
KEYThe key of the content properties you search.
PATHThe path to the value you'd like to search in the JSON document (use dot notation for embedded fields).
OPERATOROne of the supported CQL operators for the field type.

Read also