Runbook: Bulk Delete Worklogs
Platform Notice: Data Center Only - This article only applies to Atlassian products on the Data Center platform.
Note that this KB was created for the Data Center version of the product. Data Center KBs for non-Data-Center-specific features may also work for Server versions of the product, however they have not been tested. Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.
*Except Fisheye and Crucible
Goal
This page aims to share script to Bulk delete worklogs that are no longer necessary on your Jira Cloud instance.
Documentation
Bulk Delete Issue Worklogs API
Get Data
Fetch the worklog IDs you plan to delete using Get Issue Worklogs API
use startedAfter and startedBefore parameters to narrow the timeframe (timestamps in milliseconds)
Example script in Python 3
1
2
3
4
5
6
7
8
9
def get_worklog_ids(issue_key, after=None, before=None):
url = f"{SITENAME}/rest/api/3/issue/{issue_key}/worklog?" \
f"maxResults=5000&" \
f"startedAfter={get_timestamp_in_milliseconds(after)}&" \
f"startedBefore={get_timestamp_in_milliseconds(before)}"
response = requests.get(url,
auth=(USER, PWD),
timeout=30)
return [worklog['id'] for worklog in response.json()['worklogs']]
Get Data by author
To delete worklogs authored by a specific user, custom filtering of results must be done, as the Get Issue Worklogs APIdoes not accept a user parameter.
Example script in Python 3 (by email address)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
def get_worklog_ids_by_emails(issue_key, emails, after=None, before=None):
url = f"{SITENAME}/rest/api/3/issue/{issue_key}/worklog?" \
f"maxResults=5000&" \
f"startedAfter={get_timestamp_in_milliseconds(after)}&" \
f"startedBefore={get_timestamp_in_milliseconds(before)}"
response = requests.get(url,
auth=(USER, PWD),
timeout=30)
worklog_ids = []
for worklog in response.json()['worklogs']:
if 'emailAddress' in worklog['author'] and worklog['author']['emailAddress'] in emails:
worklog_ids.append(worklog['id'])
return worklog_ids
Delete Data
Delete the worklogs by calling Bulk Delete Issue Worklogs API with IDs received from the previous call
You can specify either auto or leave option for the adjustEstimateAPI parameter
leave Leaves the estimate unchanged.
auto Reduces the estimate by the value of timeSpent in the worklogs.
Example script in Python 3
1
2
3
4
5
def bulk_remove_worklogs(issue_key, worklog_ids, adjust_estimate="auto"):
url = f"{SITENAME}/rest/api/3/issue/{issue_key}/worklog?adjustEstimate={adjust_estimate}"
body = {"ids": worklog_ids}
response = requests.delete(url, json=body, auth=(USER, PWD), timeout=30)
return response.status_code, response.text
Full script
The script will delete all worklogs on issue ISSUE_KEY started after STARTED_AFTER and before STARTED_BEFORE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import json
from datetime import datetime
import requests
USER = 'admin@yahoo.com'
PWD = 'prod_token'
SITENAME = "the instance address"
ISSUE_KEY = 'TEST-1'
# Adjust if you'd prefer to use a different format
DATE_TIME_FORMAT = '%Y-%m-%dT%H:%M:%S%z'
# Can be set to None
STARTED_AFTER = '2023-01-01T11:00:00+1100'
STARTED_BEFORE = '2024-01-01T11:00:00+1100'
def get_worklog_ids(issue_key, after=None, before=None):
url = f"{SITENAME}/rest/api/3/issue/{issue_key}/worklog?" \
f"maxResults=5000&" \
f"startedAfter={get_timestamp_in_milliseconds(after)}&" \
f"startedBefore={get_timestamp_in_milliseconds(before)}"
response = requests.get(url,
auth=(USER, PWD),
timeout=30)
return [worklog['id'] for worklog in response.json()['worklogs']]
def get_worklog_ids_by_emails(issue_key, emails, after=None, before=None):
url = f"{SITENAME}/rest/api/3/issue/{issue_key}/worklog?" \
f"maxResults=5000&" \
f"startedAfter={get_timestamp_in_milliseconds(after)}&" \
f"startedBefore={get_timestamp_in_milliseconds(before)}"
response = requests.get(url,
auth=(USER, PWD),
timeout=30)
worklog_ids = []
for worklog in response.json()['worklogs']:
if 'emailAddress' in worklog['author'] and worklog['author']['emailAddress'] in emails:
worklog_ids.append(worklog['id'])
return worklog_ids
def get_timestamp_in_milliseconds(date):
if not date:
return ''
return 1000 * int(datetime.strptime(date, DATE_TIME_FORMAT).timestamp())
def bulk_remove_worklogs(issue_key, worklog_ids, adjust_estimate="auto"):
url = f"{SITENAME}/rest/api/3/issue/{issue_key}/worklog?adjustEstimate={adjust_estimate}"
body = {"ids": worklog_ids}
response = requests.delete(url, json=body, auth=(USER, PWD), timeout=30)
return response.status_code, response.text
while True:
worklog_ids = get_worklog_ids(ISSUE_KEY, STARTED_AFTER, STARTED_BEFORE)
if len(worklog_ids) == 0:
print("No more worklogs to delete")
break
status, body = bulk_remove_worklogs(ISSUE_KEY, worklog_ids)
if status == 200:
print(f"Successfully deleted *some* worklogs, response \n\"{body}\"")
elif status == 204:
print(f"Successfully deleted {len(worklog_ids)} worklogs on issue {ISSUE_ID}")
else:
print(f"Received different status than HTTP 200/204 from the Bulk Delete endpoint, status {status}, response body \n\"{body}\"")
break
FAQ
Q. How many worklogs, at max, can be deleted at a time?
A. The limit, as described in the API docs, is 5000 worklogs.
Q. What are the various criteria that can be used to identify the worklogs to delete?
A. The Bulk Delete API can only accept worklog IDs. Those IDs must be fetched using one of the available APIs, e.g. the Get Issue Worklogs API
Q. What is the maximum time range to get worklog IDs?
A. The Get Issue Worklogs API does not limit the time range, as long as the timestamps are valid.
Q. Are worklogs deleted from a single issue at a time?
A. The worklog must be from a single issue, specified in the {issueIDOrKey} API parameter.
Q. What if I delete worklogs by mistake? Can i restore them back?
A. The worklogs cannot be restored so the delete operations must be performed cautiously.
Q. Does the Bulk Delete API update issue change history?
A. Yes, issue change history will be updated.
Was this helpful?