AutomationFlowsAI & RAG › Automatically Document and Backup N8n Workflows

Automatically Document and Backup N8n Workflows

ByLuke @ozskywalker on n8n.io

Automatically backs up your workflows to Github and generates documentation in a Notion database. Weekly run, uses the "internal-infra" tag to look for new or recently modified workflows Uses a Notion database page to hold the workflow summary, last updated date, and a link to…

Cron / scheduled trigger★★★★☆ complexityAI-powered22 nodesHTTP RequestNotionSlackOpenAIGitHubn8n
AI & RAG Trigger: Cron / scheduled Nodes: 22 Complexity: ★★★★☆ AI nodes: yes Added:
Automatically Document and Backup N8n Workflows — n8n workflow card showing HTTP Request, Notion, Slack integration

This workflow corresponds to n8n.io template #3354 — we link there as the canonical source.

This workflow follows the GitHub → HTTP Request 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 →

Download .json
{
  "id": "oDMm9XRg5bfp9TTu",
  "meta": {
    "templateId": "2151",
    "templateCredsSetupCompleted": true
  },
  "name": "_infra: Automatically document n8n workflows directly in Notion database",
  "tags": [
    {
      "id": "R5f4JtfSlaX6a5AQ",
      "name": "internal-infra",
      "createdAt": "2025-02-13T14:32:55.887Z",
      "updatedAt": "2025-02-13T14:32:55.887Z"
    }
  ],
  "nodes": [
    {
      "id": "d702f13e-8e93-4142-87c7-49fbb6031e19",
      "name": "Set fields",
      "type": "n8n-nodes-base.set",
      "position": [
        800,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "1744510d-7ed7-46d8-acd3-f975ab73f298",
              "name": "active",
              "type": "boolean",
              "value": "={{ $json.active }}"
            },
            {
              "id": "7e76f5dc-0c32-4b26-a289-975155b80112",
              "name": "url",
              "type": "string",
              "value": "=https://<n8n_host_name>/workflow/{{ $json.id }}"
            },
            {
              "id": "a7b069bf-8090-4dca-a432-f4fd7aa84e6f",
              "name": "errorWorkflow",
              "type": "boolean",
              "value": "={{ !!$json.settings?.errorWorkflow }}"
            },
            {
              "id": "0bff7a9b-0860-4552-b0f6-5fc279fc75d6",
              "name": "workflow-name",
              "type": "string",
              "value": "={{ $json.name }}"
            },
            {
              "id": "3065ee2f-d1bb-42b7-b341-7bb38b0f6720",
              "name": "updatedAt",
              "type": "string",
              "value": "={{ $json.updatedAt }}"
            },
            {
              "id": "ea9d39e4-50ca-4c79-b6ab-8b22cafd0257",
              "name": "createdAt",
              "type": "string",
              "value": "={{ $json.createdAt }}"
            },
            {
              "id": "265d66cd-1796-40eb-ae5b-dca8d1a91871",
              "name": "envId",
              "type": "string",
              "value": "=internal-{{ $json.id }}"
            },
            {
              "id": "6ffb9c13-82a7-4f40-b2e6-887c018b747c",
              "name": "workflow-definition",
              "type": "string",
              "value": "={{ JSON.stringify($json, null, 2) }}"
            },
            {
              "id": "8b2a1098-125f-44b0-b8c0-99098e582156",
              "name": "workflow-export-filename",
              "type": "string",
              "value": "={{ $json.name.replace(/ /g, \"_\").replace(/-/g, \"_\") + \".json\" }}"
            }
          ]
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "4527dc91-bad5-4214-b210-ea8f89504fbf",
      "name": "Get notion page with workflow id",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        960,
        480
      ],
      "parameters": {
        "url": "https://api.notion.com/v1/databases/<your_db_id_here>/query",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n    \"filter\": { \"and\": [\n    {\n        \"property\": \"envId\",\n        \"rich_text\": { \"contains\": \"{{ $json.envId }}\" }\n    }]\n}\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Notion-Version",
              "value": "2022-06-28"
            }
          ]
        },
        "nodeCredentialType": "notionApi"
      },
      "credentials": {},
      "typeVersion": 4.1
    },
    {
      "id": "ced49644-b18f-4984-8dfd-199d88e3ded7",
      "name": "Map fields",
      "type": "n8n-nodes-base.set",
      "position": [
        1120,
        480
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "49092f3a-7f42-4067-b8ea-1073ef1d1bb8",
              "name": "input",
              "type": "object",
              "value": "={{ $('Set fields').item.json }}"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.3
    },
    {
      "id": "86edfe55-9a88-49ed-82de-df0c44a65d53",
      "name": "Add to Notion",
      "type": "n8n-nodes-base.notion",
      "position": [
        1960,
        460
      ],
      "parameters": {
        "title": "={{ $('Map fields').item.json.input['workflow-name'] }}",
        "options": {},
        "resource": "databasePage",
        "databaseId": {
          "__rl": true,
          "mode": "list",
          "value": "<replace_me>",
          "cachedResultUrl": "https://www.notion.so/<replace_me>",
          "cachedResultName": "Workflow Sync"
        },
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "Workflow Name|title",
              "title": "={{ $('Map fields').item.json.input['workflow-name'] }}"
            },
            {
              "key": "URL (dev)|url",
              "urlValue": "={{ $('Map fields').item.json.input.url }}"
            },
            {
              "key": "isActive (dev)|checkbox",
              "checkboxValue": "={{ $('Map fields').item.json.input.active }}"
            },
            {
              "key": "Workflow created at|date",
              "date": "={{ $('Map fields').item.json.input.createdAt }}"
            },
            {
              "key": "Workflow updated at|date",
              "date": "={{ $('Map fields').item.json.input.updatedAt }}"
            },
            {
              "key": "Error workflow setup|checkbox",
              "checkboxValue": "={{ $('Map fields').item.json.input.errorWorkflow }}"
            },
            {
              "key": "Record last update|date",
              "date": "={{ $now }}"
            },
            {
              "key": "AI Summary|rich_text",
              "textContent": "={{ $json.message.content }}"
            },
            {
              "key": "envId|rich_text",
              "textContent": "={{ $('Map fields').item.json.input.envId }}"
            }
          ]
        }
      },
      "credentials": {},
      "typeVersion": 2.1
    },
    {
      "id": "9d547270-37dd-41ee-98b7-13001c954ffa",
      "name": "Update in Notion",
      "type": "n8n-nodes-base.notion",
      "position": [
        1960,
        640
      ],
      "parameters": {
        "pageId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Map fields').item.json.results[0].id }}"
        },
        "options": {},
        "resource": "databasePage",
        "operation": "update",
        "propertiesUi": {
          "propertyValues": [
            {
              "key": "isActive (dev)|checkbox",
              "checkboxValue": "={{ $('Set fields').item.json.active }}"
            },
            {
              "key": "Workflow updated at|date",
              "date": "={{ $('Set fields').item.json.updatedAt }}"
            },
            {
              "key": "Error workflow setup|checkbox",
              "checkboxValue": "={{ $('Set fields').item.json.errorWorkflow }}"
            },
            {
              "key": "AI Summary|rich_text",
              "textContent": "={{ $json.message.content }}"
            }
          ]
        }
      },
      "credentials": {},
      "typeVersion": 2.1
    },
    {
      "id": "f612d12c-d3cf-4186-9ed1-c75ed53132cb",
      "name": "Notify internal-infra of push",
      "type": "n8n-nodes-base.slack",
      "position": [
        2160,
        460
      ],
      "parameters": {
        "text": "=Pushed new workflow to Notion: {{ $('Map fields').item.json.input['workflow-name'] }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "<yourchannelID>",
          "cachedResultName": "<yourchannelname>"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {},
      "typeVersion": 2.3
    },
    {
      "id": "aef5c65e-323b-463b-8e1e-f09cc064c44b",
      "name": "Notify internal-infra of update",
      "type": "n8n-nodes-base.slack",
      "position": [
        2160,
        640
      ],
      "parameters": {
        "text": "=Updated workflow in Notion: {{ $('Map fields').item.json.input['workflow-name'] }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "<yourchannelID>",
          "cachedResultName": "<yourchannelname>"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {},
      "typeVersion": 2.3
    },
    {
      "id": "f200a66c-b902-4b90-8499-93ae7d12a552",
      "name": "Notify on workflow setup error",
      "type": "n8n-nodes-base.slack",
      "position": [
        1060,
        1020
      ],
      "parameters": {
        "text": "=WARNING: Error workflow has NOT been setup for: <{{ $json.input.url }}|{{ $json.input['workflow-name'] }}> (No backup will take place until err-workflow is configured)",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "<yourchannelID>",
          "cachedResultName": "<yourchannelname>"
        },
        "otherOptions": {
          "mrkdwn": true,
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {},
      "typeVersion": 2.3
    },
    {
      "id": "f10268c7-706f-4651-9bee-99b13cdc1ed1",
      "name": "Summarize what the Workflow does",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1360,
        480
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-4o-mini",
          "cachedResultName": "GPT-4O-MINI"
        },
        "options": {},
        "messages": {
          "values": [
            {
              "content": "=Concisely tell me what this N8N plugin does in 1-2 lines, then describe how it does it in no more than a paragraph, but only if that detail was already covered by the first 1-2 lines - we don't want to repeat ourselves.\n<n8nplugin>\n{{ $json.input['workflow-definition'] }}\n</n8nplugin>"
            }
          ]
        }
      },
      "credentials": {},
      "typeVersion": 1.8
    },
    {
      "id": "21fa612f-98c5-4fe6-a048-2e2891bc6893",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        760,
        380
      ],
      "parameters": {
        "color": 4,
        "width": 480,
        "height": 300,
        "content": "## Extract key fields"
      },
      "typeVersion": 1
    },
    {
      "id": "6b6f931b-298f-4ac6-a256-be051912e667",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        380
      ],
      "parameters": {
        "color": 5,
        "width": 1080,
        "height": 440,
        "content": "## Generate documentation in Notion\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7caa1e4a-9705-4abd-9b91-73abe7ef41d0",
      "name": "Upload changes to repo",
      "type": "n8n-nodes-base.github",
      "onError": "continueErrorOutput",
      "position": [
        1380,
        980
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "<yourownernamehere>"
        },
        "filePath": "=N8N_Workflows/{{ $('Set fields').item.json['workflow-export-filename'].replaceAll(/[\\/:*?\"<>|,\\t\\n#%&']/g, \"_\") }}",
        "resource": "file",
        "operation": "edit",
        "repository": {
          "__rl": true,
          "mode": "list",
          "value": "<yourreponamehere>",
          "cachedResultUrl": "<yourrepoURLhere>",
          "cachedResultName": "<yourreponamehere>"
        },
        "fileContent": "={{ $('Set fields').item.json['workflow-definition'] }}",
        "commitMessage": "=updated by N8N #{{ $execution.id }}",
        "authentication": "oAuth2"
      },
      "credentials": {},
      "typeVersion": 1
    },
    {
      "id": "50993b0c-81fa-4042-9fb9-0d53d1266743",
      "name": "Create new file in repo",
      "type": "n8n-nodes-base.github",
      "onError": "continueErrorOutput",
      "position": [
        1720,
        980
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "<yourownernamehere>"
        },
        "filePath": "=N8N_Workflows/{{ $('Set fields').item.json['workflow-export-filename'].replaceAll(/[\\/:*?\"<>|,\\t\\n#%&']/g, \"_\") }}",
        "resource": "file",
        "repository": {
          "__rl": true,
          "mode": "list",
          "value": "<yourreponamehere>",
          "cachedResultUrl": "<yourrepoURLhere>",
          "cachedResultName": "<yourreponamehere>"
        },
        "fileContent": "={{ $('Set fields').item.json['workflow-definition'] }}",
        "commitMessage": "created by N8N",
        "authentication": "oAuth2"
      },
      "credentials": {},
      "typeVersion": 1
    },
    {
      "id": "e640de5f-2cc8-4fd9-817b-147a3fd67ed3",
      "name": "Notify on create file in repo fail",
      "type": "n8n-nodes-base.slack",
      "position": [
        2160,
        980
      ],
      "parameters": {
        "text": "=WARNING: Failed to upload new N8N workflow <{{ $json.input.url }}|{{ $json.input['workflow-name'] }}> to repo",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "<yourchannelID>",
          "cachedResultName": "<yourchannelname>"
        },
        "otherOptions": {
          "mrkdwn": true,
          "includeLinkToWorkflow": true
        }
      },
      "credentials": {},
      "typeVersion": 2.3
    },
    {
      "id": "623c4dd7-ebce-4b15-ab2a-b9222eab66f3",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        760,
        840
      ],
      "parameters": {
        "color": 3,
        "width": 480,
        "height": 360,
        "content": "## Check workflow setup OK "
      },
      "typeVersion": 1
    },
    {
      "id": "bc47d8ab-3265-4148-ba2c-23e0a77156b6",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        840
      ],
      "parameters": {
        "color": 5,
        "width": 1080,
        "height": 360,
        "content": "## Upload / backup workflow to GitHub repo"
      },
      "typeVersion": 1
    },
    {
      "id": "6cf569ad-38cd-4f8d-b65b-7c7fe36b1315",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        60,
        380
      ],
      "parameters": {
        "width": 660,
        "height": 300,
        "content": "## Check weekly for changes on active internal-infra workflows"
      },
      "typeVersion": 1
    },
    {
      "id": "b890dacf-2ac2-4802-b96a-5097119d35ee",
      "name": "Is this a new workflow (to Notion) ?",
      "type": "n8n-nodes-base.if",
      "position": [
        1720,
        480
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "88337d36-8cf6-4cd5-bec1-5123cf612934",
              "operator": {
                "type": "array",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $('Map fields').item.json.results }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "2c3549c1-99c1-4255-a02d-2f454e6ced5e",
      "name": "Every Monday at 1am",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        120,
        480
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtDay": [
                1
              ],
              "triggerAtHour": 1
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "8d1fdf8c-3a80-4972-b721-ca9477be891b",
      "name": "Check if updated in last 7 days",
      "type": "n8n-nodes-base.if",
      "position": [
        560,
        480
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "5f0685ee-2ffa-4cf8-8d65-32addb4bb703",
              "operator": {
                "type": "dateTime",
                "operation": "afterOrEquals"
              },
              "leftValue": "={{ $json.updatedAt }}",
              "rightValue": "={{ new Date(new Date().setDate(new Date().getDate()-7)).toISOString() }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "3380272e-5631-44aa-b7da-5e23e0966978",
      "name": "Get active workflows with internal-infra tag",
      "type": "n8n-nodes-base.n8n",
      "position": [
        340,
        480
      ],
      "parameters": {
        "filters": {
          "tags": "internal-infra",
          "activeWorkflows": true
        },
        "requestOptions": {}
      },
      "credentials": {},
      "typeVersion": 1
    },
    {
      "id": "0049cf1e-91e9-4ee0-abd7-5e0bfab18b7f",
      "name": "Check that error workflow has been configured",
      "type": "n8n-nodes-base.if",
      "position": [
        820,
        900
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "c53617b5-a217-4111-a229-82d93fb0bec6",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.input.errorWorkflow }}",
              "rightValue": ""
            },
            {
              "id": "3ea0c94e-e192-4e94-867f-788feda52d61",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.input['workflow-name'] }}",
              "rightValue": "_infra: Get a Slack alert when a workflow went wrong"
            }
          ]
        }
      },
      "typeVersion": 2.2
    }
  ],
  "active": true,
  "settings": {
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "dnboDNiqvl2P7sCZ",
    "executionOrder": "v1",
    "saveManualExecutions": false,
    "saveExecutionProgress": true
  },
  "versionId": "a5aaebfd-20cc-4042-9a76-1790f8501188",
  "connections": {
    "Map fields": {
      "main": [
        [
          {
            "node": "Check that error workflow has been configured",
            "type": "main",
            "index": 0
          },
          {
            "node": "Summarize what the Workflow does",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set fields": {
      "main": [
        [
          {
            "node": "Get notion page with workflow id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Add to Notion": {
      "main": [
        [
          {
            "node": "Notify internal-infra of push",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update in Notion": {
      "main": [
        [
          {
            "node": "Notify internal-infra of update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Every Monday at 1am": {
      "main": [
        [
          {
            "node": "Get active workflows with internal-infra tag",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload changes to repo": {
      "main": [
        [],
        [
          {
            "node": "Create new file in repo",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create new file in repo": {
      "main": [
        [],
        [
          {
            "node": "Notify on create file in repo fail",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Notify on workflow setup error": {
      "main": [
        []
      ]
    },
    "Check if updated in last 7 days": {
      "main": [
        [
          {
            "node": "Set fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get notion page with workflow id": {
      "main": [
        [
          {
            "node": "Map fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Summarize what the Workflow does": {
      "main": [
        [
          {
            "node": "Is this a new workflow (to Notion) ?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is this a new workflow (to Notion) ?": {
      "main": [
        [
          {
            "node": "Add to Notion",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update in Notion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get active workflows with internal-infra tag": {
      "main": [
        [
          {
            "node": "Check if updated in last 7 days",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check that error workflow has been configured": {
      "main": [
        [
          {
            "node": "Upload changes to repo",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Notify on workflow setup error",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Automatically backs up your workflows to Github and generates documentation in a Notion database. Weekly run, uses the "internal-infra" tag to look for new or recently modified workflows Uses a Notion database page to hold the workflow summary, last updated date, and a link to…

Source: https://n8n.io/workflows/3354/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Who is this for This workflow is perfect for busy professionals, consultants, and anyone who frequently travels between meetings. If you want to make the most of your free time between appointments an

Google Calendar, Notion, OpenWeatherMap +3
AI & RAG

The workflow triggers every weekday at 8 AM, automatically fetching the latest papers from Hugging Face for easy access.

HTTP Request, Notion, OpenAI +1
AI & RAG

A scheduled process aggregates content from eight distinct data sources and standardizes all inputs into a unified format. AI models perform sentiment scoring, detect conspiracy or misinformation sign

HTTP Request, OpenAI, Postgres +2
AI & RAG

AI-powered priority re-evaluation every 2 hours. Analyzes new signals, meeting decisions, emails, and blockers, then runs 3 AI passes (Impact, Urgency, Final Ranking) to suggest re-ranking. Only updat

Notion, OpenAI, Slack
AI & RAG

This workflow monitors filesystem sync and backup jobs by validating their execution logs, not by running or inspecting the jobs themselves.

Google Cloud Storage, Gmail, GitHub +2