It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

Confluence REST API's: Uploading a document to Confluence - JAVA


I am beginning a project where the goal is to upload a document to a folder on my company's confluence site. I have been researching what REST API's and services there are that could help me with my problem. I feel like I have gotten close but am just missing the mark and cannot figure what to do. I have looked through a lot of documentation that has been provided by Atlassian but I have either not been looking in the right place or I just went over something along the way. Can anyone point in the right direction on where I should start? I am attempting to do this within Java. I am new to Confluence and Atlassian so I have no idea if this is possible.

Thanks in advance

3 answers

1 accepted

1 vote
Answer accepted

Tiago and Gorka,

I appreciate both of your assistance. I did figure out how to upload an attachment to a Confluence page in Java. While I didn't use your methods specifically I'll give you both upvotes for your time and because while they didn't quite fit what I was looking for I know it will help someone else out there. And trying both of your methods spurred my thinking and got me going. My method is similar to Bob Swifts method found here:

If you find you are getting weird SSL Exception errors that means you need to add your Confluence's security certificate to your cacerts file. You can find more details on that here:


Here's what I did:

ConfluenceSoapServiceServiceLocator fConfluenceSoapServiceGetter = new ConfluenceSoapServiceServiceLocator();
ConfluenceSoapService service = null;
String fToken = null;

// This prevents Java from fatal error because it doesn't recognizes Confluence's security certificate. May have to your Confluence sites security certificate to your cacerts file
System.setProperty("jsse.enableSNIExtension", "false");

