Introducing Content State API

We’ve recently added a new feature to Confluence: the ability to add a Content State to pages. To complement this, we have added endpoints for Getting, Setting, and Removing Content States from content. Additional endpoints for getting admin space settings for content states, and seeing all available states for a piece of content have been added as well. See the changelog for details.


Hi @EmileGivental , can you change the category to #announcements?


@EmileGivental Where is the end-user documentation of the “Content State” feature? I was unable to locate it.

I’d like to learn what this REST API can be used for, how it creates value for the end-user?


Hi @aron.gombas,

The documentation can be found here:

As for what the feature itself is, we have this community post that demonstrates what it appears as in the UI:

The feature itself is being turned on slowly in production, and is currently available to 10% of users. It can be found in our UI in the editor above the page title.

I hope this answers your question.


@amardesich, I’m adding you to this conversation because I really think this is a good example of the challenges that we’re going to need to tackle with regards to comms & announcements. There are three posts on three different places regarding the content state:

The community post to announce the feature to the Atlassian end-users

The Content API in the change logs

Introducing Content State API

Obviously, the community post does not include API documentation for developer. The change logs do not refer to the actual feature announcement, but only to the API documentation, and the announcement on CDAC only refers to the change logs.

For the developer community, this means that we need to get information from three sources and ask a forum question here on CDAC to get more insights into what feature has been released.

In order for us to truly benefit from the features Atlassian develops & releases, and to expand upon those features in our products to help unleash the potential of every team, we need a unified approach to announcements.


Thank you @remie this is a great example for us to learn from and work to make it easier to get the full story in one place. I hope our upcoming efforts lead to fewer examples like these, but please continue to flag them as they arise.

I have now extensively worked with this API and it has been a very Atlassiany experience.

Here are some useful findings that I have found in the API but not in its documentation:

  • While each existing content state has an ID, it is possible to set the content state on a page without providing an ID. When not providing an ID, if any space or custom state is available that has the same name (case sensitive) and colour (case insensitive), that state is used. Otherwise a new custom state is created (if permitted). This means that multiple content states with the same name but different colours can exist.
  • The ID of an existing content state is a number. This number may be 0.
  • The “get available content states” API returns only the last 3 used custom states. This means that the current state of the page might not be listed in the returned list of available content states for the page. There seems to be no way to retrieve the information for a custom state that is not among the last 3 used ones (for example to show it in a content state picker), other than retrieving it from a page that is using that status.
  • The “get available content states” API returns spaceContentStates and customContentStates. While these can be empty arrays if none are available, they can also be undefined if the respective feature is disabled in the space settings.
  • Creating new content states will fail if the “custom states” feature is disabled in the space settings. This scenario can be detected by checking if the customContentStates is undefined.
  • The maximum length for a content state name is 20 characters. Attempting to create a state with a longer name results in an error.
  • While any colour can be specified for a content state, the ones available in the Confluence UI are B200, G200, Y200, R200, P200.

Hi candid, thanks for putting these here. All of these are completely correct, and we’ll add this information in some ways to the documentation. Also, we recently added an endpoint for getting custom states that will return all custom states ever made by the calling user. The documentation is here.

Thank you for your useful response, I was not aware of some of these endpoints and they are indeed exactly what I need.

However, I’m having trouble using the /content-states endpoint. As stated in the documentation, the endpoint is not available through AP.request(). This is very inconvenient, is there any reason for this? But I can also not access the endpoint from my backend using OAuth user impersonation. I am getting a 401 “Client must be authenticated to access this resource”. I verified that the /user/current endpoint returns the correct user when called with the same OAuth token. The /content-states endpoint seems to only work in the browser, where it is not really useful for my app.

Hi @EmileGivental ,
A great addition would be it the content state is expandable in a call like

It is expandable as

1 Like

Hi @candid ,
Thank you for the information. Do you know if it is documented?
It is also possible to query for and

