Bulk move work items with the Jira cloud REST API

Platform Notice: Cloud Only - This article only applies to Atlassian apps on the cloud platform.

Summary

Bulk move Jira cloud work items using the REST API, including tips for handling hierarchies and updating request types via script.

Solution

For this scenario, we will be utilizing the following endpoint: Jira Cloud platform REST API - Bulk Move work items.

The Bulk Move REST endpoint requires the complete list of work-item keys/IDs and does not automatically include child work items. There is no single "move this item and all descendants" operation.

Key Points:

  • Bulk Move API: You can move many work items simultaneously, but you must provide the complete list of work item keys/IDs. The API does not recursively include a parent's child work items.

  • Endpoint: Jira Cloud REST API — Bulk move work items

  • Hierarchy Awareness: To move a parent + children: first query all descendants (JQL / issue-search API), collect their keys, then pass them all to the bulk-move call.

  • No Single Hierarchy Move: No built-in "move this work item and all its descendants" operation exists. You must orchestrate this in your integration or script.

  • N:1 is supported (many types → one target project/type), but preserving hierarchy in one atomic call is not.

  • Multiple Calls May Be Needed: For complex hierarchies (for example, epics with stories and subtasks), you may need to perform multiple bulk move calls—one for each work item type or hierarchy level.

Parameters of the Endpoint:

inferClassificationDefaults

If true, when work items are moved into this target group, they will adopt the target project's default classification if they don't already have one. If they have a classification, it will remain the same after the move. Leave targetClassification empty when using this.

If false, you must provide a targetClassification mapping for each classification associated with the selected work items.

inferFieldDefaults

If true, values from the source work items will be retained for the mandatory fields in the destination project's field configuration. The targetMandatoryFields property shouldn't be defined.

If false, the user must set values for the mandatory fields in the destination project's field configuration. Provide input by defining the targetMandatoryFields property.

inferStatusDefaults

If true, the statuses of work items being moved into this target group that are not present in the target workflow will be set to the target workflow's default status (see below). Leave targetStatus empty when using this.

If false, you must provide a targetStatus for each status not present in the target workflow. 

Limitations:

  • Moving the work item of type A to work type B in the same project or a different project: SUPPORTED.

  • Moving multiple work items of type A in one or more projects to multiple work items of type B in one of the source projects or a different project: SUPPORTED.

  • Moving work items of multiple types in one or more projects to work items of a single work type in one of the source projects or a different project: SUPPORTED. For example, work items of story and task work types in projects 1 and 2 could be moved to work items of task work type in project 3.

  • Moving a standard parent work item of type A with its multiple subtask work types in one project to a standard work item of type B and multiple subtask work types in the same project or a different project: SUPPORTED.

  • Moving standard work items with their subtasks to a parent work item in the same project or a different project without losing their relation: SUPPORTED.

  • Moving an epic work item with its child work items to a different project without losing their relation: SUPPORTED. This use case is supported by multiple requests. Move the epic in one request, then the children in a separate request with the target parent set to the epic work item ID.

The example script provided is intended for demonstration purposes only and is not officially supported by Atlassian. If you choose to use or modify this script, please do so at your own risk, as Atlassian Support can’t assist with troubleshooting, maintenance, or customization of example scripts. For official support, please refer to Atlassian’s supported products and services.

{ "sendBulkNotification": true, "targetToSourcesMapping": { "<targetPRojectKey>,<targetProjectID>": { "inferClassificationDefaults": false, "inferFieldDefaults": false, "inferStatusDefaults": false, "inferSubtaskTypeDefault": true, "issueIdsOrKeys": [ "<destinationProjectWorkItem>", "<destinationProjectWorkItem>" ], "targetClassification": [ { "classifications": { "5bfa70f7-4af1-44f5-9e12-1ce185f15a38": [ "bd58e74c-c31b-41a7-ba69-9673ebd9dae9", "-1" ] } } ], "targetMandatoryFields":<optional_to_observe_the_usage> [ { "fields": { "summary": { "retain": false, "type": "raw", "value": [ "<test summary>" ] } } } ], "targetStatus": [ { "statuses": { "10003"<target status id>: [ "10004"<source status id> ], "1": [ "10018" ] } } ] } } }

What about the request types:

You will need the following script to update the request type of newly moved work items.

import requests from requests.auth import HTTPBasicAuth JIRA_URL = "https://your-domain.atlassian.net" API_TOKEN = "your_api_token" EMAIL = "service-account@your-domain.com" REQUEST_TYPE_FIELD = "customfield_10050" # Replace with your actual field ID REQUEST_TYPE_VALUE = "ithelp/getithelp" # Replace with your actual portalkey/requesttypekey for issue_key in issue_keys: update_url = f"{JIRA_URL}/rest/api/3/issue/{issue_key}" update_payload = { "fields": { REQUEST_TYPE_FIELD: REQUEST_TYPE_VALUE } } response = requests.put( update_url, json=update_payload, auth=HTTPBasicAuth(EMAIL, API_TOKEN), headers={"Accept": "application/json", "Content-Type": "application/json"} ) if response.ok: print(f"Request type set for {issue_key}") else: print(f"Failed to set request type for {issue_key}: {response.text}")

Steps to execute the script:

Bulk move is not easily reversible — run the script against a handful of test issues and verify the target project/request type before moving a full hierarchy.

  1. Create the script using the above template.

  2. Fill in the parameters based on your environment.

  3. Save the script.

  4. Open a terminal and navigate to the script location.

  5. Use the following command to execute the script.

    1. python3 bulkMove.py

Conclusion

You can utilize the Jira cloud REST API endpoint to trigger a bulk work item move action without navigating through the UI for external integrations.

If you have any further questions, please contact Atlassian Cloud support.

Resources

The Jira Cloud platform REST API

Updated on July 24, 2026

Still need help?

The Atlassian Community is here for you.