# Confluence REST API v2 — Create page with atlas\_doc\_format representation

**URL:** <https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565>\
**Category:** Confluence Cloud\
**Tags:** rest-api-v2, confluence-cloud\
**Created:** [March 18, 2023, 9:42pm UTC](https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565 "2023-03-18T21:42:48Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![KingChungHuang](https://avatars.discourse-cdn.com/v4/letter/k/45deac/32.png) [@KingChungHuang](https://community.developer.atlassian.com/u/KingChungHuang)\
**Post date:** [March 18, 2023, 9:42pm UTC](https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565/1 "2023-03-18T21:42:48Z")

</div>

I’m trying to use the Confluence REST API v2 API to create a new wiki page whose body is in the `atlas_doc_format`. I can’t seem to get anything except a `400 Bad Request` response with a body of `Invalid message`. Does anyone have any suggestions on what I’m doing wrong with the request?

The POST request is being made to `https://(my org).atlassian.net/wiki/api/v2/pages`, with the following request body (formatted here for readability):

```json
{
  "spaceId": 9867790169,
  "status": "draft",
  "title": "Equipment Sales",
  "body": {
    "representation": "atlas_doc_format",
    "value": {
      "body": {
        "type": "doc",
        "content": [
          {
            "type": "paragraph",
            "content": [
              {
                "type": "text",
                "text": "foo 3"
              }
            ]
          },
          {
            "type": "heading",
            "attrs": {
              "level": 2
            },
            "content": [
              {
                "type": "text",
                "text": "Background"
              }
            ]
          },
          {
            "type": "paragraph",
            "content": [
              {
                "type": "text",
                "text": "bar 3"
              }
            ]
          }
        ],
        "version": 1
      }
    }
  }
}

```

The ADF content was generated using the [Python pyadf module](https://developer.atlassian.com/cloud/jira/platform/apis/document/libs/).

What part is causing the invalid message?

---

<div class="post-metadata">

**Author:** ![KingChungHuang](https://avatars.discourse-cdn.com/v4/letter/k/45deac/32.png) [@KingChungHuang](https://community.developer.atlassian.com/u/KingChungHuang)\
**Post date:** [March 19, 2023, 4:04pm UTC](https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565/2 "2023-03-19T16:04:52Z")

</div>

Figured out yesterday that the body value needs to be JSON encoded, not passed as the underlying object. The correct form is like the following (`value` has been abbreviated).

```json
{
  "spaceId": 9867790169,
  "status": "draft",
  "title": "Equipment Sales",
  "body": {
    "representation": "atlas_doc_format",
    "value": "{\"type\": \"doc\", \"content\": [{\"type\": \"paragraph\", \"content\": [{\"type\": \"text\", \"text\": \"foo 3\"}]}]}"
  }
}

```

---

<div class="post-metadata">

**Author:** ![shawn1](https://avatars.discourse-cdn.com/v4/letter/s/58956e/32.png) [@shawn1](https://community.developer.atlassian.com/u/shawn1)\
**Post date:** [March 29, 2023, 2:42am UTC](https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565/3 "2023-03-29T02:42:35Z")

</div>

what kind of encoding is this?

---

<div class="post-metadata">

**Author:** ![GerbenWierda](https://sea1.discourse-cdn.com/atlassiandeveloper/user_avatar/community.developer.atlassian.com/gerbenwierda/32/47477_2.png) [@GerbenWierda](https://community.developer.atlassian.com/u/GerbenWierda)\
**Post date:** [March 31, 2023, 2:56pm UTC](https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565/4 "2023-03-31T14:56:13Z")

</div>

Very weird. The `value` entry is a sort of ‘escaped’ JSON. The same problem happens when you try to _get_ the body of a page. You either get XML or you get this escaped JSON as a string. But no usable JSON.

---

<div class="post-metadata">

**Author:** ![KingChungHuang](https://avatars.discourse-cdn.com/v4/letter/k/45deac/32.png) [@KingChungHuang](https://community.developer.atlassian.com/u/KingChungHuang)\
**Post date:** [March 31, 2023, 3:15pm UTC](https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565/5 "2023-03-31T15:15:33Z")

</div>

It’s a JSON encoded string of the JSON serialized object for the ADF.

Given an ADF object, you’d serialize it to the JSON representation, then assign that string as the `value`.

As @GerbenWierda noted, the same thing happens when you get the body of a page in ADF format. You have to treat the body value as a JSON serialized value and decode it to get the actual object. That’s actually what clued me in to the need to do the opposite when creating/updating a page.

---

<div class="post-metadata">

**Author:** ![GerbenWierda](https://sea1.discourse-cdn.com/atlassiandeveloper/user_avatar/community.developer.atlassian.com/gerbenwierda/32/47477_2.png) [@GerbenWierda](https://community.developer.atlassian.com/u/GerbenWierda)\
**Post date:** [March 31, 2023, 3:31pm UTC](https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565/6 "2023-03-31T15:31:25Z")

</div>

That was the tip I needed. Looking into JSON.parse() now.

---

<div class="post-metadata">

**Author:** ![shawn1](https://avatars.discourse-cdn.com/v4/letter/s/58956e/32.png) [@shawn1](https://community.developer.atlassian.com/u/shawn1)\
**Post date:** [March 31, 2023, 10:54pm UTC](https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565/7 "2023-03-31T22:54:25Z")

</div>

@KingChungHuang Could you share some code to go from a regular JSON object to this escaped object?

---

<div class="post-metadata">

**Author:** ![GerbenWierda](https://sea1.discourse-cdn.com/atlassiandeveloper/user_avatar/community.developer.atlassian.com/gerbenwierda/32/47477_2.png) [@GerbenWierda](https://community.developer.atlassian.com/u/GerbenWierda)\
**Post date:** [April 1, 2023, 11:22am UTC](https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565/8 "2023-04-01T11:22:17Z")

</div>

I’ve turned that into a separate question for the community as I have the same question.

> [@How do I create a valid atlas\_doc\_format string from a JSON?](https://community.developer.atlassian.com/t/how-do-i-create-a-valid-atlas-doc-format-string-from-a-json/68105):
>
> If I get the body of a page through the API and I want it in JSON format, I have to ask for atlas\_doc\_format and I get the body as a string, which starts with: "body": { "atlas\_doc\_format": { "value": "{\"type\":\"doc\",... To use it I can get JSON.parse to transform it: "body": { "atlas\_doc\_format": { "value": { "type": "doc", ... My question is this: how do I get the value for this value: key back in the atlas\_doc\_format single string form with the e…

Answer given in the other thread. Multiple `JSON.stringify()`'s

---

<div class="post-metadata">

**Author:** ![KingChungHuang](https://avatars.discourse-cdn.com/v4/letter/k/45deac/32.png) [@KingChungHuang](https://community.developer.atlassian.com/u/KingChungHuang)\
**Post date:** [April 3, 2023, 3:59pm UTC](https://community.developer.atlassian.com/t/confluence-rest-api-v2-create-page-with-atlas-doc-format-representation/67565/9 "2023-04-03T15:59:26Z")

</div>

Here’s an extension of the Python example in the [Create page](https://developer.atlassian.com/cloud/confluence/rest/v2/api-group-page/#api-pages-post) documentation showing an ADF document being created and encoded.

In short, the key is to JSON encode the ADF body object and assign that as the body value in the request.

```python
import json

from pyadf.document import Document
import requests
from requests.auth import HTTPBasicAuth

url = "https://{your-domain}/wiki/api/v2/pages"

auth = HTTPBasicAuth("email@example.com", "<api_token>")

headers = {
  "Accept": "application/json",
  "Content-Type": "application/json"
}

doc = Document()
doc.paragraph().text("Hello, world!")

# This is the ADF document body as an actual object.
body = doc.to_doc()["body"]

# The key is to serialize the ADF body as JSON for the create/update request,
# not assign the unserialized object directly as the body value.
payload = {
    "spaceId": 15,
    "status": "current",
    "title": "Example",
    "parentId": 34,
    "body": {
        "representation": "atlas_doc_format",
        "value": json.dumps(body), # Serialize the ADF body as JSON.
    }
}

# The entire payload is then serialized as JSON for the create/update request.
payload_json = json.dumps(payload)

response = requests.request(
    "POST",
    url,
    data=payload_json,
    headers=headers,
    auth=auth
)

```

This also means that the reverse is true when getting a page in ADF format. You’d need to JSON decode the response, get the body value string, and then JSON decode that in order to get the ADF object.
