Jira REST API examples (2024)

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 Data Center REST API is here:Jira Data Center REST API.If you've never used the Jira REST APIs before, 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 thecreatemetaresource 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 usingthecreatemetaresource.

For example:

12
http://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:

12
http://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:

12
http://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:

12
http://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.

12
http://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
12
curl \ -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
12
curl \ -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
  • TheissueTypefield must correspond to a sub-task issue type(you can use/issue/createmetato discover sub-task issue types).
  • You must provide aparentfield in the issue create request containing the ID orkeyof 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 or key of the parent issue.
Request
12
curl \ -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
12
curl \ -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
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:

12
curl \ -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"}

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:

  1. Editing an issue by updating the value of a field. Examples:
    • Assigning an issue to a user.
    • Updating multiple fields in one request.
  2. 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 theeditmetaresource. For example:

12
http://localhost:8080/rest/api/2/issue/JRA-13/editmeta

Note that theeditmetaresource 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
12
curl \ -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
12
curl \ -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
12
curl \ -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
12
curl \ -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
12
curl \ -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
12
curl \ -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:

  1. Adding a comment using thecommentresource.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.
  2. 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
12
curl \ -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
12
curl \ -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" }}

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
12
curl \ -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
12
curl \ -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
12
curl \ -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:startAtandmaxResults.These parameters specifythe starting issue returned in the JQL results and the number of issues from that starting issue respectively.

Request
12
curl \ -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 byclause in the JQL query itself(not via a URL parameter in your REST API call).

Request
12
curl \ -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
12
curl \ -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 APIsearchresource instead.Any additional URL parameters (apart from theurlparameter) described above must be included in yourJSON-formatted JQL query.

Request
12
curl \ -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 thecreatemetaresource.

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
12
curl \ -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:

12
curl \ -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
12
curl \ -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
12
http://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
12
http://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
12
http://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:

12
http://localhost:8080/jira/rest/api/2/issue/createmeta/{projectIdOrKey}/issuetypes?startAt=0&maxResults=50

or

To look for list-issuetype-fields use:

12
http://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:

  1. You make an HTTP call.
  2. Get some data back.
  3. 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:

12
resource = 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.

12
fields = 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:

12
def 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:

12
python draw-chart.py --help

You can test this against your Jira site with:

12
python draw-chart.py --user=username --password=password --jira=<url-of-your-jira-site>

The output should look similar to:

12
Fetching 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.pngto show an image that should look something like this:

Jira REST API examples (1)

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.

Jira REST API examples (2)

You can achieve this by using aWeb Resource Context.This lets your app put JavaScript just on the View Issue page of Jira.

  1. 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>
  2. Havejava-demo-plugin.jslook in the comment body for URLs that "look like" they might point to Jira issues.

  3. Obtain the JSON representation of the issue using Jira's REST API, do some quick formatting on it, and putit into anAUI InlineDialog.

12
define('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');

You can view the full demo app onBitbucket.

Jira REST API examples (2024)
Top Articles
Latest Posts
Article information

Author: Carlyn Walter

Last Updated:

Views: 6580

Rating: 5 / 5 (50 voted)

Reviews: 89% of readers found this page helpful

Author information

Name: Carlyn Walter

Birthday: 1996-01-03

Address: Suite 452 40815 Denyse Extensions, Sengermouth, OR 42374

Phone: +8501809515404

Job: Manufacturing Technician

Hobby: Table tennis, Archery, Vacation, Metal detecting, Yo-yoing, Crocheting, Creative writing

Introduction: My name is Carlyn Walter, I am a lively, glamorous, healthy, clean, powerful, calm, combative person who loves writing and wants to share my knowledge and understanding with you.