try {
	// find endpoint on Confluence to work with and get Services from Confluence
	String endPoint = "/plugins/servlet/soap-axis1/confluenceservice-v2";
	fConfluenceSoapServiceGetter.setConfluenceserviceV2EndpointAddress("https://confluence.<companynamehere>.com" + endPoint);
	service = fConfluenceSoapServiceGetter.getConfluenceserviceV2();
	// Authenticate user
	fToken = service.login(username, password);

	// Read file to be uploaded to Confluence
	FileInputStream fis = null;
	File in = new File(sourceLoc);
	fis = new FileInputStream(in);
	byte[] buf = new byte[4096];
	byte[] fbuf = new byte[(int) in.length()];
	int c = 0;
	int length = 0;
	logger.debug("Reading: " + in.getAbsolutePath());
	while((length = > 0) {
		System.arraycopy(buf, 0, fbuf, c, length);
		c += length;

	// Gather information necessary to upload file
	RemoteAttachment ra = new RemoteAttachment();

	// Uploads file to Confluence. PageId is of the page you want to put the attachment on
	service.addAttachment(fToken, pageId, ra, fbuf);
} catch (Exception e) {

Nice! I'm glad you did it!

help to find out text from confluence 

Hi James,

Using what Tiago posted, you can create a POST request from java

User adminUser = userManager.getUser("admin");

ConfluenceUser confluenceAdminUser = new ConfluenceUserImpl(adminUser);
		AuthenticatedUserThreadLocal.set((ConfluenceUser) confluenceAdminUser);
	Request request = requestFactory.createRequest(Request.MethodType.POST, restUrl);

Depending on what you need, you can set the content type or the body of the request



or even handle the response

request.execute(new ResponseHandler() {
			public void handle(Response response) throws ResponseException {

Hope this gives you a hint about how to follow!


Thank you for this Gorka. Do you know which jar contains "User" and where I can find that? And is the variable "userManager" of type UserManager? What are the other dependencies for this code?

Hi James,

The jar containing com.atlassian.user.User is atlassian-user-3.0.jar but I think it comes with the core. UserManager has to be injected in your constructor

public YourClass(UserManager userManager){
		this.userManager = userManager;

For the rest of dependencies, I think the following should be enough


	<component-import key="userManager" interface="com.atlassian.sal.api.user.UserManager" />
<component key="compatibilityUserManager" class="com.atlassian.sal.usercompatibility.impl.CompatibilityUserManager" />
  <component-import key="salRequestFactory" interface="" />

Your pom.xml

<dependency> <groupId>com.atlassian.sal</groupId> <artifactId>sal-api</artifactId> <version>${sal.api.version}</version> <scope>provided</scope> </dependency>


Check it and post the result!


I've never used User or UserManager before and am having some trouble with it. Do you think you could give me a little explanation on them? Not sure how to get it setup. Thanks

Could you be a little more specific? What troubles are you having now?


I get that the adminUser contains credentials for the confluence site I am trying to post to. I do not know how to assign said credentials to the adminUser. It appears it is done with the UserManager but I can't quite figure out how to do it.

Thanks again

Hi James,

In the example I gave to you

User adminUser = userManager.getUser("admin");
ConfluenceUser confluenceAdminUser = new ConfluenceUserImpl(adminUser);
        AuthenticatedUserThreadLocal.set((ConfluenceUser) confluenceAdminUser);
    Request request = requestFactory.createRequest(Request.MethodType.POST, restUrl);

Check this line

AuthenticatedUserThreadLocal.set((ConfluenceUser) confluenceAdminUser);

A simple ThreadLocal to store the currently authenticated user. This can be used when the user comes from something other than the web interface (i.e. SOAP).

Extracted from

Did you try it? If it worked like Tiago said, I suppose it should work this way. You are doing the same, a POST request.



Hi James, have you tried to upload your attachments using this REST call?

curl -D- -u user:password -X POST -H "X-Atlassian-Token: nocheck" -F "file=@test.txt" http://&lt;confluence_url&gt;/rest/api/content/&lt;page_id&gt;/child/attachment

The output of it should be something like this:

HTTP/1.1 100 Continue

HTTP/1.1 100 Continue

HTTP/1.1 200 OK
Date: Tue, 02 Sep 2014 14:21:34 GMT
Server: Apache-Coyote/1.1
X-ASEN: SEN-L4138508
X-Seraph-LoginReason: OK
X-Content-Type-Options: nosniff
Content-Type: application/json
Set-Cookie: JSESSIONID=6BE16241C81BAAA2F19B7ECBBD4D1A58; Path=/confluence/; HttpOnly
Connection: close
Transfer-Encoding: chunked

{"results":[{"id":"att9797634","type":"attachment","title":"test.txt","version":{"by":{"type":"known","profilePicture":{"path":"/confluence/s/en_GB/5510/701ab0bfc8a95d65a5559a923f8ed8badd272d36.1/_/images/icons/profilepics/default.png","width":48,"height":48,"isDefault":true},"username":"admin","displayName":"Administrator"},"when":"2014-09-02T11:21:34.019-0300","number":1,"minorEdit":false},"container":{"id":"9502724","type":"page","title":"content test","_links":{"webui":"/display/CS/content+test","tinyui":"/x/BACR","self":"https://ironman/confluence/rest/api/content/9502724"},"_expandable":{"history":"/rest/api/content/9502724/history","body":"","container":"","ancestors":"","children":"/rest/api/content/9502724/child","descendants":"/rest/api/content/9502724/descendant","space":"/rest/api/space/CS","version":"","metadata":""}},"metadata":{"mediaType":"application/octet-stream"},"_links":{"download":"/download/attachments/9502724/test.txt?version=1&amp;modificationDate=1409667694019&amp;api=v2","webui":"/pages/viewpageattachments.action?pageId=9502724&amp;highlight=test.txt#content+test-attachment-test.txt","self":"https://ironman/confluence/rest/api/content/att9797634"},"_expandable":{"history":"/rest/api/content/att9797634/history","body":"","ancestors":"","children":"/rest/api/content/att9797634/child","descendants":"/rest/api/content/att9797634/descendant","space":"/rest/api/space/CS"}}],"size":1}

I hope it helps.


I have not, I am actually trying to do this within Java. I did not mention that in the original post, my apologies. I will fix that. Do you know how to do this in Java?

Tiago, I tried running this and it returned the html of the confluence page. Would you know why this happens?

I got:

HTTP/1.1 100 Continue

HTTP/1.1 100 Continue

HTTP/1.1 404 Not Found

Do you know what's the http response? for example, in the command output above the response was HTTP/1.1 200 OK, which is the expected one when everything is alright.


404 means that your URL wasn't found. In the command line above you'll see the example http://<confluence_url>/rest/api/content/<page_id>/child/attachment, which in my case the actual URL was: https://ironman/confluence/rest/api/content/8814611/child/attachment, you may want to confirm your URL.


I am definitely going wrong with the <confluence_url> portion. To me it seems like it should be the full url of the page I want to upload a document to. But your example only has "ironman/confluence" as the "<confluence_url>". Is there anything you can explain about this portion? I appreciate all the help by the way

I am also now getting a HTTP 302 response now. Isn't that some form of redirect?

Sure, ironman is a DNS alias (cname) to one of our test servers and the portion "confluence" is a context path that was defined to this confluence instance. So if I want to access Confluence dashboad I'd use https://ironman/confluence

I hope it helps to clarify, let me know if you need any additional info.


So I just don't know enough about these rest services, DNS servers and Confluence but the Confluence instance I am working in is only accessible online through a https://confluence.<companynamehere>.com/display/<destinationfolder>. Based on your previous comment it seems like I can't just use that URL I just put here to complete the CURL command. Does it only work with the DNS alias and context path you have defined? Would I have to do the same thing. I'm sorry if I sound uneducated about this stuff but the truth is I am. I just want to make sure were on the same page and there's not more setup required on my end.

Yes, this gives me the HTTP 404 as the third HTTP message just like before. Then it spits back the html of that confluence page. I am also using a -k for a parameter because of an issue with the security certificate so I'm just bypassing it. Would that affect anything? Other than that I did exactly what you suggested

This is the exact command I am using

curl -D- -u <user>:<password> -X POST -H "X-Atlassian-Token: no-check" -F "file=@C:\DEV\TestFile2.txt" https://confluence.<companynameher>.com/rest/api/content/<pageid>/child/attachment-k

Actually it's not necesary to define DNS alias or context path, sorry I may have caused this confusion, my intention was just explain how my URL was built.

Based on your comment it seems that the URL in your curl command should be https://confluence.<companynamehere>.com/rest/api/content/<page_id>/child/attachment, have you tried this format?

Suggest an answer

Log in or Sign up to answer
This widget could not be displayed.
This widget could not be displayed.
Community showcase
Published Thursday in Confluence

Confluence CVEs and common questions

Two vulnerabilities have been published for Confluence Server and Data Center recently: March 20, 2019 CVE-2019-3395 / CVE-2019-3396 April 17, 2019 CVE-2019-3398 The goal of this article is...

130 views 0 10
Read article

Atlassian User Groups

Connect with like-minded Atlassian users at free events near you!

Find a group

Connect with like-minded Atlassian users at free events near you!

Find my local user group

Unfortunately there are no AUG chapters near you at the moment.

Start an AUG

You're one step closer to meeting fellow Atlassian users at your local meet up. Learn more about AUGs

Groups near you