This workflow corresponds to n8n.io template #14218 — we link there as the canonical source.
This workflow follows the HTTP Request → n8n recipe pattern — see all workflows that pair these two integrations.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"id": "2FTV8hcwvH5owM2J",
"name": "util.UpdateMigratedWorkflows",
"tags": [],
"nodes": [
{
"id": "ccdf19d1-7ec6-4577-9677-14276b5ffef4",
"name": "When clicking \u2018Execute workflow\u2019",
"type": "n8n-nodes-base.manualTrigger",
"position": [
-128,
-256
],
"parameters": {},
"typeVersion": 1
},
{
"id": "a24c2a20-d203-4207-9257-e08794aac97c",
"name": "orig datatables",
"type": "n8n-nodes-base.httpRequest",
"position": [
352,
-256
],
"parameters": {
"url": "={{ $(\"config\").item.json.orig_url }}/api/v1/data-tables",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "n8nApi"
},
"typeVersion": 4.4
},
{
"id": "06d29ada-aa31-4208-82c1-a6edcc20319c",
"name": "orig workflows",
"type": "n8n-nodes-base.httpRequest",
"position": [
544,
-256
],
"parameters": {
"url": "={{ $(\"config\").item.json.orig_url }}/api/v1/workflows",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "n8nApi"
},
"typeVersion": 4.4
},
{
"id": "830b73ef-e4ab-4449-afe8-2c2518e8d864",
"name": "new datatables",
"type": "n8n-nodes-base.httpRequest",
"position": [
768,
-256
],
"parameters": {
"url": "={{ $(\"config\").item.json.new_url }}/api/v1/data-tables",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "n8nApi"
},
"typeVersion": 4.4
},
{
"id": "cc90dbab-a7ed-4ee4-b1e4-625b8a17f663",
"name": "new workflows",
"type": "n8n-nodes-base.httpRequest",
"position": [
992,
-256
],
"parameters": {
"url": "={{ $(\"config\").item.json.new_url }}/api/v1/workflows",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "n8nApi"
},
"typeVersion": 4.4
},
{
"id": "67d139dc-a09b-4f98-ae18-6c71081b32eb",
"name": "config",
"type": "n8n-nodes-base.code",
"position": [
96,
-256
],
"parameters": {
"jsCode": "\nconst orig_url = \"\"; //eg. https://your-url.app.n8n.cloud\nconst new_url = \"\"; //eg. https://n8n.other-url.hstgr.cloud\n\nreturn {\n json: {\n orig_url: orig_url,\n new_url: new_url\n }\n};"
},
"typeVersion": 2
},
{
"id": "5152b84d-c7ea-4f39-aa3f-61d525fdb92e",
"name": "map",
"type": "n8n-nodes-base.code",
"position": [
1216,
-256
],
"parameters": {
"jsCode": "// 1. Get the array of objects from the previous node\nconst originalData = $('orig datatables').first().json.data;\nconst newData = $('new datatables').first().json.data;\nconst originalFlows = $('orig workflows').first().json.data;\nconst newFlows = $('new workflows').first().json.data;\n\n// 1. Grab the existing map from your previous node \n// (Replace 'First Map Node' with the actual name of your node)\nconst existingMap = {};\n\noriginalData.forEach(item => {\n const entityName = item.name;\n const new_vars = {\n orig_id: item.id\n }\n\n if (entityName) {\n if (existingMap[entityName]) { \n existingMap[entityName] = {\n ...existingMap[entityName], \n ...new_vars \n };\n } else {\n existingMap[entityName] = new_vars;\n }\n }\n});\n\nnewData.forEach(item => {\n const entityName = item.name;\n const new_vars = {\n new_id: item.id\n }\n\n if (entityName) {\n if (existingMap[entityName]) { \n existingMap[entityName] = {\n ...existingMap[entityName], \n ...new_vars \n };\n } else {\n existingMap[entityName] = new_vars;\n }\n }\n});\n\noriginalFlows.forEach(item => {\n const entityName = item.name;\n const new_vars = {\n orig_id: item.id\n }\n\n if (entityName) {\n if (existingMap[entityName]) { \n existingMap[entityName] = {\n ...existingMap[entityName], \n ...new_vars \n };\n } else {\n existingMap[entityName] = new_vars;\n }\n }\n});\n\nnewFlows.forEach(item => {\n const entityName = item.name;\n const new_vars = {\n new_id: item.id,\n }\n\n if (entityName) {\n if (existingMap[entityName]) { \n existingMap[entityName] = {\n ...existingMap[entityName], \n ...new_vars \n };\n } else {\n existingMap[entityName] = new_vars;\n }\n }\n});\n\n// 4. Output the newly updated, enriched map\nreturn {\n json: {\n entity_map: existingMap\n }\n};"
},
"typeVersion": 2
},
{
"id": "9327e51c-6a05-4e9c-883a-d1a13250bea2",
"name": "update flow nodes",
"type": "n8n-nodes-base.code",
"position": [
1440,
-256
],
"parameters": {
"jsCode": "// 1. Get the array of objects from the previous node\nconst entityMap = $(\"map\").first().json.entity_map;\nconst newFlows = $('new workflows').first().json.data;\n\n// 2. Create a reverse lookup dictionary: orig_id -> new_id\n// This makes swapping the IDs instantly fast and ignores the names entirely\nconst reverseIdMap = {};\nfor (const entityName in entityMap) {\n const ids = entityMap[entityName];\n if (ids.orig_id && ids.new_id) {\n // Force strings just in case n8n handles the IDs as numbers\n reverseIdMap[ids.orig_id.toString()] = ids.new_id.toString();\n }\n}\n\n// 3. Define the specific nodes we want to target\nconst targetNodeTypes = [\n 'n8n-nodes-base.executeWorkflow',\n 'n8n-nodes-base.dataTable'\n];\n\n// 4. Helper Function: Recursively search parameters and swap IDs\n// This ensures we catch the ID even if n8n nests it inside an \"options\" object\nfunction replaceOldIds(parameters, idMap) {\n for (const key in parameters) {\n if (typeof parameters[key] === 'object' && parameters[key] !== null) {\n replaceOldIds(parameters[key], idMap);\n } else if (typeof parameters[key] === 'string' || typeof parameters[key] === 'number') {\n const currentValue = parameters[key].toString();\n // If the current parameter value is an old ID in our map, swap it!\n if (idMap[currentValue]) {\n parameters[key] = idMap[currentValue]; \n }\n }\n }\n}\n\n// 5. Loop through the workflows and apply the updates\nvar jsonFlows = [];\nnewFlows.forEach(flow => {\n // Ensure the flow actually has a nodes array\n if (flow.nodes && Array.isArray(flow.nodes)) {\n \n flow.nodes.forEach(node => {\n // If the node type matches our targets, scan its parameters\n if (targetNodeTypes.includes(node.type) && node.parameters) {\n replaceOldIds(node.parameters, reverseIdMap);\n }\n });\n \n }\n\n const flow_json = {...flow};\n\n // 2. THE FIX: Clean the payload for the strict API schema\n // Reset settings to an empty object to clear out unrecognized legacy properties\n flow_json.settings = {};\n \n // Delete read-only properties that the API will reject on a PUT request\n delete flow_json.id;\n delete flow_json.createdAt;\n delete flow_json.updatedAt;\n delete flow_json.versionId;\n delete flow_json.active; // (Optional: safely prevents accidentally activating half-migrated flows)\n\n jsonFlows.push({\n id: flow.id,\n workflow: JSON.stringify(flow_json)\n })\n});\n\n\n// 6. Output the updated workflows\n// Returning it as 'updatedFlows' attached to the JSON\nreturn jsonFlows;"
},
"typeVersion": 2
},
{
"id": "11f2f9e7-4a81-4339-af52-2e8d6493f2fd",
"name": "update new workflows",
"type": "n8n-nodes-base.n8n",
"position": [
1712,
-256
],
"parameters": {
"operation": "update",
"workflowId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"requestOptions": {},
"workflowObject": "={{ $json.workflow }}"
},
"typeVersion": 1
},
{
"id": "06dc6231-33ae-4ab7-861d-278b3272a6b7",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
16,
-544
],
"parameters": {
"color": 7,
"width": 256,
"height": 464,
"content": "## Config\nThis node just stores the urls as variables so you only have to update them once.\n\n**Instructions**\n- Set the orig_url to be the path to your original n8n install\n- Set the new_url to be the path to your new n8n install"
},
"typeVersion": 1
},
{
"id": "6bb19ec8-241a-45d1-8078-5f4084549b28",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
304,
-544
],
"parameters": {
"color": 7,
"width": 384,
"height": 464,
"content": "## Get Originals\nThese nodes grab all datatables and workflows from the original n8n install via the n8n API.\n\n**Instructions**\n- You'll need to create an n8n credential for your **original** n8n instance and select that in these 2 nodes."
},
"typeVersion": 1
},
{
"id": "334b94ce-ded5-429e-b62e-c1cd4c38428f",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
736,
-544
],
"parameters": {
"color": 7,
"width": 384,
"height": 464,
"content": "## Get New\nThese nodes grab all datatables and workflows from the new n8n install via the n8n API.\n\n**Instructions**\n- You'll need to create an n8n credential for your **new** n8n instance and select that in these 2 nodes."
},
"typeVersion": 1
},
{
"id": "87dfee3f-3ebe-4f87-9cb6-40f14505a2b7",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1184,
-544
],
"parameters": {
"color": 7,
"width": 384,
"height": 464,
"content": "## The Magic\n1. First node creates an entity map of all the datatables and workflows from both instances and stores the original and new ID.\n2. Second node then goes through all your new workflows looking for any datatable or sub-workflow executions and then rewrites the original ID to be the new ID."
},
"typeVersion": 1
},
{
"id": "108df2be-66c4-45f8-852b-6bc7afa019de",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
1616,
-544
],
"parameters": {
"color": 3,
"width": 272,
"height": 464,
"content": "## Update\nThis node will now update each of the new workflows with the updated JSON.\n\n**Instructions**\n- You'll need to select the n8n credential for you **NEW** n8n instance. ***BE CAREFUL!!!***"
},
"typeVersion": 1
},
{
"id": "799578e4-b44f-42ee-b0ec-aeeafe6b8fbe",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
-704,
-544
],
"parameters": {
"width": 496,
"height": 464,
"content": "## Migration Helper - Automated Reconnection for Workflows + Datatables\n**Purpose**\nThis workflow is designed to automate the re-wiring of all your subworkflows and datatable actions after migrating them to a new n8n instance.\n\n**What it does**\n- **Recursive ID Swapping:**\nTakes a master dictionary of your old IDs -> new IDs, loops through your workflow JSONs, and recursively hunts down and replaces the node parameters. (Saves you from having to know if the ID is nested in an options object or at the root).\n\n---\n\n**Instructions**\nBasically you just need to define the relevant URL\u2019s and setup your n8n API credentials - then VERY CAREFULLY select the right credentials in the right nodes. Full instructions can be found in the sticky notes."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"availableInMCP": false,
"executionOrder": "v1"
},
"versionId": "cab8bf33-dc87-42d3-bf29-0595d299357f",
"connections": {
"map": {
"main": [
[
{
"node": "update flow nodes",
"type": "main",
"index": 0
}
]
]
},
"config": {
"main": [
[
{
"node": "orig datatables",
"type": "main",
"index": 0
}
]
]
},
"new workflows": {
"main": [
[
{
"node": "map",
"type": "main",
"index": 0
}
]
]
},
"new datatables": {
"main": [
[
{
"node": "new workflows",
"type": "main",
"index": 0
}
]
]
},
"orig workflows": {
"main": [
[
{
"node": "new datatables",
"type": "main",
"index": 0
}
]
]
},
"orig datatables": {
"main": [
[
{
"node": "orig workflows",
"type": "main",
"index": 0
}
]
]
},
"update flow nodes": {
"main": [
[
{
"node": "update new workflows",
"type": "main",
"index": 0
}
]
]
},
"When clicking \u2018Execute workflow\u2019": {
"main": [
[
{
"node": "config",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Purpose This workflow is designed to automate the re-wiring of all your subworkflows and datatable actions after migrating them to a new n8n instance.
Source: https://n8n.io/workflows/14218/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow allows you to import any workflow from a file or another n8n instance and map the credentials easily. A multi-form setup guides you through the entire process At the beginning you have t
N8n recently introduced folders and it has been a big improvement on workflow management on top of the tags.
Git Commit. Uses github, n8n, formTrigger, httpRequest. Event-driven trigger; 34 nodes.
Remixed Backup your workflows to GitHub from Solomon's work. Check out his templates.
This workflow provides everything you need to package and deploy multiple workflows from a single workflow you distribute.