Confluence Rest API V2 - Struggling to create a page with the new editor

Hey Dev Community,
I’m running into a bit of a head-scratcher with the new Confluence API and thought I’d reach out to all of you for some help.

Previously, we could create a page using the editor v2, by sending some metadata with the post request on this path

With API V2 things have changed, and the tricks we used doesn’t work anymore :cry:
It seems impossible to post a page with editor v2 with the page api.
Am I missing something, or is it the API ?

Can you share the request body you have used? When I create a page with /wiki/api/v2/pages and the following request body, it uses the v2 editor by default:

{
  "spaceId": "...",
  "status": "current",
  "title": "API page",
  "parentId": "...",
  "body": {
    "representation": "storage",
    "value": "Created with the v2 API"
  }
}

This is the editor content property of the new page:

{
  "id": "...",
  "key": "editor",
  "value": "v2",
  ...
}

Yes sure

{
    "spaceId": "...",
    "status": "current",
    "title": "Interesting page title",
    "parentId": "...",
    "body": {
        "representation": "storage",
        "value": "some html stuff"
    }
}

So basically it’s the same payload except for the body value which is some encoded HTML. Maybe this is it, I’ll look into it.

Thank you for your response, by the way.

It appears that the solution to my scenario involves sending the inner content of the HTML body rather than the body as a whole.

So instead of sending:

{
    "spaceId": "...",
    "status": "current",
    "title": "Interesting page title",
    "parentId": "...",
    "body": {
        "representation": "storage",
        "value": "<body><p>The page content</p></body>"
    }
}

We’ll have to send:

{
    "spaceId": "...",
    "status": "current",
    "title": "Interesting page title",
    "parentId": "...",
    "body": {
        "representation": "storage",
        "value": "<p>The page content</p>"
    }
}

You can force the legacy editor (v1) or the new editor (v2) by setting/updating the “editor” content property.

You cannot set content properties with the V2 REST API (as far as I know) during page creation. Therefore, you have to create the page first and then check if the “editor” property already exists. If it does, update it; otherwise, create it.

I believe this to be the better solution if you want to force the editor choice. Many other HTML tags, besides <body>, can trigger the legacy editor. Additionally, Confluence might change their legacy-detection code in the future.

Here is some pseudo-code:

// Step 1: Create the page
page = post("https://{your-domain}/wiki/api/v2/pages", {
  "spaceId": "...",
  "status": "current",
  "title": "Interesting page title",
  "parentId": "...",
  "body": {
    "representation": "storage",
    "value": "<p>The page content</p>"
  }
});

// Step 2: Search for the "editor" property
search_for_editor_properties = get(`https://{your-domain}/wiki/api/v2/pages/${page.id}/properties?key=editor`);

if (search_for_editor_properties.results.length === 0) {
  // Step 3: If the editor property does not exist, create it
  post(`https://{your-domain}/wiki/api/v2/pages/${page.id}/properties`, {
    "key": "editor",
    "value": "v2"
  });
} else {
  // Step 4: If the editor property exists, update it
  const editor_property = search_for_editor_properties.results[0];
  put(`https://{your-domain}/wiki/api/v2/pages/${page.id}/properties/${editor_property.id}`, {
    "key": "editor",
    "value": "v2",
    "version": {
      "number": editor_property.version.number + 1
    }
  });
}

So my current process is:

  1. Create a draft
  2. Set the editor property (using the method above)
  3. Set the content
  4. Publish

This works very reliably but it is a pain that I now need to make multiple calls with the V2 REST API for something that I was able to do with one call with the old V1 API. Together with all the retry logic I have, this is very reliable but also very cumbersome. I’m just lucky that in my application, execution time isn’t really an issue.

Hey man I know this is old but thank you so much I was struggling so hard with this old editor problem cause I’m passing the body on a HTML, and I fund another problem if u pass a very large HTML, it triggers the old editor, but this approach works flawless.

Thanks for the workaround of setting the property via additional API calls. It’s sad that this is necessary and I hope Atlassian will fix their V2 API for page creation.

I am struggling to get the editor version of existing page. These are legacy pages that may or may not be converted to the Cloud editor. But I get a 404 error when I try what you suggest.

404 Client Error: Not Found for url: https://{domain}/wiki/api/v2/pages/113541121/properties?key=editor

Its not a unauthorised error… (I also believe I have all the token scopes assigned that I need)

Ran into very similar issue with a KB management script.

Reproducible cause: pages created via the REST API in storage format are treated as legacy content unless you explicitly set the “editor” content property to v2.
Opening such a page in the Cloud editor converts it, and that conversion rewrites every attachment reference to UNKNOWN_ATTACHMENT - images and attached PDFs stop rendering.

Matched-pair test on Confluence Cloud, two pages created by the same script, identical body and identical two image attachments.
The only difference was the editor property.

  • Page A - no editor property, which is the default for REST-created pages. Opened in the editor, the images immediately displayed as broken. The stored body was still intact at that point, so merely opening the editor does no permanent damage. On save, both refs were written to storage as ri:filename=“UNKNOWN_ATTACHMENT”, permanently.
  • Page B - POST /rest/api/content//property with {“key”:“editor”,“value”:“v2”} right after creation. Same edit and same save, both refs intact, and the storage format was not rewritten.

Two details that cost us time:

  • Passing metadata.properties.editor in the CREATE payload is silently ignored. The property reads back 404 afterwards. It has to be POSTed to /content//property as a separate call.
  • The published Atlassian KB for “Unknown Attachment” attributes it to cross-page refs from copy/pasting images between pages. That is a different cause. Our affected pages had zero ri:page refs, and the refs were plain ri:filename on the same page.

Retrofitting the property onto existing pages is non-destructive.
It adds a property, does not change content, and creates no new version.
That protects pages already published by a script before anyone opens one in the editor.