How to handle issue attachments in JIRA from Javascript code?

Recently, I've used my 20% time allocation to make a new JIRA plugin available from the Atlassian Marketplace Image Annotator for JIRA. The idea behind this project was to create an image editor for image attachments, seamlessly integrated with JIRA. One of the challenges that I encountered was handling attachments directly from frontend code (this plugin is 99% made in JavaScript).

After finding out correct REST path to make the AJAX calls (/rest/api/2/issue/ISSUE_ID/attachments) the question was what should be set as data argument? JIRA requires the request to be multipart, so if you want to use jQuery's ajax method then you have to use FormData object:

var formData = new FormData();

formData.append("file", blob);

But it turned out that it's not enough. JIRA complained about image name not being sent with the request. Quick research revealed that FormData.append() method has two versions. Third argument can be added, and this third argument is the file name. Exactly what I was looking for! Please be advised though that some IDEs, like IntelliJ IDEA, says that FormData.append() takes only two arguments, not three. Yet, I tested this method in 4 different browsers (Chrome, Firefox, Safari and IE11) and in all of them adding third argument worked fine. So, finally FormData.append() looked like that:

formData.append("file", blob, "file_name.txt");

You may wonder what this blob is. Blob type is just a representation of our file that is going to be attached to an issue. This is a raw data and in every case this object should be created in a different way. In the most simple case, plain text file, the code is following:

var fileParts = ["Hello JIRA!"];

var blob = new Blob(fileParts, {type : 'text/plain'});

Finally, having all the data we need, we can make the ajax call:


url: AJS.contextPath() + "/rest/api/2/issue/ISSUE_ID/attachments",

type: "POST",

data: formData,

headers: {

"X-Atlassian-Token": "nocheck"


success: function () {



error: function(jqXHR, textStatus, errorThrown) {



contentType: false,

processData: false


I hope you will find this article useful, it took me quite a while to find out how to create a proper data object and save it as an issue attachment, all done in JavaScript code.

Last but not least, I encourage you to try our brand new plugin Image Annotator for JIRA. If you like it, you can vote for it on Codegeist Hackathon (only a few days left!). Every vote counts (smile).

This website, like many others, uses small files called cookies to help us provide social media features and to analyse our traffic.
You consent to our cookies if you continue to use this website.