ScriptRunner can extend the functionality of Atlassian products, such as Confluence and Jira Software. From creating pages or tickets within the script console to setting up jobs and listeners, ScriptRunner is an excellent add-on.
In our previous article, The ScriptRunner Showdown, we explored possible limitations of ScriptRunner for Atlassian’s Cloud products when compared to the capabilities available for their Server products. Essentially, Atlassian’s Server products allow for more actions than Cloud products, largely because Cloud products are restricted to the Cloud REST API while Server products have access to both the Server REST API and Java REST API.
Our script uses a simple example, but one that is likely to be at the heart of much more complicated scripts: create a page. To make things a bit interesting, and to diverge from the ‘copy page tree’ built-in script provided by ScriptRunner, we want the new page to appear under the home page of the target space page hierarchy. In our example script the space key is TESTSPACE.
Create a page script with ScriptRunner for Confluence Server

It turns out there are actually two approaches that can be used to create a page using ScriptRunner for Confluence Server: via the Java REST API components or using the Server REST API. We will demonstrate both approaches.
Using Confluence Server Java REST API Components
One way of creating a page in a space would be to use components from the Java REST API.

Confluence Server has been around for a while and there is plenty of documentation on the internet to assist with learning the broad scope of the Java REST API, whether through Atlassian community Q&As or documentation. This article will not provide any further background or explanation of the provided script example.
The following code example uses the PageManager and SpaceManager components found in the API to create a page in the space with key TESTSPACE:
import com.atlassian.confluence.pages.Page
import com.atlassian.confluence.pages.PageManager
import com.atlassian.confluence.spaces.Space
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.sal.api.component.ComponentLocator
def spaceManager = ComponentLocator.getComponent(SpaceManager)
def pageManager = ComponentLocator.getComponent(PageManager)
def spaceKey = "TESTSPACE"
def space = spaceManager.getSpace("${spaceKey}")
def homePage = space.getHomePage()
Page parentPage = pageManager.getPage(homePage.id);
Page page = new Page();
page.setSpace(space);
page.setParentPage(parentPage);
page.setTitle("Title of Page");
page.setBodyAsString("Body of page. Bolded text.");
parentPage.addChild(page);
pageManager.saveContentEntity(page, null, null);When creating a new page, the ‘set’ functions within the Page class (API 7.12.2 documentation) can be used to add values to the page being created. Recall that one requirement for this example is for the new page to be created below the homepage in the space page tree hierarchy. Therefore the new page must setParentPage as the homepage, and the homepage must add the new page as its child. This example does not care about the history of the new page so it can be saved with a context of null.
Using Confluence Server REST API
The Confluence REST API Documentation may not seem as extensive as the Java REST API, but for our comparison it will get the same job done. The Confluence Server Developer even includes an example on how to create a new page.

The following is the code to create a new page, using our requirements and the REST API:
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.confluence.spaces.Space
import groovy.json.StreamingJsonBuilder
import com.atlassian.sal.api.component.ComponentLocator
def spaceManager = ComponentLocator.getComponent(SpaceManager)
def server = 'YOUR SERVER BASE URL'
def authString = 'username:password'.getBytes().encodeBase64().toString()
def spaceKey = "TESTSPACE"
def space = spaceManager.getSpace("${spaceKey}")
def homePage = space.getHomePage()
def pageParams = [
title: "Title of Page",
type: "page",
space:[
key:"${spaceKey}"
],
ancestors: [
[id:homePage.id]
],
body: [
storage: [
value: "Body of page. Bolded text.",
representation: "storage"
]
]
]
def createPageResult = new URL("${server}/rest/api/content").openConnection() as HttpURLConnection
createPageResult.requestMethod = 'POST'
createPageResult.setRequestProperty('Authorization', "Basic ${authString}")
createPageResult.doOutput = true
createPageResult.setRequestProperty('Content-Type', 'application/json;charset=UTF-8')
createPageResult.outputStream.withWriter('UTF-8') { new StreamingJsonBuilder(it, pageParams) }
createPageResult.connect()
log.warn"${createPageResult.getResponseCode()} created Page ${pageParams.title} for Space ${spaceKey}"
//Close POST
createPageResult.disconnect()Using the Server REST API involves more set up or configuration, specifically, the script must specify:
- The base URL of the instance
- The credentials (username and password) of a user who has permission to create a page in the target space.
In the Adaptavist ScriptRunner for Confluence’s console, this code will create a page identical to the one made by the components script shared above.
Create a page script with ScriptRunner for Confluence Cloud

Adaptavist ScriptRunner for Confluence Cloud includes a few example code snippets which are helpful to kickstart your introduction to the Cloud REST API. The code below is similar to ScriptRunner’s Create page in space, with a few changes to fit this example. As with the previous code snippets, this creates a page in the Confluence space with key TESTSPACE.
def spaceKey = "TESTSPACE"
def createPageResult = post('/wiki/rest/api/content')
.header('Content-Type', 'application/json')
.body([
space: [
key: spaceKey
],
status: "current",
title: "Title of Page",
type: "page",
body: [
storage: [
representation: "storage",
value: "Body of page. Bolded text."
]
]
])
.asObject(Map).bodyInstead of requiring the base url and authentication be added into the console by the user, the post function applies the values associated with the Cloud instance. That’s great news as it means less work for the developer.
If you have seen the ScriptRunner console’s example, you may have noticed they use a body format view while this example has storage. Depending on what the body content of the page is will help determine which format should be used. The Confluence REST API states only one body format should be used, and it includes a list to choose from in its example. Definitions for the body formats can be found in the Server ContentRepresentation class.
What did we learn?
We have shown three possibilities to script creating a page in a Confluence space. By demonstrating a Server script that uses the Server REST API we were able to see how that is similar to what can be expected when migrating to the Cloud. We were also able to clearly see Server scripts based upon the Java REST API components will require considerable more re-development than ones using the Server REST API.
If you will continue to develop new scripts for Server, you should consider switching to the Server REST API as much as possible to reduce the effort required to convert the scripts when you migrate to the Cloud.
We have summarized our findings in the following table.
| Method | Create Page | User Requirements |
|---|---|---|
| Components | – Get and add Space – Set values – Get and add Parent Page – Add Child Page to Parent Page – Save configuration | – Space Key – Permission to access Space and add Page |
| Server REST API | – Get Space – Create parameters – POST parameters | – Space Key – Base URL – Username – Password – Permission to access Space and add Page |
| Cloud REST API | – Create parameters – POST parameters | – Space Key – Permission to access Space and add Page |
We know our example was very simple, but it does demonstrate key differences between the three approaches, what you can do in the short term, and how you can plan for the long term as you look towards your Cloud migration.
As part of your migration planning it is especially important to check if any components in a ScriptRunner script have an equivalent API call that can be made in Cloud. If there are none, then you may need to consider alternate designs and exploring other approaches, like Automation. Knowing what to expect and planning with that in mind will help smooth out your migration path.