{
  "name": "n8n subworkflow dependency graph & auto-tagging",
  "nodes": [
    {
      "id": "c3e6b9cb-4681-4778-b2f4-01c4a7d8c844",
      "name": "Update workflow tags",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3200,
        740
      ]
    },
    {
      "id": "d348051c-cc81-40cf-9c9b-f42c6f16c9d6",
      "name": "GET all workflows",
      "type": "n8n-nodes-base.n8n",
      "position": [
        1000,
        0
      ]
    },
    {
      "id": "bd1c08e5-f8fa-46a0-bfa9-ced09373d3eb",
      "name": "List callers of subworkflows",
      "type": "n8n-nodes-base.code",
      "position": [
        1200,
        0
      ]
    },
    {
      "id": "8a1ad58d-feb4-428f-b1e3-df0c08486416",
      "name": "Exclude uncalled workflows",
      "type": "n8n-nodes-base.filter",
      "position": [
        1400,
        0
      ]
    },
    {
      "id": "d654ca59-f4d6-4b67-9e87-021346ded854",
      "name": "Exclude missing workflows",
      "type": "n8n-nodes-base.filter",
      "position": [
        1800,
        0
      ]
    },
    {
      "id": "56a8b861-0f20-4379-b094-ebd3976ab95c",
      "name": "And every Sunday",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        760,
        160
      ]
    },
    {
      "id": "efacee31-5265-46e4-bc6d-c921a4169546",
      "name": "When this workflow is activated",
      "type": "n8n-nodes-base.n8nTrigger",
      "position": [
        760,
        0
      ]
    },
    {
      "id": "0eb2bb9b-0529-4d8e-bdd9-78e0373de744",
      "name": "GET workflow(s)",
      "type": "n8n-nodes-base.n8n",
      "position": [
        1600,
        0
      ]
    },
    {
      "id": "24efc8dc-103f-44fb-b229-8b8785ec75ed",
      "name": "Count callers and identify new callers",
      "type": "n8n-nodes-base.set",
      "position": [
        2000,
        0
      ]
    },
    {
      "id": "887bf07e-08f7-4491-aee4-a67ce0778319",
      "name": "Loop through workflows",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        2240,
        0
      ]
    },
    {
      "id": "dd5379fa-74be-44b7-9d49-9b1ae3fab425",
      "name": "GET all tags",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2800,
        220
      ]
    },
    {
      "id": "ba913e58-4c40-4e97-b4da-18ff3050a895",
      "name": "Remove existing tags from new_callers list",
      "type": "n8n-nodes-base.set",
      "position": [
        3000,
        220
      ]
    },
    {
      "id": "745ed318-8c11-4eb7-8c62-82fa85d32dde",
      "name": "If any new callers",
      "type": "n8n-nodes-base.if",
      "position": [
        2600,
        560
      ]
    },
    {
      "id": "a22e9a9d-33ed-4c73-b557-03fc6eb572bd",
      "name": "Split out new callers as new tags",
      "type": "n8n-nodes-base.splitOut",
      "position": [
        2800,
        440
      ]
    },
    {
      "id": "2af955b7-f50f-4422-b5a7-4b330a350f5d",
      "name": "Create new tags",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3000,
        440
      ]
    },
    {
      "id": "03e389d8-3f48-4fcc-b097-7f631f4e98ad",
      "name": "Return original pass through values",
      "type": "n8n-nodes-base.code",
      "position": [
        3200,
        440
      ]
    },
    {
      "id": "8ff8a3f3-e12c-4206-916e-856e3e88c2ce",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        3400,
        560
      ]
    },
    {
      "id": "a1043d63-67e3-41d9-a5de-485068a9b5c7",
      "name": "GET all tags again",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2600,
        740
      ]
    },
    {
      "id": "4a81485a-6f1a-44b3-8a2e-64190572f423",
      "name": "Create tag id:name dictionary",
      "type": "n8n-nodes-base.set",
      "position": [
        2800,
        740
      ]
    },
    {
      "id": "a1dbb6f5-fc0e-4506-890a-64c0da6b5b8c",
      "name": "Retrieve tag ids and names from dictionary",
      "type": "n8n-nodes-base.set",
      "position": [
        3000,
        740
      ]
    },
    {
      "id": "174d23bc-3aa1-4e05-81e2-8f45f92a16ee",
      "name": "Return dependency graph data",
      "type": "n8n-nodes-base.set",
      "position": [
        3400,
        740
      ]
    },
    {
      "id": "d45f7287-09f8-4de2-b74d-c55e200750aa",
      "name": "Combine dependency graph values into labels",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        2600,
        -20
      ]
    },
    {
      "id": "aeee2b70-e6e2-4d3e-bfda-2b69a7e95ffc",
      "name": "Visualize subworkflow dependency graph",
      "type": "n8n-nodes-base.quickChart",
      "position": [
        3000,
        -20
      ]
    },
    {
      "id": "f57710f5-788f-473d-b429-59eaf7193a7b",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        660,
        -397.5668732742495
      ],
      "parameters": {
        "width": 2909.758966302104,
        "height": 1357.9229992534551,
        "content": "# n8n Subworkflow Dependency Graph & Auto-Tagging"
      }
    },
    {
      "id": "ce9a88c8-5d6b-4b74-ae59-52128ec6d1af",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1160,
        160
      ],
      "parameters": {
        "width": 190.3269519041407,
        "height": 172.4182620239646,
        "content": "The script builds a dependency graph of workflows by identifying which workflows call others (via execution nodes) while preserving workflow names, caller relationships, and tags."
      }
    },
    {
      "id": "9e5bbc26-006e-45bf-be5c-d5e0cf7228f0",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1380,
        160
      ],
      "parameters": {
        "width": 150,
        "height": 135.16347595207057,
        "content": "Here we filter out any workflows that are not [sub-workflows](https://docs.n8n.io/flow-logic/subworkflows/) (i.e. executed by other workflows)."
      }
    },
    {
      "id": "6c957763-7410-4b3c-b08c-f73f2c502d5e",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1580,
        160
      ],
      "parameters": {
        "width": 345.30539364962834,
        "height": 100.16655570271519,
        "content": "We verify that the sub-workflows we intend to tag exist in our instance (not old workflow ids left over after importing a workflow from another instance)"
      }
    },
    {
      "id": "21ea4110-0f31-4621-b401-3bac222352d9",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3160,
        220
      ],
      "parameters": {
        "width": 320.4824213076102,
        "height": 97.51953145794394,
        "content": "If a tag is freshly created during an earlier iteration through the list of workflows, then it is removed from the list of new callers (i.e. new tags to create)."
      }
    },
    {
      "id": "0b04a2d3-5a10-4500-9450-5fee1ff77dec",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2560,
        180
      ],
      "parameters": {
        "width": 188.64373499228745,
        "height": 206.54161516323953,
        "content": "### Change instance URL"
      }
    },
    {
      "id": "98812066-6de5-48c4-a945-6639158b6394",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2940,
        -80
      ],
      "parameters": {
        "width": 502.4185703091201,
        "height": 243.8281544043028,
        "content": "## Generate chart"
      }
    },
    {
      "id": "1427d97f-7971-494c-9594-b3ec81d83511",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3220,
        -20
      ],
      "parameters": {
        "width": 180.46986136506064,
        "height": 135.95151736720237,
        "content": "### Pie Chart\nBasic visualization of which sub-workflows are called most often by other workflows"
      }
    },
    {
      "id": "1b8ee382-3e5d-4f6a-863b-100c84c3435e",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        680,
        500
      ],
      "parameters": {
        "width": 434.64763783570623,
        "height": 447.49544828389617,
        "content": "## Setup instructions:\n1. [Set n8n API credentials](https://docs.n8n.io/api/authentication/)\n2. Replace instance_url in workflow (highlighted in red)\n\n## Frequently used terms\n1. **Callers**: Workflow"
      }
    },
    {
      "id": "c005ed7e-8a7c-4588-944d-be0fa28b6959",
      "name": "SET instance_url",
      "type": "n8n-nodes-base.set",
      "position": [
        2600,
        220
      ]
    },
    {
      "id": "1ab2c9e9-fec1-4ab6-ace3-0bbe54a81058",
      "name": "When viewed in a browser",
      "type": "n8n-nodes-base.webhook",
      "position": [
        760,
        -160
      ]
    },
    {
      "id": "f1f930ed-2c42-4cab-a1a8-71b8810e0273",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2940,
        -360
      ],
      "parameters": {
        "width": 502.4185703091201,
        "height": 243.8281544043028,
        "content": "## Generate dependency graph"
      }
    },
    {
      "id": "d47598c9-1a50-4754-a6a5-b6e9976d83a0",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3220,
        -300
      ],
      "parameters": {
        "width": 180.46986136506064,
        "height": 135.95151736720237,
        "content": "### Dependency Graph\nA visual representation of the relationships between the workflows in your n8n instance"
      }
    },
    {
      "id": "18b2022a-dabc-4176-9b86-f3c1639d9b32",
      "name": "Format workflow relationship data for rendering",
      "type": "n8n-nodes-base.code",
      "position": [
        2600,
        -280
      ]
    },
    {
      "id": "3655d6bd-45a1-4c2e-856f-44104f0bd832",
      "name": "Visualize dependency graph with MermaidJS",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        3000,
        -280
      ]
    },
    {
      "id": "d9b0e9be-1794-4f5e-899c-b5d1e22baa58",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        680,
        -320
      ],
      "parameters": {
        "width": 653.2415806326139,
        "height": 140.62930090784633,
        "content": "## About this workflow\nThis workflow analyzes an n8n instance to detect dependencies between workflows. It identifies which workflows call others ([sub-workflows](https://docs.n8n.io/flow-logic/subwor"
      }
    },
    {
      "id": "357037ff-f5f7-4b5d-9b72-7c2aec393de4",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1360,
        -320
      ],
      "parameters": {
        "width": 266.5295926113459,
        "height": 95.5709893724457,
        "content": "## About the maker\n**[Find Ludwig Gerdes on LinkedIn](https://www.linkedin.com/in/ludwiggerdes)**"
      }
    }
  ],
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "GET all tags again",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET all tags": {
      "main": [
        [
          {
            "node": "Remove existing tags from new_callers list",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create new tags": {
      "main": [
        [
          {
            "node": "Return original pass through values",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET workflow(s)": {
      "main": [
        [
          {
            "node": "Exclude missing workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "And every Sunday": {
      "main": [
        [
          {
            "node": "GET all workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SET instance_url": {
      "main": [
        [
          {
            "node": "GET all tags",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET all workflows": {
      "main": [
        [
          {
            "node": "List callers of subworkflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET all tags again": {
      "main": [
        [
          {
            "node": "Create tag id:name dictionary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If any new callers": {
      "main": [
        [
          {
            "node": "Split out new callers as new tags",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Update workflow tags": {
      "main": [
        [
          {
            "node": "Return dependency graph data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop through workflows": {
      "main": [
        [
          {
            "node": "Combine dependency graph values into labels",
            "type": "main",
            "index": 0
          },
          {
            "node": "Format workflow relationship data for rendering",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "SET instance_url",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When viewed in a browser": {
      "main": [
        [
          {
            "node": "GET all workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Exclude missing workflows": {
      "main": [
        [
          {
            "node": "Count callers and identify new callers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Exclude uncalled workflows": {
      "main": [
        [
          {
            "node": "GET workflow(s)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List callers of subworkflows": {
      "main": [
        [
          {
            "node": "Exclude uncalled workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Return dependency graph data": {
      "main": [
        [
          {
            "node": "Loop through workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create tag id:name dictionary": {
      "main": [
        [
          {
            "node": "Retrieve tag ids and names from dictionary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When this workflow is activated": {
      "main": [
        [
          {
            "node": "GET all workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Split out new callers as new tags": {
      "main": [
        [
          {
            "node": "Create new tags",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Return original pass through values": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Count callers and identify new callers": {
      "main": [
        [
          {
            "node": "Loop through workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Remove existing tags from new_callers list": {
      "main": [
        [
          {
            "node": "If any new callers",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Retrieve tag ids and names from dictionary": {
      "main": [
        [
          {
            "node": "Update workflow tags",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine dependency graph values into labels": {
      "main": [
        [
          {
            "node": "Visualize subworkflow dependency graph",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format workflow relationship data for rendering": {
      "main": [
        [
          {
            "node": "Visualize dependency graph with MermaidJS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}