As JIRA is a web application, it is generally possible to construct a URL which will trigger an operation, such as creating or commenting on an issue. This is often a simple alternative to SOAP or XML-RPC.
For example, To create a Bug in the 'TST' project on jira.atlassian.com, click on:
This URL contains various parameters (pid, issuetype, summary) that are either hidden or submitted in HTML forms. Here is another variant, setting a custom field, but not submitting the form (ie. prepopulating a field):
So the task is to discover exactly what parameters are required for a particular operation.
Discovering HTTP parameters
HTTP parameters are most easily discovered with the LiveHTTPHeaders plugin for Firefox.
Install this plugin, and then navigate to the point before the operation you're interested in (eg. Step 2 in the issue creation process). Now open the LiveHTTPHeaders window, and submit the JIRA form to proceed with the operation. In the LiveHTTPHeaders window you will see the HTTP POST operation:
POST /secure/CreateIssueDetails.jspa HTTP/1.1 Host: jira.atlassian.com User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1) Gecko/20060918 Firefox/2.0 Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5 Accept-Language: en-us,en;q=0.5 Accept-Encoding: gzip,deflate Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7 Keep-Alive: 300 Connection: keep-alive Referer: http://jira.atlassian.com/secure/CreateIssue.jspa Cookie: jira.conglomerate.cookie=navigator.filter.subheading.workratio=0; jira.conglomerate.cookie=;JSESSIONID=aWtQgyV8UTO9JioJG-; s_cc=true; s_sq=%5B%5BB%5D%5D Content-Type: multipart/form-data; boundary=---------------------------20848862422003718001775908787 Content-Length: 2665 -----------------------------20848862422003718001775908787 Content-Disposition: form-data; name="summary" My test issue -----------------------------20848862422003718001775908787 Content-Disposition: form-data; name="description" Test description ..... -----------------------------2084886242200378001775908787 Content-Disposition: form-data; name="customfield_10061:1" 10104 -----------------------------20848862422003718001775908787 Content-Disposition: form-data; name="customfield_10170" -----------------------------20848862422003718001775908787 Content-Disposition: form-data; name="pid" 10420 -----------------------------20848862422003718001775908787 Content-Disposition: form-data; name="issuetype" 1 -----------------------------20848862422003718001775908787 Content-Disposition: form-data; name="Create" Create -----------------------------20848862422003718001775908787--
From this, get the POST header URL:
/secure/CreateIssueDetails.jspa
then find the section for each field you're interested in, and construct a name:value pair for it, eg:
pid=10420
issuetype=1
summary=My test issue
description=Test description
Now construct a full URL, separating the URL from the parameters with '?', and each parameter from others with '&':
Finally for authentication, either:
- append
&os_authType=basicand supply the login details outside the URL (-u username:passwordfor curl,--username=user --password=passfor wget). This has the advantage of not showing your login details in access logs. - append the special
os_usernameandos_passwordparameters, which will log you in as a user to perform the operation:
http://jira.atlassian.com/secure/CreateIssueDetails.jspa?pid=10420&issuetype=1&summary=My test issue&description=Test description&os_username=soaptester&os_password=soaptester
You can automate the submission of a URL like this with command-line
tools like wget or curl.
Scripting multi-stage operations
Some operations in JIRA require the accumulation of server-side state (in the user's session), and span multiple page requests. For this, you will need to store and reuse a cookie to tie multiple requests together.
With wget, this can be done as follows:
justin@asahi ~ $ wget --save-cookies cookies.txt --post-data 'os_username=justin&os_password=XXXX&os_cookie=true' http://localhost:8090/jira/login.jsp
This command perform the initial request to log you into your JIRA instance and also create a file in your home directory called cookies.txt.
So for any further requests you just need to reference the cookies.txt file and use a normal URL without appending any user details:
justin@asahi ~ $ wget --load-cookies cookies.txt -p http://localhost:8090/jira/browse/WEB-3
With curl, first use --cookie-jar to save the cookies on login:
$ curl -u justin:XXXX --cookie-jar cookies.txt 'http://localhost:8080/secure/Dashboard.jspa?os_authType=basic' --head
Then use --cookie cookies.txt on subsequent requests.
Uploading file attachments
In JIRA 4.3 or later
The Atlassian REST API allows adding attachments:
$ curl -H "X-Atlassian-Token: no-check" -u justin:XXXX 'http://localhost:8080//rest/api/2.0-alpha1/issue/<issuekey>/attachments' -X POST -F file=@/path/to/file
Substitute in your own base URL, username/password, issue key, and file. You can specify multiple file parameters to upload multiple attachments. You can also explicitly set the name of the attachment, by using -F "file=@/path/to/file;filename=attachmentname".
In JIRA 4.1 or earlier
The simplest way to upload an attachment from the command-line is with curl (though I'm sure it's possible with wget too). Assuming you want to upload a file test.txt to JIRA at http://localhost:8080, you'd run:
curl -H "X-Atlassian-Token: no-check" 'http://localhost:8080/secure/AttachFile.jspa?id=10000&os_username=test&os_password=test' -F filename.1=@small.txt
The issue ID (10000) can be discovered by looking at the URLs for operations on the JIRA issue (comment, assign etc).
Bulk adding custom field options
If you need to add a lot of custom field options:

This operation can be easily scripted. Use LiveHTTPHeaders to analyse one submission:
POST /secure/admin/EditCustomFieldOptions!add.jspa HTTP/1.1 Host: localhost:8080 ..... Content-Type: application/x-www-form-urlencoded Content-Length: 87 addValue=second&fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&Add=Add
So the URL is:
/secure/admin/EditCustomFieldOptions!add.jspa?
addValue=second&fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&Add=Add
Prepending the hostname, appending authentication parameters and moving the value to the end gives:
http://localhost:8080/secure/admin/EditCustomFieldOptions\!add.jspa?fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&os_username=test&os_password=test&addValue=second (http://localhost:8080/secure/admin/EditCustomFieldOptions\!add.jspa?fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&os_username=test&os_password=test&addValue=second)
So now we can add a third value from the command-line:
$ wget --header="X-Atlassian-Token: no-check" -q 'http://localhost:8080/secure/admin/EditCustomFieldOptions!add.jspa?fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&os_username=test&os_password=test&addValue=third'
or even bulk add options from a file or script:
$ for user in `cat /etc/passwd \| cut \-d: \-f1`; do
wget --header="X-Atlassian-Token: no-check" -q 'http://localhost:8080/secure/admin/EditCustomFieldOptions!add.jspa?fieldConfigId=10031&selectedParentOptionId=&addSelectValue=true&os_username=test&os_password=test&addValue='$user
done
Bypassing XSRF protection
Many actions on JIRA have XSRF protection on them to ensure that they can't be executed using XSRF. One of the limitations of an XSRF attack is that an attacker cannot control the HTTP headers submitted by their victims browser. Hence JIRA has a custom HTTP header that can be used to bypass the XSRF token check. The name of this header is X-Atlassian-Token, and its value must be "no-check". To use this with wget, supply --header="X-Atlassian-Token: no-check", or with curl -H "X-Atlassian-Token: no-check".

16 Comments
Hide/Show CommentsJun 08, 2007
Richard Sargent
I see examples for creating an issue, but not for updating one. I have tried to do so, based on what I can glean, but it just doesn't give the results I desire. Can anyone tell me what I have missed?
Specifically, I use the following URL to attempt to set a custom field:
http://someserver:8080/secure/EditIssue.jspa?Update=Update&customfield_10354=Waived&id=28831&os_username=rsargent&os_password=XXXXXXXX
I get the EditIssue.jspa page back (some 400 Kb of HTML). Which shows my update to the custom field, but it has not been committed. Is this one of those tasks that require cookies and a two stage process?
Any advice on making this work would be appreciated.
BTW, I am not using a command line program like WGET. I am sending the HTTP request programmatically and reading the reply programmatically as well.
May 25, 2010
AndersL
I second this, has anyone found a solution to update a field via the url?
Oct 20, 2010
Evgeny Zislis
There are several things to note when trying to update issues with EditIssue.jspa
1. You need to specify all the existing fields as well as the updated ones if they are required fields for your issue.
2. The above also includes the <input type="hidden"> fields, such as:
a. Issue ID (the database id number, different from issue key)
b. XSRF token, called atl_token in Jira 4.1.1 - you need to grab it from the "get" request to EditIssue.jspa page, and post it back as you received it.
The reason why you get 400kb page with all the fields, is that it is a pre-filled form ... when you click the "update" button it actually sends ALL the fields to the server, and not just the changed ones. It is on the server side that they are checked for any changes. So to automate it -- you need to send everything, just like a browser would have.
I doubt there is an option to update just a single field (or selected fields) via URL, unless it is programmed into jira as a special case just for the purpose of automation.
Aug 07, 2007
Eric Rawlins
I was able to use this successfully to Add and Remove values from custom fields, as well as sort the new values alphabetically. This was implemented as part of a solution to synchronize a custom field list programatically with an external database. Code must still be written to determine additions/deletions between JIRA and the other values, and the jira database must be queried to get customfieldoption ID's, but if all those exist here are the commands I used, as an FYI:
Adding a Value
http://server/secure/admin/EditCustomFieldOptions!add.jspa?addValue=NEWVALUE_TEST&fieldConfigId=10270&os_username=username?os_password=password?Add=Add
Delete a Value
http://server/secure/admin/EditCustomFieldOptions!remove.jspa?fieldConfigId=10270&selectedValue=26460&confirm=true&Delete=Delete&os_username=username?os_password=password
Sort Alphabetically http://server/secure/admin/EditCustomFieldOptions!sort.jspa?fieldConfigId=10270&os_username=username?os_password=password
Jul 16, 2008
zcraven
Unfortunately released after you created that solution Eric, but this is another way of achieving the same thing:
http://confluence.atlassian.com/display/JIRAEXT/Database+Values+JIRA+Plugin
Dec 27, 2007
Chris Kohlhardt
Here is a php example for logging into jira and creating an issue:
Jul 16, 2008
zcraven
More info for people using PHP, such as how to set dates, customfields etc via SOAP (not wget)
http://forums.atlassian.com/thread.jspa?messageID=257281327
Jan 22, 2009
Jeff Turner
If you have a JIRA multi-level select-list custom field, and wish to bulk add options, there's a script here which does it:
https://svn.atlassian.com/svn/public/contrib/jira/csv2jiraopts
Nov 17, 2009
Jeff Turner
See also the JIRA Command-line Interface.
Feb 16, 2010
Matt Doar (CustomWare)
Jeff, the link to the CLI is no longer useful.
Also, when creating an issue, many JIRA instances will require &reporter=userid1&assignee=userid2
Feb 16, 2010
Matt Doar (CustomWare)
Jeff, the link to the CLI is no longer useful.
Also, when creating an issue, many JIRA instances will require &reporter=userid1&assignee=userid2
Feb 16, 2010
Christina Bang [Atlassian]
I'll jump in and give the updated link to the JIRA Command Line Interface
Feb 22, 2010
Janet Albion [Atlassian]
Here is an example of Shell Script for Auto Re-Indexing in Unix platform. On the safe side, I can't guarantee it works for everyone:
\#\!/usr/bin/sh \### SETTINGS ### USERNAME=jiradminusername PASSWORD=jiraadminpassword DASHBOARD_PAGE_URL=http://localhost:8080/secure/Dashboard.jspa INDEX_PAGE_URL=http://localhost:8080/secure/admin/jira/IndexReIndex.jspa LOGIN_PAGE_URL=http://localhost:8080/rest/gadget/1.0/login COOKIE_FILE_LOCATION=jiracoookie \### COMMANDS ### /usr/bin/curl \--cookie-jar $COOKIE_FILE_LOCATION \--output /dev/null $DASHBOARD_PAGE_URL /usr/bin/curl \--cookie $COOKIE_FILE_LOCATION \--cookie-jar $COOKIE_FILE_LOCATION \--data "os_username=${USERNAME}" \--data "os_password=${PASSWORD}" \--location \--output /dev/null ${LOGIN_PAGE_URL} /usr/bin/curl \--cookie $COOKIE_FILE_LOCATION \--data "indexPathOption=DEFAULT" \--data "indexPath=" \--data "Re-Index=Re-Index" \--output /dev/null $INDEX_PAGE_URL /bin/rm $COOKIE_FILE_LOCATIONThen trigger the script using Curl.
Enjoy!
Jan 19, 2011
Justin Downing
The above did not work for me in Linux. But this did:
May 05, 2011
Oueslati Bechir
Hi,
I have succeeded to create static forms that create and edit issues and even comment, but the only problem that i have, how can i get the id of project or the id of an issue dynamically, anyone can help me?
Thanks in advance
Oct 21, 2011
Wolfgang Guettler
I'm Trying to move issues (change parent) using wget like so:
This results in a timeout message though:
Even if I only try to request the 'Move Action' page.
This also results in the timeout page.
Any Idea ?