This guide contains different examples of how to use the Jira REST API, including how to query issues, create an issue,edit an issue, and others.
The reference documentation for the Jira Server platform REST API is here:Jira Server platform REST API.If you've never used the Jira REST APIsbefore, we recommend that you also read the overviewAbout the Jira REST APIs.
The examples on this page usecurl. If an input file is required, it is denoted by the--data @filename
syntax and the file data is shown separately.
Creating an issue examples
Note that thecreatemeta
resource has been reported to cause issues especially on larger instances. These issues have involved the size of the response or Jira running out of memory.That is why we decided to remove this endpoint in Jira 9.0. If you run Jira 8.4 or later, disable the endpoint and replace it with the other calls we've created to remedy the issue. For Jira versions earlier than 8.4, you do not need to disable the endpoint but we strongly recommend that you upgrade to a newer Jira version. Read more ...
Jira versions earlier than 8.4
Creating an issue using the Jira REST API is as simple as making a POST with a JSON document. To create an issue,you will need to know certain key metadata, like the ID of the project that the issue will be created in, or theID of the issue type. You can request the create metadata for all issue types across all projects by usingthecreatemeta
resource.
For example:
12http://localhost:8080/rest/api/2/issue/createmeta
If you only want a subset of this information, specify the desired projects and issue types as query parameters.For example, this request will return the create metadata for the Bug issue type in the Jira project:
12http://localhost:8080/rest/api/2/issue/createmeta?projectKeys=JRA&issuetypeNames=Bug&expand=projects.issuetypes.fields
For more detailed examples of requesting metadata, see theexamples in thesections later.
Jira versions 8.4 and later
Creating an issue using the Jira REST API is as simple as making a POST with a JSON document. To create an issue, you will need to know certain key metadata, like the ID of the project that the issue will be created in, the ID of the issue type, and which fields to fill.First, you need to decide which project to use. You can get a list of all the projects from the following endpoint:
12http://localhost:8080/rest/api/2/project
After finding the project you want, you will need its ID or key. You will use this information to retrieve the issue types in this project:
12http://localhost:8080/rest/api/2/issue/createmeta/{projectIdOrKey}/issuetypes
Once you find the appropriate issue type to use, you need to get the fields under this issue type. This endpoint will list the usable fields under the issue type.
12http://localhost:8080/rest/api/2/issue/createmeta/{projectIdOrKey}/issuetypes/{issueTypeId}
For more detailed examples of requesting metadata, see the examples in the sections later.
Creating an issue using a project key and field names
This is a basic example of how to create an issue using the Jira REST API.
Request
12curl \ -D- \ -u charlie:charlie \ -X POST \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/
Input data
12{ "fields": { "project": { "key": "TEST" }, "summary": "REST ye merry gentlemen.", "description": "Creating of an issue using project keys and issue type names using the REST API", "issuetype": { "name": "Bug" } }}
Response
12{ "id":"39000", "key":"TEST-101", "self":"http://localhost:8080/rest/api/2/issue/39000"}
Creating an issue using a project ID and issue type ID
This example uses the project ID and issue type ID rather than the key and name respectively. This is usefulif you only have the IDs. For example, your integration or script may have previously requested and saved onlythe IDs of the project and issue type.
Request
12curl \ -D- \ -u charlie:charlie \ -X POST \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/
Input data
12{ "fields": { "project": { "id": "10110" }, "summary": "No REST for the Wicked.", "description": "Creating of an issue using IDs for projects and issue types using the REST API", "issuetype": { "id": "1" } }}
Response
The response provides the issue ID, key, and the URL to the issue. You can use this to GET additional data,PUT updates, and so on via the REST API.
12{ "id":"39001", "key":"TEST-102", "self":"http://localhost:8080/rest/api/2/issue/39001"}
Creating a sub-task
A sub-task is essentially a special type of issue, so the sub-task creation request and response are verysimilar to issue creation. Creating a sub-task has two important differences:
Jira versions earlier than 8.4
- The
issueType
field must correspond to a sub-task issue type(you can use/issue/createmeta
to discover sub-task issue types). - You must provide a
parent
field in the issue create request containing the ID orkey
of the parent issue.
Jira versions 8.4 and later
- The
issueType
field must correspond to a sub-task issue type(you can use/issue/createmeta/{projectIdOrKey}/issuetypes
to discover sub-task issue types). - You must provide a
parent
field in the issue create request containing the ID orkey
of the parent issue.
Request
12curl \ -D- \ -u charlie:charlie \ -X POST \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/
Input data
12{ "fields": { "project": { "key": "TEST" }, "parent": { "key": "TEST-101" }, "summary": "Sub-task of TEST-101", "description": "Don't forget to do this too.", "issuetype": { "id": "5" } }}
Response
The response provides the sub-task ID, key, and the URL to the issue (which can then be used to GET additionaldata, PUT updates, and so on) via the REST API.
12{ "id":"39002", "key":"TEST-103", "self":"http://localhost:8080/rest/api/2/issue/39002"}
Creating an issue using custom fields
In the Jira REST API, custom fields are uniquely identified by the field ID, as the display names are not uniquewithin a Jira instance. For example, you could have two fields named "Escalation date", one with an ID of "12221"and one with an ID of "12222".
A custom field is actually referenced bycustomfield\_
+ the field ID, rather than just the field ID.
For example,the "Story points" custom field with ID = "10000" is referenced as customfield\_10000
for REST calls.You can get this reference identifier byrequesting the create metadata for the issue type.
The example below uses a custom free text field named "Explanation" that has an ID of 11050. Note that wereference the field by customfield\_11050
and that the name of the field "Explanation" is not used anywhere.
Request
12curl \ -D- \ -u charlie:charlie \ -X POST \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/
Input data
12{ "fields": { "project": { "key": "TEST" }, "summary": "Always do right. This will gratify some people and astonish the REST.", "description": "Creating an issue while setting custom field values", "issuetype": { "name": "Bug" }, "customfield_11050" : "Value that we're putting into a Free Text Field." }}
Response
Again, the issue created is returned in the response.
12{ "id":"39002", "key":"TEST-103", "self":"http://localhost:8080/rest/api/2/issue/TEST-103"}
Setting custom field data for other field types
The examples below show how to set the values for different types of custom fields in the input data.For Jira versions earlier than 8.4 you should retrieve custom field ID from the createmeta
endpoint.For Jira versions 8.4 and later you should retrieve custom field ID from the /issue/createmeta/{projectIdOrKey}/issuetypes/{issueTypeId}
endpoint.
CascadingSelectField
12"customfield_10001": {"value": "green", "child": {"value":"blue"} }
The value associated with "name" ("green" in this example) is the parent option selected,then "blue" is the child option).
DatePickerField
12"customfield_10002": "2011-10-03"
The format is:YYYY-MM-DD
DateTimeField
12"customfield_10003": "2011-10-19T10:29:29.908+1100"
This format is ISO 8601:YYYY-MM-DDThh:mm:ss.sTZD
FreeTextField
12"customfield_10004": "Free text goes here. Type away!"
GroupPicker
12"customfield_10005": { "name": "jira-developers" }
Like users, groups are specified by name or ID.
MultiGroupPicker
12"customfield_10007": [{ "name": "admins" }, { "name": "jira-developers" }, { "name": "jira-users" }]
Like users, groups are specified by name or ID.
MultiSelect
12"customfield_10008": [ {"value": "red" }, {"value": "blue" }, {"value": "green" }]
MultiUserPicker
12"customfield_10009": [ {"name": "charlie" }, {"name": "bjones" }, {"name": "tdurden" }]
Array of users.
NumberField
12"customfield_10010": 42.07
Just a number (not a number in a string).
ProjectPicker
12"customfield_10011": { "key": "JRADEV" }
You can also specify the project by project ID.
12{ "id":"10000" }
RadioButtons
12"customfield_10012": { "value": "red" }
You can also specify the selection by ID.
SelectList
12"customfield_10013": { "value": "red" }
You can also specify the selection by ID.
SingleVersionPicker
12"customfield_10014": { "name": "5.0" }
You can also specify the version by ID.
TextField
12"customfield_10015": "Is anything better than text?"
URLField
12"customfield_10016": "http://www.atlassian.com"
UserPicker
12"customfield_10017": { "name":"brollins" }
VersionPicker
12"customfield_10018": [{ "name": "1.0" }, { "name": "1.1.1" }, { "name": "2.0" }]
You can also specify a version by ID.
Adding a worklog entry during create
If you want to set the time tracking fields in a Jira issue when creating the issue,the create data should include a section like the following:
12"timetracking": { "originalEstimate": "1d 2h", "remainingEstimate": "3h 25m"}
Time tracking must be enabled to set these fields. In addition, if you use the Jira "Legacy" time tracking mode(set by a Jira Administrator), then only the remaining estimate can be set, so the originalestimate
fieldshould not be included in the REST request.
Request
The same as the other examples, the create is a POST:
12curl \ -D- \ -u charlie:charlie \ -X POST \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/
Input data
Again, this data is if Legacy mode for time tracking is off.
12{ "fields": { "project": { "key": "TEST" }, "summary": "Who seeks a faultless friend RESTs friendless.", "description": "Creating an issue and setting time tracking fields", "issuetype": { "name": "Bug" }, "timetracking": { "originalEstimate": "1d 2h", "remainingEstimate": "3h 25m" } }}
Response
12{ "id":"39003", "key":"TEST-104", "self":"http://localhost:8080/rest/api/2/issue/TEST-104"}
(Video) Jira Rest API GET/POST Request with Postman | Create Jira Issues Tutorial
Editing an issue examples
The examples in this section show you how to edit an existing issue using the Jira REST API. There are two typesof examples in this section:
- Editing an issue by updating the value of a field. Examples:
- Assigning an issue to a user.
- Updating multiple fields in one request.
- Editing an issue by using the SET, ADD, and REMOVE operations. Not all fields support all operations, butas a general rule, single value fields support SET, whereas multi-value fields support SET, ADD, and REMOVE,where SET replaces the field contents while ADD and REMOVE add or remove one or more values from the the currentlist of values. Examples:
- Adding a component.
- Setting the components field.
- Adding a component and removing another component in the same request.
- Updating multiple fields.
To edit an issue, you need to know certain key metadata, like the editable fields and the operations that they support.
You can request this data for an issue by using theeditmeta
resource. For example:
12http://localhost:8080/rest/api/2/issue/JRA-13/editmeta
Note that theeditmeta
resource does not work with PUT operations. You should only use it to get data.
Assigning an issue to a user
This example assigns an issue to a user with the username "charlie".
Request
12curl \ -D- \ -u charlie:charlie \ -X PUT \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/QA-31
Input data
12{ "fields": { "assignee":{"name":"charlie"} }}
Response
Status code of "204 No Content".
Updating multiple fields in one request
This example updates the summary, description, and two custom fields.
Request
12curl \ -D- \ -u charlie:charlie \ -X PUT \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/QA-31
Input data
12{ "fields" : { "summary": "Summary", "description": "Description", "customfield_10200" : "Test 1", "customfield_10201" : "Value 1" }}
Response
Status code of "204 No Content".
Adding a component
Request
12curl \ -D- \ -u charlie:charlie \ -X PUT \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/QA-31
example input data
12{ "update" : { "components" : [{"add" : {"name" : "Engine"}}] }}
Response
Status code of "204 No Content".
Setting the components field
Request
12curl \ -D- \ -u charlie:charlie \ -X PUT \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/QA-31
This is an example input data:
12{ "update" : { "components" : [{"set" : [{"name" : "Engine"}, {"name" : "Trans/A"}]}] }}
Response
Status code of "204 No Content".
Adding a component and removing another component in the same request
Request
12curl \ -D- \ -u charlie:charlie \ -X PUT \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/QA-31
This is an example input data:
12{ "update" : { "components" : [{"remove" : {"name" : "Trans/A"}}, {"add" : {"name" : "Trans/M"}}] }}
Note: The "Engine" component (if it exists) remains unaffected by this update.
Response
Status code of "204 No Content".
Updating multiple fields
Request
12curl \ -D- \ -u charlie:charlie \ -X PUT \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/issue/QA-31
This is an example input data:
12{ "update" : { "components" : [{"remove" : {"name" : "Trans/A"}}, {"add" : {"name" : "Trans/M"}}], "assignee" : [{"set" : {"name" : "harry"}}], "summary" : [{"set" : "Big block Chevy"}] }}
Response
Status code of "204 No Content".
The examples in this section show you how to add a comment to an existing issue using the Jira REST API.There are two types of examples in this section:
- Adding a comment using the
comment
resource.This resource simply adds a comment and nothing else. It isalso possible to add a comment as a side-effect of another operation like "edit issue" or "transition issue".This resource is particularly useful if the logged in user does not have "edit" permission for the issue, but doeshave the "add comment" permission. Examples:* Adding a comment.* Adding a comment and setting the security level in the same request. - Adding a comment when editing an issue, that is, using the edit issue method. Examples:
12* Adding a comment using the edit issue method.
12* Adding a comment and updating the issue description using the edit issue method.
Adding a comment
This example request adds a comment to an existing issue.
Request
12curl \ -D- \ -u fred:fred \ -X POST \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8081/rest/api/2/issue/QA-31/comment
This is an example input data:
12{ "body": "This is a comment regarding the quality of the response."}
Response
You should just receive a response with a status of "201" with the full JSON representation of the added comment.
Adding a comment and setting the security level in the same request
This example request adds a comment and sets the security level to an existing issue.
Request
12curl \ -D- \ -u fred:fred \ -X POST \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8081/rest/api/2/issue/QA-31/comment
Input data
12{ "body": "This is a comment that only administrators can see.", "visibility": { "type": "role", "value": "Administrators" }}
(Video) Jira REST API - Get issue details
Adding a comment using the edit issue method
This example request adds a comment to an existing issue via the edit issue method.Note that only one comment at a time can be added when updating an issue via this resource.
Request
12curl \ -D- \ -u fred:fred \ -X PUT \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8081/rest/api/2/issue/QA-31
Input data
12{ "update": { "comment": [ { "add": { "body": "It is time to finish this task" } } ] }}
Adding a comment and updating the issue description using the edit issue method
This example request updates the description of an existing issue and adds a comment explaining whyvia the edit issue method.
Request
12curl \ -D- \ -u fred:fred \ -X PUT \ --data {see below} \ -H "Content-Type: application/json" \ http://localhost:8081/rest/api/2/issue/QA-31
Input data
12{ "update": { "description": [ { "set": "JIRA should also come with a free pony" } ], "comment": [ { "add": { "body": "This request was originally written in French, which most of our developers can't read" } } ] }}
Searching for issues examples
The examples in this section show you how to search for issues using JQL via the Jira REST API.
Examples in this section:
- Searching for issues assigned to a particular user.
- Searching for issues assigned to particular user and restricting the number of results.
- Searching for issues assigned to particular userwith ordered results.
- Searching for issues and restricting the issue fields returned in the results.
- Searching for issues using POST.
Searching for issues assigned to a particular user
This example request searches for issues assigned to a user with the username "charlie".A single URL parameter (jql
) that contains the JQL query is provided in the request.
Request
12curl \ -D- \ -u charlie:charlie \ -X GET \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/search?jql=assignee=charlie
Response
12{ "expand": "schema,names", "startAt": 0, "maxResults": 50, "total": 6, "issues": [ { "expand": "html", "id": "10230", "self": "http://localhost:8080/rest/api/2/issue/BULK-62", "key": "BULK-62", "fields": { "summary": "testing", "timetracking": null, "issuetype": { "self": "http://localhost:8080/rest/api/2/issuetype/5", "id": "5", "description": "The sub-task of the issue", "iconUrl": "http://localhost:8080/images/icons/issue_subtask.gif", "name": "Sub-task", "subtask": true },... }, "customfield_10071": null }, "transitions": "http://localhost:8080/rest/api/2/issue/BULK-62/transitions", }, { "expand": "html", "id": "10004", "self": "http://localhost:8080/rest/api/2/issue/BULK-47", "key": "BULK-47", "fields": { "summary": "Cheese v1 2.0 issue", "timetracking": null, "issuetype": { "self": "http://localhost:8080/rest/api/2/issuetype/3", "id": "3", "description": "A task that needs to be done.", "iconUrl": "http://localhost:8080/images/icons/task.gif", "name": "Task", "subtask": false },... "transitions": "http://localhost:8080/rest/api/2/issue/BULK-47/transitions", } ]}
Searching for issues assigned to particular user and restricting the number of results
This example request searches for issues assigned to a user with the username "charlie" and restricts the numberof results to a specified number of issues.
Two additional URL parameters are provided in the request:startAt
andmaxResults.
These parameters specifythe starting issue returned in the JQL results and the number of issues from that starting issue respectively.
Request
12curl \ -D- \ -u charlie:charlie \ -X GET \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/search?jql=assignee=charlie&startAt=2&maxResults=2
Response
12{ "expand": "schema,names", "startAt": 2, "maxResults": 2, "total": 6, "issues": [ { "expand": "html", "id": "10123", "self": "http://localhost:8080/rest/api/2/issue/BULK-38", "key": "BULK-38", "fields": { "summary": "aaaaa", "timetracking": null, "issuetype": { "self": "http://localhost:8080/rest/api/2/issuetype/5", "id": "5", "description": "The sub-task of the issue", "iconUrl": "http://localhost:8080/images/icons/issue_subtask.gif", "name": "Sub-task", "subtask": true },... }, "transitions": "http://localhost:8080/rest/api/2/issue/BULK-38/transitions", }, { "expand": "html", "id": "10108", "self": "http://localhost:8080/rest/api/2/issue/BULK-32", "key": "BULK-32", "fields": { "summary": "subtasks are important, too", "timetracking": null, "issuetype": { "self": "http://localhost:8080/rest/api/2/issuetype/5", "id": "5", "description": "The sub-task of the issue", "iconUrl": "http://localhost:8080/images/icons/issue_subtask.gif", "name": "Sub-task", "subtask": true },... }, "transitions": "http://localhost:8080/rest/api/2/issue/BULK-32/transitions", } ]}
Searching for issues assigned to particular userwith ordered results
This example request searches for issues assigned to a user with the username "charlie" and orders the returnedissues by due date. The ordering is specified by using anorder by
clause in the JQL query itself(not via a URL parameter in your REST API call).
Request
12curl \ -D- \ -u charlie:charlie \ -X GET \ -H "Content-Type: application/json" \ http://localhost:8080/rest/api/2/search?jql=assignee=charlie+order+by+duedate
Response
12{ "expand": "schema,names", "startAt": 0, "maxResults": 50, "total": 6, "issues": [ { "expand": "html", "id": "10123", "self": "http://localhost:8080/rest/api/2/issue/BULK-38", "key": "BULK-38", "fields": { "summary": "aaaaa", "timetracking": null, "issuetype": { "self": "http://localhost:8080/rest/api/2/issuetype/5", "id": "5", "description": "The sub-task of the issue", "iconUrl": "http://localhost:8080/images/icons/issue_subtask.gif", "name": "Sub-task", "subtask": true },... }, "transitions": "http://localhost:8080/rest/api/2/issue/BULK-38/transitions", }, { "expand": "html", "id": "10108", "self": "http://localhost:8080/rest/api/2/issue/BULK-32", "key": "BULK-32", "fields": { "summary": "subtasks are important, too", "timetracking": null, "issuetype": { "self": "http://localhost:8080/rest/api/2/issuetype/5", "id": "5", "description": "The sub-task of the issue", "iconUrl": "http://localhost:8080/images/icons/issue_subtask.gif", "name": "Sub-task", "subtask": true },... }, "transitions": "http://localhost:8080/rest/api/2/issue/BULK-32/transitions", } ]}
Searching for issues and restricting the issue fields returned in the results
This example request searches for issues assigned to a user with the username "charlie" and restricts the issuefields returned to a specified set. The fields restriction is specified by supplying an additional URL parameterfields
, which lists the Jira fields returned in the JQL results.Each Jira field in the list should be comma-separated, for example,fields=id,key
.
Keep in mind that some extra data is always returned in the JSON response.
Request
12curl \ -D- \ -u charlie:charlie \ -X GET \ -H "Content-Type: application/json" \ 'http://localhost:8080/rest/api/2/search?jql=project=QA+order+by+duedate&fields=id,key'
Response
12{ "expand": "schema,names", "startAt": 0, "maxResults": 50, "total": 18, "issues": [ { "expand": "html", "id": "10050", "self": "http://localhost:8080/rest/api/2/issue/QA-19", "key": "QA-19", "transitions": "http://localhost:8080/rest/api/2/issue/QA-19/transitions" }, { "expand": "html", "id": "10051", "self": "http://localhost:8080/rest/api/2/issue/QA-20", "key": "QA-20", "transitions": "http://localhost:8080/rest/api/2/issue/QA-20/transitions" },... { "expand": "html", "id": "10053", "self": "http://localhost:8080/rest/api/2/issue/QA-22", "key": "QA-22", "transitions": "http://localhost:8080/rest/api/2/issue/QA-22/transitions" }, { "expand": "html", "id": "10389", "self": "http://localhost:8080/rest/api/2/issue/QA-35", "key": "QA-35", "transitions": "http://localhost:8080/rest/api/2/issue/QA-35/transitions" } ]}
Searching for issues using POST
If your JQL query is too large to specify in a URL parameter, you can POST your JQL query (in JSON format) tothe Jira REST APIsearch
resource instead.Any additional URL parameters (apart from theurl
parameter) described above must be included in yourJSON-formatted JQL query.
Request
12curl \ -D- \ -u admin:admin \ -X POST \ -H "Content-Type: application/json" \ --data '{"jql":"project = QA","startAt":0,"maxResults":2,"fields":["id","key"]}' \ "http://localhost:8080/rest/api/2/search"
Response
12{ "maxResults": 2, "startAt": 0, "total": 18, "expand": "schema,names", "issues": [ { "expand": "html", "id": "10393", "key": "QA-36", "self": "http://localhost:8080/rest/api/2/issue/QA-36", "transitions": "http://localhost:8080/rest/api/2/issue/QA-36/transitions" }, { "expand": "html", "id": "10389", "key": "QA-35", "self": "http://localhost:8080/rest/api/2/issue/QA-35", "transitions": "http://localhost:8080/rest/api/2/issue/QA-35/transitions" } ]}
Jira versions earlier than 8.4
The Jira REST API allows you to discover the fields and data available and required for creating issues.For this we use thecreatemeta
resource.
Examples in this section:
- Discovering project and issue type data.
- Discovering issue field data.
Discovering project and issue type data
To create an issue in Jira, you first need to specify a project and issue type. These together are referred toin Jira as anIssue contextand are used to find the Jira schemes that control what fields are availablefor an issue, what the default values are, and what fields are mandatory.
Using the createmeta
resource you can discover the project and issue types.
Request
12curl \ -D- \ -u fred:fred \ -X GET \ -H "Content-Type: application/json" \ http://localhost:8081/rest/api/2/issue/createmeta
Response
The response consists of an array of projects and each project contains an array of issue types thatapply to that project.
12{ "expand": "projects", "projects": [ { "self": "http://localhost:8081/rest/api/2/project/XSS", "id": "10020", "key": "XSS", "name": "<iframe src=\"http://www.google.com\"></iframe>", "avatarUrls": { "16x16": "http://localhost:8081/secure/projectavatar?size=small&pid=10020&avatarId=10011", "48x48": "http://localhost:8081/secure/projectavatar?pid=10020&avatarId=10011" }, "issuetypes": [ { "self": "http://localhost:8081/rest/api/2/issuetype/1", "id": 1, "name": "Bug", "iconUrl": "http://localhost:8081/images/icons/bug.gif" }, { "self": "http://localhost:8081/rest/api/2/issuetype/2", "id": 2, "name": "New Feature", "iconUrl": "http://localhost:8081/images/icons/newfeature.gif" },... { "self": "http://localhost:8081/rest/api/2/issuetype/5", "id": 5, "name": "Sub-task", "iconUrl": "http://localhost:8081/images/icons/issue_subtask.gif" } ] }, { "self": "http://localhost:8081/rest/api/2/project/BULK", "id": "10000", "key": "BULK", "name": "Bulk Move 1", "avatarUrls": { "16x16": "http://localhost:8081/secure/projectavatar?size=small&pid=10000&avatarId=10020", "48x48": "http://localhost:8081/secure/projectavatar?pid=10000&avatarId=10020" }, "issuetypes": [ { "self": "http://localhost:8081/rest/api/2/issuetype/1", "id": 1, "name": "Bug", "iconUrl": "http://localhost:8081/images/icons/bug.gif" },... { "self": "http://localhost:8081/rest/api/2/issuetype/5", "id": 5, "name": "Sub-task", "iconUrl": "http://localhost:8081/images/icons/issue_subtask.gif" } ] }, { "self": "http://localhost:8081/rest/api/2/project/BLUK", "id": "10001", "key": "BLUK", "name": "Bulk Move 2", "avatarUrls": {.... } ]}
If you know the projects or issue types you are interested in, you can restrict the list using theprojectKeys
, projectIds
, issuetypeNames
, and issuetypeIds
query parameters.For example:
12curl \ -D- \ -u fred:fred \ -X GET \ -H "Content-Type: application/json" \ http://localhost:8081/rest/api/2/issue/createmeta?projectKeys=QA,XSS
Discovering issue field data
When you have a project and issue type, you can retrieve the information for the issue fields by supplyingthe expand
query parameter with the projects.issuetypes.fields
value.
Request
12curl \ -D- \ -u fred:fred \ -X GET \ -H "Content-Type: application/json" \ http://localhost:8081/rest/api/2/issue/createmeta?projectKeys=QA&issuetypeNames=Bug&expand=projects.issuetypes.fields
Response
The response consists of an array of projects and each project contains an array of issue types that applyto that project.
12{ "expand": "projects", "projects": [ { "expand": "issuetypes", "self": "http://localhost:8081/rest/api/2/project/QA", "id": "10010", "key": "QA", "name": "QA", "avatarUrls": { "16x16": "http://localhost:8081/secure/projectavatar?size=small&pid=10010&avatarId=10011", "48x48": "http://localhost:8081/secure/projectavatar?pid=10010&avatarId=10011" }, "issuetypes": [ { "expand": "fields", "self": "http://localhost:8081/rest/api/2/issuetype/1", "id": 1, "name": "Bug", "iconUrl": "http://localhost:8081/images/icons/bug.gif", "fields": { "summary": { "required": true, "schema": { "type": "string", "system": "summary" }, "operations": [ "set" ] }, "timetracking": { "required": false, "operations": [ ] }, "issuetype": { "required": true, "schema": { "type": "issuetype", "system": "issuetype" }, "operations": [ ], "allowedValues": [ { "id": "1", "name": "Bug", "description": "A problem which impairs or prevents the functions of the product.", "iconUrl": "http://localhost:8081/images/icons/bug.gif" } ] }, "customfield_10080": { "required": false, "schema": { "type": "array", "items": "string", "custom": "com.atlassian.jira.plugin.system.customfieldtypes:labels", "customId": 10080 }, "operations": [ ] },.... "customfield_10010": { "required": false, "schema": { "type": "array", "items": "string", "custom": "com.atlassian.jira.plugin.system.customfieldtypes:labels", "customId": 10010 }, "operations": [ ] }, "customfield_10071": { "required": false, "schema": { "type": "array", "items": "string", "custom": "com.atlassian.jira.plugin.system.customfieldtypes:textfield", "customId": 10071 }, "operations": [ ] } } } ] } ]}
If you prefer, by omitting the projectKeys
and issuetypeNames
parameters you can retrieve all the issuefield data at once for all projects and issue types. However, this approach could amount to a very large response and couldtake some time to build on systems with a large number of projects and issue types.
Jira versions 8.4 and later
The Jira REST API allows you to discover the fields and data available and required for creating issues. For this, we use three different resources.
Examples in this section:
Discovering project
Discovering issue type data.
Discovering issue field data.
Discovering project
To create an issue in Jira, you first need to specify a project.
Request
12http://localhost:8080/rest/api/2/project
Response
12[ { "expand":"description,lead,url,projectKeys", "self":"http://localhost:8080/rest/api/2/project/10000", "id":"10000", "key":"TEST", "name":"Test", "avatarUrls":{ "48x48":"http://localhost:8080/secure/projectavatar?avatarId=10324", "24x24":"http://localhost:8080/secure/projectavatar?size=small&avatarId=10324", "16x16":"http://localhost:8080/secure/projectavatar?size=xsmall&avatarId=10324", "32x32":"http://localhost:8080/secure/projectavatar?size=medium&avatarId=10324" }, "projectTypeKey":"business" }]
Discovering issue type data
After selecting a project you will need an issue type. In Jira The Issue type together with the project is referred to as an Issue context and it is used to find the Jira schemes that control which fields are available for an issue, what the default values are, and which fields are mandatory.
Using the issue/createmeta/{projectIdOrKey}/issuetypes
resource you can discover the issue types under a project. The response will be paged.
Request
12http://localhost:8080/rest/api/2/issue/createmeta/TEST/issuetypes?startAt=0&maxResults=50
Response
12{ "maxResults":50, "startAt":0, "total":2, "isLast":true, "values":[ { "self":"http://localhost:8080/rest/api/2/issuetype/10000", "id":"10000", "description":"A task that needs to be done.", "iconUrl":"http://localhost:8080/secure/viewavatar?size=xsmall&avatarId=10318&avatarType=issuetype", "name":"Task", "subtask":false }, { "self":"http://localhost:8080/rest/api/2/issuetype/10001", "id":"10001", "description":"The sub-task of the issue", "iconUrl":"http://localhost:8080/secure/viewavatar?size=xsmall&avatarId=10316&avatarType=issuetype", "name":"Sub-task", "subtask":true } ]}
Discovering issue field data
When you have the project and the issue type, you can retrieve the information for the issue fields by calling the /issue/createmeta/{projectIdOrKey}/issuetypes/{issueTypeId}
endpoint. The response will be paged.
Request
12http://localhost:8080/rest/api/2/issue/createmeta/TEST/issuetypes/10000?startAt=0&maxResults=5
Response
12{ "maxResults":5, "startAt":0, "total":11, "isLast":false, "values":[ { "required":false, "schema":{ "type":"user", "system":"assignee" }, "name":"Assignee", "fieldId":"assignee", "autoCompleteUrl":"http://localhost:8080/rest/api/latest/user/assignable/search?issueKey=null&username=", "hasDefaultValue":false, "operations":[ "set" ] }, { "required":false, "schema":{ "type":"array", "items":"attachment", "system":"attachment" }, "name":"Attachment", "fieldId":"attachment", "hasDefaultValue":false, "operations":[ ] }, { "required":false, "schema":{ "type":"string", "system":"description" }, "name":"Description", "fieldId":"description", "hasDefaultValue":false, "operations":[ "set" ] }, { "required":false, "schema":{ "type":"date", "system":"duedate" }, "name":"Due Date", "fieldId":"duedate", "hasDefaultValue":false, "operations":[ "set" ] }, { "required":true, "schema":{ "type":"issuetype", "system":"issuetype" }, "name":"Issue Type", "fieldId":"issuetype", "hasDefaultValue":false, "operations":[ ], "allowedValues":[ { "self":"http://localhost:8080/rest/api/2/issuetype/10000", "id":"10000", "description":"A task that needs to be done.", "iconUrl":"http://localhost:8080/secure/viewavatar?size=xsmall&avatarId=10318&avatarType=issuetype", "name":"Task", "subtask":false, "avatarId":10318 } ] } ]}
Createmeta in integrations that work across versions - detect a new API functionality
This is only for Jira 8.4.1 and later
If you are building an integration that works across Jira versions (versions later and earlier than 8.4), you may want to check if the new endpoints are already available for your Jira instance. To do so, use one of the entries available in the the response of the /rest/capabilities endpoint.
Look for one of the capability names (list-project-issuetypes
or list-issuetype-fields
) in the response to determine if the new endpoints are present in the Jira instance.
To look for list-project-issuetypes
use:
12http://localhost:8080/jira/rest/api/2/issue/createmeta/{projectIdOrKey}/issuetypes?startAt=0&maxResults=50
or
To look for list-issuetype-fields
use:
12http://localhost:8080/jira/rest/api/2/issue/createmeta/{projectIdOrKey}/issuetypes/{issueTypeId}?startAt=0&maxResults=50
You can also parse these URLs and use them to make requests.
Other examples
The examples in this section show you more advanced use cases for the REST API, like calling the REST API froma script or an app.
Examples in this section:
- Calling the REST API from a script: Graphing image links.
- Calling the REST API from an app: Quickview inline dialog app.
Calling the REST API from a script: Graphing image links
This example shows you how to write a small python script that will use REST interface to graph the relationshipsbetween issues in Jira site.
To simplify the REST requests, you can use the small helper library called restkit.This library is not strictly necessary – after all, REST is just an HTTP.However, restkit can be used for convenience.You also rely onpygraphviz to do the actual graphing for you too.To use it you will need Graphviz installed.
Using the Jira REST API is straightforward:
- You make an HTTP call.
- Get some data back.
- Then do something with that data.
In the following example, 95% of the code is doing something other than interacting with the Jira REST API.So before you see the full example, let's highlight the actual REST usage out of context to show how simple itusually is. This example uses Python:
12resource = Resource(url + '/rest/api/2/issue/%s' % key, filters=[auth])response = resource.get(headers = {'Content-Type' : 'application/json'}) if response.status_int == 200: # Not all resources will return 200 on success. There are other success status codes. Like 204. We've read # the documentation though and know what to expect here. issue = json.loads(response.body_string()) return issue else: return None
This performs a GET on the issue, checks for a successful response, and then parses the JSON response into aPython dictionary.Thefilters=\[auth\]
line is how you tell restkit to perform BASIC Authentication.Later on, you'll reach into this Python dictionary to grab the data you want for your work.
12fields = issue['fields']if fields.has_key('subtasks'): for subtask in issue['fields']['subtasks']: # do work with a subtask
You also get an Epic Link
custom field ID with following:
12def get_epic_id(url, key, auth): resource = Resource(url + ('/rest/api/latest/issue/%s?expand=names' % key), filters=[auth]) response = resource.get(headers={'Content-Type': 'application/json'}) if response.status_int == 200: for field_id, field_name in json.loads(response.body_string())['names'].items(): if field_name == 'Epic Link': return field_id else: return None
You can view the full source on Bitbucket.
You can see the script's command line options using the standard command:
12python draw-chart.py --help
You can test this against your Jira site with:
12python draw-chart.py --user=username --password=password --jira=<url-of-your-jira-site>
The output should look similar to:
12Fetching JRADEV-1391Fetching JRADEV-2062Fetching JRADEV-2063Fetching JRADEV-1107Fetching JRADEV-112Fetching JRADEV-1108Fetching JRADEV-1218Fetching JRADEV-1219Fetching JRADEV-1220Fetching JRADEV-1221Fetching JRADEV-1684Fetching JRADEV-2064Fetching JRADEV-1390Fetching JRADEV-1389Fetching JRADEV-1388Fetching JRADEV-2125Fetching JRADEV-1264Fetching JRADEV-1256Writing to issue_graph.png
Open theissue\_graph.png
to show an image that should look something like this:
Blue lines with arrows denote Sub-tasks.
Calling the REST API from an app: Quickview inline dialog app
This example shows you how to create a Jira app that uses the REST API. We want to look through all the commentson the issue and add a little tooltip that will pop-up when you hover over a link to a Jira issue.
The pop-up should contain a "quick view" of information about the target issue (similar to the example shown in the followingimage) so that you do not have to click the issue's link to see this information.
You can achieve this by using aWeb Resource Context.This lets your app put JavaScript just on the View Issue page of Jira.
Define the Web Resource Context in the
atlassian-plugin.xml
file:12
<web-resource key="remote-link" name="Remote Issue Linking"> <dependency>com.atlassian.auiplugin:ajs</dependency> <resource name="java-demo-plugin.js" type="download" location="js/java-demo-plugin.js"/> <context>jira.view.issue</context></web-resource>
Have
java-demo-plugin.js
look in the comment body for URLs that "look like" they might point to Jira issues.Obtain the JSON representation of the issue using Jira's REST API, do some quick formatting on it, and putit into anAUI InlineDialog.
12define('issue-hover', ['ajs'], function(AJS){ AJS.toInit(function() { var i = new Date().getTime(); AJS.$("#issue_actions_container").find('.action-body a').each(function() { if (this.href.match(/\/browse\/[A-Z]+\-\d+$/)) { var split = this.href.split('/browse/'); var base = split[0]; var key = split[1]; var options = { cacheContent: true, onHover: true, showDelay: 400, hideDelay: 400, closeOthers: false, width: 500 } var draw = function(contents, trigger, showPopup) { AJS.$.getJSON(base + '/rest/api/latest/issue/' + key, function(data) { var fields = data["fields"]; contents.empty(); contents.append( "<ul class=\"item-details\">" + "<li>" + "<dl><dt>Summary: </dt>" + "<dd>" + fields["summary"] + "</dd></dl>" + "<dl><dt>Type: </dt>" + "<dd>" + fields["issuetype"]["name"] + "</dd></dl>" + "<dl><dt>Priority: </dt>" + "<dd>" + fields["priority"]["name"] + "</dd></dl>" + "<dl><dt>Status: </dt>" + "<dd>" + fields["status"]["name"] + "</dd></dl>" + "<dl><dt>Assignee: </dt>" + "<dd>" + fields["assignee"]["name"] + "</dd></dl>" + "<dl><dt>Description: </dt>" + "<dd>" + fields["description"] + "</dd></dl>" + "</li></ul>"); contents.append("<form id=\"add-watch\" name=\"watch\" action=\"\">"); AJS.$("<input type=\"button\" name=\"button\" value=\"Watch\"/>").click(function() { // We don't actually know our own username...and we need it to add a Watcher. So we get it from the // "current user" resource AJS.$.getJSON(base + '/rest/auth/latest/session', function(data) { AJS.$.ajax({ type: "POST", url: base + "/rest/api/latest/issue/" + key + "/watchers", data: "\""+ data['name']+ "\"", dataType: "json", contentType: "application/json" }) }) }).appendTo(contents); contents.append("</form>"); showPopup() }) }; AJS.InlineDialog(AJS.$(this), "issue-linking-" + (i++), draw, options) } }) })});require('issue-hover');
(Video) JIRA REST API Tutorial - JQL Basic
You can view the full demo app onBitbucket.