Is it possible to get the history of an issue using the JIRA REST API?
Thanks.
Depending on the kind of history you're looking for this is possible.
http://docs.atlassian.com/jira/REST/latest/#id162178
Another great way to discover the JIRA rest api is via the rest api browser, which is included in the developers toolbox or a JIRA development:
- https://developer.atlassian.com/display/RAB/Overview+of+the+Atlassian+REST+API+Browser- https://marketplace.atlassian.com/plugins/com.atlassian.devrel.developer-toolbox-plugin
Cheers
Nope. You can find available methods here: http://docs.atlassian.com/jira/REST/latest/
I would like to get the change history for an issue, i.e. the information shown on an issue's 'History' tab:
I have tried to do this using the Python wrapper to the REST API as follows:
from jira.client import JIRA import json options = { 'server': 'https://yada-yada.atlassian.net', } jira = JIRA(options, basic_auth=(USERNAME, PASSWORD)) projects = jira.projects() issue = jira.issue('INF-119') print json.dumps(issue.raw)
The result is this:
{ "key": "INF-119", "fields": { "comment": { "total": 0, "startAt": 0, "comments": [], "maxResults": 0 }, "customfield_10700": null, "customfield_10703": null, "customfield_10702": null, "customfield_10705": null, "customfield_10704": null, "customfield_10600": null, "customfield_10601": null, "labels": [], "aggregatetimespent": null, "watches": { "self": "https://yada-yada.atlassian.net/rest/api/2/issue/INF-119/watchers", "watchCount": 1, "isWatching": false }, "assignee": { "displayName": "Chris Young", "name": "chris.young", "self": "https://yada-yada.atlassian.net/rest/api/2/user?username=chris.young", "avatarUrls": { "48x48": "https://yada-yada.atlassian.net/secure/useravatar?ownerId=chris.young&avatarId=10300", "16x16": "https://yada-yada.atlassian.net/secure/useravatar?size=small&ownerId=chris.young&avatarId=10300" }, "emailAddress": "Chris.Young@yada-yada.com", "active": true }, "lastViewed": null, "issuelinks": [], "worklog": { "worklogs": [], "total": 0, "startAt": 0, "maxResults": 0 }, "customfield_10400": null, "aggregateprogress": { "progress": 0, "total": 0 }, "environment": null, "votes": { "hasVoted": false, "self": "https://yada-yada.atlassian.net/rest/api/2/issue/INF-119/votes", "votes": 0 }, "fixVersions": [], "priority": { "iconUrl": "https://yada-yada.atlassian.net/images/icons/priority_critical.gif", "self": "https://yada-yada.atlassian.net/rest/api/2/priority/2", "name": "Critical", "id": "2" }, "timespent": null, "customfield_10109": null, "aggregatetimeestimate": null, "progress": { "progress": 0, "total": 0 }, "duedate": null, "attachment": [], "status": { "id": "6", "iconUrl": "https://yada-yada.atlassian.net/images/icons/status_closed.gif", "self": "https://yada-yada.atlassian.net/rest/api/2/status/6", "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed" }, "updated": "2012-10-29T13:53:58.317+0000", "customfield_10200": [], "subtasks": [], "description": null, "reporter": { "displayName": "Chris Young", "name": "chris.young", "self": "https://yada-yada.atlassian.net/rest/api/2/user?username=chris.young", "avatarUrls": { "48x48": "https://yada-yada.atlassian.net/secure/useravatar?ownerId=chris.young&avatarId=10300", "16x16": "https://yada-yada.atlassian.net/secure/useravatar?size=small&ownerId=chris.young&avatarId=10300" }, "emailAddress": "Chris.Young@yada-yada.com", "active": true }, "customfield_10103": null, "customfield_10102": null, "customfield_10101": null, "customfield_10100": "3_*:*_1_*:*_4111_*|*_1_*:*_1_*:*_10925_*|*_6_*:*_1_*:*_0_*|*_10011_*:*_1_*:*_4469_*|*_10013_*:*_1_*:*_2206_*|*_10009_*:*_1_*:*_2121", "timeestimate": null, "timeoriginalestimate": null, "customfield_10000": "3659", "aggregatetimeoriginalestimate": null, "customfield_10300": "3656", "customfield_10701": null, "created": "2012-10-29T13:53:34.485+0000", "versions": [], "resolutiondate": "2012-10-29T13:53:58.306+0000", "summary": "Dummy ticket to see if we can extract change history", "project": { "self": "https://yada-yada.atlassian.net/rest/api/2/project/INF", "avatarUrls": { "48x48": "https://yada-yada.atlassian.net/secure/projectavatar?pid=10200&avatarId=10010", "16x16": "https://yada-yada.atlassian.net/secure/projectavatar?size=small&pid=10200&avatarId=10010" }, "id": "10200", "key": "INF", "name": "Infrastructure" }, "timetracking": {}, "components": [], "issuetype": { "name": "Infrastructure", "self": "https://yada-yada.atlassian.net/rest/api/2/issuetype/9", "iconUrl": "https://yada-yada.atlassian.net/images/icons/genericissue.gif", "subtask": false, "id": "9", "description": "Things that the team will need to spend time working on but which don't actually deliver any value." }, "resolution": { "self": "https://yada-yada.atlassian.net/rest/api/2/resolution/1", "id": "1", "name": "Fixed", "description": "A fix for this issue is checked into the tree and tested." }, "workratio": -1 }, "self": "https://yada-yada.atlassian.net/rest/api/2/issue/15913", "id": "15913", "expand": "renderedFields,names,schema,transitions,operations,editmeta,changelog" }
So, unless I'm missing something it looks like you cannot access an issue's history via the REST API.
My work around is to screen scrape this information via selenium.
Before I go down this path can someone tell me if I am missing a trick and there is a less brittle / time consuming way of doing this?
I am using the hosted JIRA fo which AFAIK the only API access is via REST.
Thanks
Chris
Hi Chris, i think this is what you are looking for
https://jira.atlassian.com/browse/JRA-27692?focusedCommentId=303842&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-303842
https://jira.atlassian.com/rest/api/2/issue/JRA-22053?expand=changelog
In that example, you can see that one of the top-level attributes is "expand", and it includes the expandable name "changelog". If you add<tt>?expand=changelog</tt> then JIRA will include the changelog (issue history) in the response.
Jonny, that is fantastic. It works! Many Thanks.
jira = JIRA(options, basic_auth=(USERNAME, PASSWORD)) issue = jira.issue('FOO-100', expand='changelog') changelog = issue.changelog for history in changelog.histories: for item in history.items: if item.field == 'status': print 'Date:' + history.created + ' From:' + item.fromString + ' To:' + item.toString
Gives me:
Date:2012-10-23T09:49:41.197+0100 From:Open To:Queued Date:2012-10-23T09:49:43.838+0100 From:Queued To:In Progress Date:2012-10-23T09:49:45.390+0100 From:In Progress To:Blocked Date:2012-10-29T16:06:36.733+0000 From:Blocked To:In Progress Date:2012-10-31T16:47:40.191+0000 From:In Progress To:Peer Review Date:2012-10-31T16:47:41.783+0000 From:Peer Review To:Customer Approval
Which is exactly what I wanted!
Now I can get data on cycle time, figure out where our bottlenecks are and see which tickets are dropping out of our workflow after we have commited to working on them.
Brilliant.
Many Thanks!
Hi,
I'm using the REST interface in Excel with VBA.
I know that expand=changelog should do the job, but I get the same result either with this expresson or without it.
I attached my test code and both DEebig.Print deliver exactly the same result
Any idea what's wrong?
Dieter
Private JiraService As New MSXML2.XMLHTTP60 Private JiraAuth As New MSXML2.XMLHTTP60 Public sRestAntwort As String Sub JiraAccess() With JiraAuth .Open "POST", "http://JiraServer/rest/auth/1/session", False .setRequestHeader "Content-Type", "application/json" .setRequestHeader "Accept", "application/json" .Send " {""username"" : ""user"", ""password"" : ""passwd""}""" sCookie = "JSESSIONID=" & Mid(sErg, 42, 32) & "; Path=/Jira" End With With JiraService .Open "GET", "http://JiraServer/rest/api/2.0.alpha1/issue/JRA-444", False .setRequestHeader "Content-Type", "application/json" .setRequestHeader "Accept", "application/json" .setRequestHeader "Set-Cookie", sCookie .Send sRestAntwort = .responseText Debug.Print "*************************" Debug.Print .responseText Debug.Print "*************************" End With With JiraService .Open "GET", "http://JiraServer/rest/api/2.0.alpha1/issue/JRA-444?expand=changelog", False .setRequestHeader "Content-Type", "application/json" .setRequestHeader "Accept", "application/json" .setRequestHeader "Set-Cookie", sCookie .Send sRestAntwort = .responseText Debug.Print "*************************" Debug.Print .responseText Debug.Print "*************************" End With With JiraAuth .Open "DELETE", "http://JiraServer/rest/auth/1/session", False .Send End With End Sub
OK, I guess I found the problem.
We are using Jira 4.3.3 and it looks like, that this interface is not supported for that version.
Also '?fields' does not work.
So any other idea how I can get the change history for an item or can get access to single fields with my version?
Hi Chris,
Can you please post your full code so that i can have a better exposer of REST, since i am a new user to it.
It will be really helpfull for my work experience with JIRA.
I am working on same task to retrieve Issue History with a Jira ticket.
Thanks !
I had to use getattr(item, 'from') instead of item.from due to reserved keywords in Python
Interestingly there is an expand parameter for the search method, so it ought to be possible to retrieve issues with the changelog directly from a search. At the moment with jira-python I'm still having to do a second call such as
issue = jira.issue('FOO-100', expand='changelog')
issue = jira.issue(
'FOO-100'
,
expand
=
'changelog'
)
It would be great to avoid the second network round trip, but performance was not as bad as I thought. I ended up running a search, getting the changelog for each issue and updating the reporter at a rate of about one issue per second.
Hello Chris, could you tell me how can i get status of field "assignee" from someone to someone? and how can i get comment from jira?
Hi Chris, can I have a sample of code in Excel VBA format?
Here are all possible item types:
item_fields = { 'Epic Link', 'Link', 'Notes for QA', 'Rank', 'WorklogId', 'assignee', 'description', 'status', 'summary', 'timeestimate', 'timespent'}
Hello, in PowerShell I created this function :
function Get-JiraIssueChangelog {
Param ([Parameter(Mandatory)]$Issue,[Parameter(Mandatory)]$Server,[Parameter(Mandatory)]$Headers)#https://community.atlassian.com/t5/Jira-questions/Is-it-possible-to-get-the-issue-history-using-the-REST-API/qaq-p/510094<#$uri = “https://xxx.atlassian.net/rest/api/latest/issue/YYYY-100/changelog?startAt=0&maxResults=100”$projectIssuePage = Invoke-RestMethod $uri -Method ‘GET’ -Headers $headers$projectIssuePage#>try {return (Invoke-RestMethod -Method Get -Uri "$Server/rest/api/2/search?jql=key=$Issue&expand=changelog" -Headers $Headers).issues.changelog.histories;#Invoke-RestMethod -Method Get -Uri "$Server/rest/api/latest/issue/$Issue/changelog?startAt=0&maxResults=100” -Headers $Headers;}catch {$_}}
function Get-JiraIssueTransition {
Param ([Parameter(Mandatory)]$Issue,[Parameter(Mandatory)]$Server,[Parameter(Mandatory)]$Headers)
$object_Histories = Get-JiraIssueChangelog -Issue $Issue -Server $Server -Headers $Headers;
$object_Transitions = @();
foreach ($object_History in $object_Histories){foreach($object_item in $object_History.items){if($object_item.field -EQ 'status'){$object_Transitions += [pscustomobject]@{author = $object_History.author.namedate = (Get-Date $object_History.created)to = $object_item.toStringfrom = $object_item.fromString}}}}
return $object_Transitions;}
The endpoint
/rest/api/latest/issue/YYYY-100/changelog
does not exist on my instance. Maybe it was introduces in a later version. However, I also cannot find this endpoint in the latest documentation.
Jira 8.13.1 (atlassian.com)
Where did you find this endpoint?
Definitely add ?expand=changelog as Jonny Xu added below, I didn't see column changes without it!
Doing God's work here, thank you so much for this
it works for me, at 2024, so much appreciate
It looks like you're new here. Sign in or register to get started.