A story leaves the sprint in its second week, and in the review someone asks what was taken out, and when. Jira has the answer in every issue's history, but not as a query. The JQL people try first fails: sprint was "Sprint 41" answers History searches do not support the 'sprint' field, and sprint != "Sprint 41" returns every issue that is not in the sprint now, which is nearly every issue on the site. JRACLOUD-75868, the request to search for issues added to and removed from a sprint, has been open since January 2018 with more than 1,400 votes. Here are the ways teams answer the question today, what each one can and cannot do, and when each is enough. Disclosure up front: I am building the last one.
Open the board, then Reports, Sprint Report, and pick the sprint. The last section, Issues Removed From Sprint, lists the issues that were in the sprint after it started and were no longer in it when it was completed. It is exact, it covers every closed sprint, and it costs nothing.
Three details matter when you compare it with anything else. An issue that was added after the start and removed again appears only in this section, not among the additions marked with an asterisk. Subtasks are left out. And the issues you move to the backlog when you complete a sprint are not completed, not removed: completing a sprint leaves the closed sprint in their Sprint field, so they were never taken out of it.
What it cannot do is what a page cannot do: no filter, no column, no dashboard gadget, no automation, no export beyond copy and paste, and one sprint at a time. For a retrospective on one sprint it is the right tool. For "how much did we pull out of each sprint this quarter" it means opening a report per sprint and counting.
For one disputed story, the issue's History tab shows every change to the Sprint field with the value before and after, the time and the person who made it. That is the most precise answer Jira gives, and it is the only one of the free ways that says who removed the issue. It is also one issue at a time, so nobody rebuilds a sprint this way.
If the numbers have to end up in a spreadsheet or a BI tool, the Sprint Report page reads GET /rest/greenhopper/1.0/rapid/charts/sprintreport?rapidViewId=<board id>&sprintId=<sprint id>, and its contents.puntedIssues is the removed list. A small script that walks a board's closed sprints (GET /rest/agile/1.0/board/<board id>/sprint?state=closed) can fill a table overnight, and the numbers agree with the report because they are the report's.
The limits: the endpoint is internal and undocumented, so it can change without notice; it takes one call per sprint; and it gives the list without the time or the person, which live in each issue's changelog (POST /rest/api/3/changelog/bulkfetch with the Sprint field, up to 1,000 issues per call). Someone has to own the script and the schedule.
From the day it exists, a rule can keep the record the report computes after the fact:
{{now}}, and set "Sprint log" to its existing text followed by a new line such as {{now.jiraDate}} {{initiator.displayName}}: {{fieldChange.fromString}} to {{fieldChange.toString}}.It works, and it records who made the change, which the report does not. The limits are real, though. Automation cannot tell whether the sprint an issue left was active, so a move between two future sprints is logged exactly like a removal from the running sprint, and someone has to read the log to tell them apart. A log is text, so "removed from Sprint 41" becomes a text search rather than a filter you can trust. Nothing before the rule's first run is recorded. And every run counts against the site's monthly automation allowance (100 runs a month on Free, 1,700 site-wide on Standard, 1,000 per user on Premium at the time of writing).
The two big JQL toolkits cover the other half of the question on Jira Cloud. Appfire's JQL Search Extensions has addedToSprintAfterStart(board, sprint), and ScriptRunner has addedAfterSprintStart(board, sprint) on its Enhanced Search screen. Neither documents a function for removals on Cloud: ScriptRunner's removedAfterSprintStart belongs to its self-hosted edition, and its Cloud documentation lists it among the functions that are not available. If you already own either app, check its current function list before you look further.
Sprint Ledger is a Forge app that reconstructs the membership history of every sprint on the site from the changelog, keeps it current from Jira's events, and answers the removal question the ways the free methods cannot:
issue in removedFromSprint("Sprint 41") returns the issues taken out after the start and before the completion. Without an argument it means the active sprints, and a name with * covers a series: issue in removedFromSprint("Team A Sprint *").issue in removedFromSprint("Sprint 41") AND issue not in committedTo("Sprint 42") is what was dropped and not picked back up in the next sprint."Sprint removed (Ledger)" >= -14d is an ordinary filter and a sortable column.It is retroactive for every sprint the site has run and follows the Sprint Report's definitions, with the differences documented. One of them is deliberate: an issue added after the start and removed again counts as both added and removed, because reporting on scope change needs both. It runs entirely inside Atlassian's infrastructure, so no issue data leaves Jira. It is on the Atlassian Marketplace, priced at about $50 a month for a 100-user site and free for sites with up to 10 users.
| Sprint Report | Issue history | Report endpoint | Automation log | Sprint Ledger | |
|---|---|---|---|---|---|
| Removed issues of a closed sprint | yes, on a page | one issue at a time | yes, by script | from the rule's first run | yes |
| Every past sprint at once | no | no | a script over all sprints | no | yes |
| A JQL filter, board or dashboard | no | no | no | text search on the log | yes |
| When it was removed | no | yes | from the changelog | yes | yes |
| Who removed it | no | yes | from the changelog | yes | stored; the export that shows it is in progress |
| Setup | none | none | a script and a schedule | an afternoon | install and wait for the reconstruction |
| Cost for 100 users | free | free | free | free (rule runs) | about $50 a month |
If you look at one sprint in a retrospective, the Sprint Report is enough. If a single story is in dispute, its history is enough. If the numbers must reach a BI tool and someone can own a script, the endpoint is enough. If you only care from today on and can live with reading a log, the automation rule is enough. If you want removals as a query and a column for every sprint the site has run, that is the gap Sprint Ledger is meant to fill, and I would like to hear where it is wrong: support@dyordanov.com.
The other half of the question, what was added after the start, has its own comparison: Four ways to find issues added after sprint start in Jira Cloud. Sprint dates as a filter and a column are covered in Sprint start and end dates in JQL and as columns.