Confluence Server REST API Not working
Asked by Mamadou Barry:

I'm trying to use the rest API to create pages in my confluence instance, however, the API isn't working as intended.  

I tried with Js, postman, even python script, none work.

I got the 200 ok code but the response is in HTML and when I look at my confluence, there's no page created.

**JS**

<br />

const req = require('request')  
//This creates a page in a space.  
var username = "admin";  
var password = "admin";

var jsondata = {"type":"page",  
"title":"My Test Page",  
"space":{"key":"TEST"},  
"body":{"storage":{"value":"\<p\>This is a new page\</p\>","representation":"storage"}}};

req.post("http://localhost:8090/confluence/rest/api/content/", {  
'contentType': "application/json; charset=utf-8",  
'dataType': "json",  
'auth': {  
'user': username,  
'pass': password  
},  
data: {"type":"page",  
"title":"My Test Page",  
"space":{"key":"TEST"},  
"body":{"storage":{"value":"\<p\>This is a new page\</p\>","representation":"storage"}}},  
}, (err, httpResponse, body)=\> {  
if (err) {  
return console.error('upload failed:', err);  
}  
console.log('Upload successful! Server responded with:', httpResponse);  
});

Python
> # This script bulk generates spaces and pages in Confluence.
>
> import click  
> import grequests as greqs  
> import requests as reqs  
> from requests.auth import HTTPBasicAuth  
> from tqdm import tqdm  
> import itertools
>
> <br />
>
> SPACES_URL = "http://{hostname}:{port}/rest/api/space"  
> PAGES_URL = "http://{hostname}:{port}/rest/api/content"
>
> <br />
>
> @click.command()  
> @click.option("-u", "--username", default="admin", show_default=True, show_envvar=True, prompt=True)  
> @click.password_option("-p", "--password", default="admin", show_default=True, show_envvar=True, prompt=True)  
> @click.option("-h", "--hostname", default="localhost", show_default=True, show_envvar=True, prompt=True)  
> @click.option("-P", "--port", default=8090, show_default=True, show_envvar=True, prompt=True)  
> @click.option("-t", "--threads", default=8, show_default=True, show_envvar=True, prompt=True)  
> @click.option("-s", "--space-count", show_envvar=True, prompt=True)  
> @click.option("-c", "--page-count", show_envvar=True, prompt=True)  
> @click.option("-r", "--prefix", default="CONFLUENCE", show_default=True, show_envvar=True, prompt=True)  
> @click.option("-d", "--disable-progress", default=False, show_default=True, show_envvar=True, prompt=True)  
> def cli(username, password, hostname, port, threads, space_count, page_count, prefix, disable_progress):  
> global SPACES_URL, PAGES_URL  
> SPACES_URL = SPACES_URL.format(hostname=hostname, port=port)  
> PAGES_URL = PAGES_URL.format(hostname=hostname, port=port)
>
> space_count = int(space_count)  
> page_count = int(page_count)
>
> spaces_generator = (greqs.post(SPACES_URL,  
> json={"key": f"{prefix}SpaceStation{i}",  
> "name": f"{prefix}_Space{i}"},  
> auth=HTTPBasicAuth(username, password)) for i in range(space_count))
>
> spaces_reqs = greqs.imap(spaces_generator, size=threads,  
> exception_handler=lambda r, e: print("Request failed. Reason: " + str(e)))
>
> spaces_responses = \[\]  
> print(f"Generating {space_count} spaces...")  
> for _ in tqdm(range(space_count), disable=disable_progress):  
> try:  
> spaces_responses.append(next(spaces_reqs))  
> except:  
> # Silently ignore the exception  
> continue
>
> if len(spaces_responses) == space_count:  
> pages_reqs = \[\]  
> count = 0
>
> for response in spaces_responses:  
> # 200 OK (HTTP Status Code)  
> if response.status_code == reqs.codes.ok:  
> count += 1  
> space_key = response.json()\["key"\]  
> pages_generator = (greqs.post(PAGES_URL,  
> json={  
> "type": "page",  
> "title": f"{prefix}_Page{j}",  
> "space": {"key": space_key},  
> "body": {  
> "storage": {  
> "value": "\<p\>This is a new page\</p\>",  
> "representation": "storage"  
> }  
> }  
> },  
> auth=HTTPBasicAuth(username, password)) for j in range(page_count))
>
> pages_reqs.append(greqs.imap(pages_generator, size=threads,  
> exception_handler=lambda r, e: print("Request failed. Reason: " + str(e))))
>
> pages_reqs = itertools.chain(\*pages_reqs)  
> print(f"Generating {page_count} pages for each newly created space...")  
> for _ in tqdm(range(page_count \* count), disable=disable_progress):  
> try:  
> next(pages_reqs)  
> except:  
> # Silently ignore the exception  
> continue
>
> <br />
>
> if __name__ == "__main__":  
> cli(auto_envvar_prefix="CONF")  
>
> Is there anything i should do differenty? thank you


Answers:
author: Mamadou Barry
body: The endpoint I was using was the issue. In production, you should use this endpoint **http://localhost:8090/rest/api/content/,** but I was using this one **http://localhost:8090/confluence/rest/api/content/** which is used for development, so that was it.

Remember this:

For production use this endpoint **http://localhost:8090/rest/api/content/**

For development use this endpoint **http://localhost:8090/confluence/rest/api/content/**

comments: author: Dario B
body: Hi [@Mamadou Barry](/t5/user/viewprofilepage/user-id/2246246) ,

Please notice that the different endpoint has nothing to do with Development or Production environments but it depends on how you configured the **Context-path** in **server.xml** configuration file:

* if you leave an empty context path then the url to connect to Confluence is **http://localhost:8090/.**   
  To this url you have to add the REST API endpoint you are trying to call (in this case **/rest/api/content/** ). This seems to be the case for your Production environment:

  ```
  <Context path=""
  ```

* If the context path is configured to be any other string, like e.g., in your development environment is configured to be "confluence", then the url to connect to Confluence is **http://localhost:8090/confluence/** to which you add the REST API endpoint **/rest/api/content/**

  ```
  ?<Context path="confluence"
  ```

I hope this explains.

Cheers,  
Dario


author: Dario B
body: [@Mamadou Barry](/t5/user/viewprofilepage/user-id/2246246) ,

In order to try to help we may need a bit more details:

What is the HTML you get in response saying?

Also, is this working if you send the same request to the same endpoint using curl?

Cheers,  
Dario

comments: author: Mamadou Barry
body: Thanks for replying. Actually, I have figured out the issue and solved it.  

The endpoint I was using was the issue. In production, you should use this endpoint **http://localhost:8090/rest/api/content/,** but I was using this one **http://localhost:8090/confluence/rest/api/content/**which is used for development, so that was it.


Tags: server