Hi @EmileGivental are you able to provide a timeframe for when the docs will be updated with @candid’s extremely valuable comments?

I’m also a bit confused about how to “create” a content state, the API docs don’t mention that scenario but the release notes do.

Finally, why are they referred to as “states” in the API but “statuses” in the browser UI?

PS also does Atlassian have plans to expose APIs for the new Space Settings related to this feature? If not please can someone create a ticket in the right Jira instance and project at Atlassian and post a link here so I can vote/watch for that?

Hi @jbevan, the changes to the documentation got caught up in the backlog. Thanks for bringing them back up, and I’ll look to have them in by Monday 8/8.

In our UI, content states can be created in two ways. Space content states can be made and deleted in the settings under the content statuses submenu. Custom content states are made on the fly by typing in names and selecting a color while in the editor. The set page status button is found by hovering over the title, and once a status is set on the page, it can be found at the top of the page.

Via the API, space content states can not be made. They are considered as part of the space settings, and we did not want to expose changes to state settings via the API. Custom states are made by using the PUT /content/{id}/state and passing in a name and color. In all put cases, the type of state and states in general must be enabled.

In the backend, we already have content statuses (CURRENT, ARCHIVED, etc.) and we did not want a naming clash. However, the design of the project always intended for these to be called statuses for end users, thus the difference between API and UI naming.

Hope this helps!

Hi @EmileGivental ,
I’ve got a question about the usage of the API and UI.
Imagine we have a page we want to have reviewed. A group of reviewers reviews the latest version. When this specific page version is reviewed, the want to set the content state to “Reviewed”. However setting the content state changes the page version. And the new page version was not reviewed, it was the previous version.
In some regulatory processes the “Reviewed” status of a page is tied to a specific document version.
Any advice on how to handle this situation?

Hi @marc ,
I’m going to lay out how content states work with versioning, and then answer the question.

Content States can be tied to a draft, or a published version.

In the UI:

  • You can change draft content state by going in the dropdown and selecting a state. This state will only appear on the draft, and if you close the draft, you will see the old content state and old content. No new version of content is created.
  • You can change the published content state by hitting publish, and the draft content state will now become the published state, and the content in the editor will become the new published content. A new version of content is created, and the state that was the draft state, which just became the published state, is tied to this new version.

Via the API:

  • You can change the draft content state by calling the PUT /content/{id}/state?status=draft. This will not publish a new page, and is the same as the first bullet above.
  • You can change the published content state by calling the PUT endpoint with status=current. This will create a draft state property, and then also publish the page, with identical content to the previous version. This publish will ignore any content that has been changed in the current draft, and will only change the content state and uptick the version.

So, in your situation in the UI, when reviewers agree the page is REVIEWED, they can change the state and hit publish in the UI. What they see in front of them will become a new version, and only this new version will show as REVIEWED in the content history.

Via the API, if they are looking at the current published content and agree that it is REVIEWED, they can call PUT with the REVIEWED state and status=current. A new version with what they are seeing in front of them will be created, and be REVIEWED.

If they are instead working on a new draft, and this new draft is what is REVIEWED (whereas previous versions were not reviewed), then the API should call PUT with status=draft, and then a publish should be done independently. If you were to do this with status=current, then any changes made in the draft would not be reflected in the REVIEWED version of the page.

I’m sorry for the lengthy response, but I see the confusion with the API. We wanted state to be tied to versions, but we also wanted the API to be capable of creating a new permanent (view page) state. This meant that the API would need to create a new version of the page, but we didn’t want for the API caller to need to know what changes may have been made in the draft of the page, and inadvertently publish things that are not ready to be published.

1 Like

Hi @EmileGivental ,
Thank you for the explanatory response!
Now I understand the design of the feature better.
Our customers use Confluence differently. They first determine a final document version, and then review it. The document review is seen as document metadata, not as a change to the document itself.
We are going to test if we can reconcile these two approaches.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.