Selbstdokumentierendes API-Portal für Webhooks mit n8n API und Bootstrap generieren

Experte

Dies ist ein Document Extraction, Multimodal AI-Bereich Automatisierungsworkflow mit 17 Nodes. Hauptsächlich werden N8n, Set, Code, Html, Webhook und andere Nodes verwendet. Selbstdokumentierende API-Portale für Webhooks mit n8n API und Bootstrap generieren

Voraussetzungen
  • HTTP Webhook-Endpunkt (wird von n8n automatisch generiert)
Workflow-Vorschau
Visualisierung der Node-Verbindungen, mit Zoom und Pan
Workflow exportieren
Kopieren Sie die folgende JSON-Konfiguration und importieren Sie sie in n8n
{
  "meta": {
    "instanceId": "e860732ed76ff1de8212e780b2d62bd140dee0b71e6ccf7172d54e965acae43d",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "a59b516a-e188-4364-8722-f83fd00ed0f0",
      "name": "Aggregieren",
      "type": "n8n-nodes-base.aggregate",
      "position": [
        120,
        -300
      ],
      "parameters": {
        "options": {},
        "aggregate": "aggregateAllItemData"
      },
      "typeVersion": 1
    },
    {
      "id": "3ab41431-6298-4380-aaec-d0e29f7f9cb5",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -700,
        460
      ],
      "webhookId": "e98f9bf5-f5ad-46fb-a93c-08218eea8d5e",
      "parameters": {
        "path": "api-doc",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "286e23f0-44c8-46c4-bfd2-8aab6eae245b",
      "name": "Konfigurationen",
      "type": "n8n-nodes-base.set",
      "position": [
        -480,
        460
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "9a243289-a359-47fd-9155-a809a910b8f7",
              "name": "name_doc",
              "type": "string",
              "value": "N8N Example Doc"
            },
            {
              "id": "59992f15-d27d-454c-9c1f-a66f0674c7bb",
              "name": "version",
              "type": "string",
              "value": "v.0.1"
            },
            {
              "id": "f0633ecb-b0c8-4e55-8285-51aa05492420",
              "name": "description",
              "type": "string",
              "value": "Example description"
            },
            {
              "id": "2da37a16-f97a-4ec8-9d9c-13f09bea1d39",
              "name": "url_base",
              "type": "string",
              "value": "n8n.io/"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "b910c088-c3c6-4bfc-9856-5294891e4cd0",
      "name": "Notizzettel",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -370,
        -400
      ],
      "parameters": {
        "color": 2,
        "width": 860,
        "height": 260,
        "content": "## Get Workflow and filter\n"
      },
      "typeVersion": 1
    },
    {
      "id": "add44468-ffba-401e-a119-3e25c4870ece",
      "name": "Notizzettel1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -360,
        -120
      ],
      "parameters": {
        "color": 6,
        "width": 760,
        "height": 400,
        "content": "## webhook for testing"
      },
      "typeVersion": 1
    },
    {
      "id": "1de3f20f-152c-4f81-b42d-cc9e03f5bf0d",
      "name": "Antworten",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        120,
        -40
      ],
      "parameters": {
        "options": {},
        "respondWith": "allIncomingItems"
      },
      "typeVersion": 1.1
    },
    {
      "id": "0a7a9d55-5b34-4129-952d-c982ebcc3d7c",
      "name": "HTML-Antwort",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        180,
        460
      ],
      "parameters": {
        "options": {},
        "respondWith": "text",
        "responseBody": "={{$json.html}}"
      },
      "typeVersion": 1.1
    },
    {
      "id": "f85d91a0-16ec-4f79-870a-dfc24f954469",
      "name": "Vollständiges HTML erstellen",
      "type": "n8n-nodes-base.html",
      "position": [
        -40,
        460
      ],
      "parameters": {
        "html": "<html>\n<head>\n  <title>{{$('Configs').item.json.name_doc}}</title>\n  <link rel=\"stylesheet\" href=\"https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css\">\n  <link href=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css\" rel=\"stylesheet\">\n  <style>\n    :root {\n      --bs-body-bg: #1a1a1a;\n      --bs-body-color: #e0e0e0;\n      --bs-border-color: #444;\n      --bs-accordion-bg: #2b2b2b;\n      --bs-accordion-color: #e0e0e0;\n      --bs-accordion-button-color: #e0e0e0;\n      --bs-accordion-border-color: #444;\n      --bs-accordion-button-active-bg: #3c3c3c;\n      --bs-accordion-button-active-color: #ffffff;\n      --bs-accordion-button-focus-border-color: #007bff;\n      --bs-accordion-button-focus-box-shadow: 0 0 0 0.25rem rgba(0, 123, 255, 0.25);\n    }\n    .method {\n      display: inline-block;\n      padding: 0.3em 0.8em;\n      border-radius: 0.25rem;\n      font-weight: bold;\n      font-size: 0.9em;\n      color: white;\n      text-transform: uppercase;\n      margin-right: 1rem;\n    }\n    .method-post { background-color: #49cc90; }\n    .method-get { background-color: #61affe; }\n    .endpoint-path {\n      font-family: monospace;\n      font-size: 1.1em;\n      color: #ccc;\n    }\n    pre {\n      background-color: #161B22;\n      padding: 1rem;\n      border-radius: 0.25rem;\n      white-space: pre-wrap;\n      word-break: break-all;\n      border: 1px solid var(--bs-border-color);\n    }\n    code { color: #c9d1d9; }\n    .accordion-button:not(.collapsed) {\n        box-shadow: inset 0 -1px 0 var(--bs-accordion-border-color);\n    }\n  </style>\n</head>\n<body class=\"p-4\">\n  <div class=\"container\">\n    <div class=\"d-flex align-items-baseline mb-4\">\n      <h1 class=\"text-white me-3\">{{$('Configs').item.json.name_doc}}</h1>\n      <p class=\"text-white-50 me-3\">{{$('Configs').item.json.description}}</p>\n      <span class=\"badge bg-secondary\">{{$('Configs').item.json.version}}</span>\n    </div>\n    \n    {{ $json.htmlContent || `\n<div class=\"alert alert-danger d-flex align-items-center mt-4\" role=\"alert\">\n  <i class=\"bi bi-x-octagon-fill me-3\" style=\"font-size: 2rem;\"></i>\n  <div>\n    <h4 class=\"alert-heading\">Documentation Generation Failed!</h4>\n    <p>An error occurred while trying to generate the API documentation from the sub-workflow.</p>\n    <hr>\n    <p class=\"mb-1\"><strong>Please check the following:</strong></p>\n    <ul>\n      <li>Ensure the sub-workflow (the one that generates the accordion) executed successfully and produced an output named <code>htmlContent</code>.</li>\n      <li>Verify that at least one of your workflows is active and contains a correctly configured <code>API_DOCS</code> node.</li>\n      <li>Check the n8n execution logs for more detailed error messages from the sub-workflow.</li>\n    </ul>\n  </div>\n</div>\n`}}\n\n\n    </div>\n <footer class=\"mt-5 pt-4 text-center text-white-50\">\n  <p>\n    Created by <a href=\"https://www.linkedin.com/in/matheus-pedrosa-custodio/\" target=\"_blank\" rel=\"noopener noreferrer\" class=\"link-light text-decoration-none\">\n      <i class=\"bi bi-linkedin\"></i> Matheus Pedrosa\n    </a>\n  </p>\n</footer>\n  \n  <script src=\"https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js\"></script>\n</body>\n</html>"
      },
      "typeVersion": 1.2
    },
    {
      "id": "0bd66854-cf1b-46b5-ad75-e0d7ef9b71d4",
      "name": "Unterarbeitsablauf ausführen",
      "type": "n8n-nodes-base.executeWorkflow",
      "onError": "continueRegularOutput",
      "position": [
        -260,
        460
      ],
      "parameters": {
        "options": {
          "waitForSubWorkflow": true
        },
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "y2xOdk7RyRoS2sgF",
          "cachedResultName": "Documentation"
        },
        "workflowInputs": {
          "value": {},
          "schema": [
            {
              "id": "url_base",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "url_base",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "43a02f1b-9f18-4148-9705-2c3347997cfa",
      "name": "Ausführen",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        -320,
        -300
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "url_base"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "91ad9f92-adf3-4a8c-af48-3d1e5cd06678",
      "name": "Arbeitsabläufe abrufen",
      "type": "n8n-nodes-base.n8n",
      "position": [
        -100,
        -300
      ],
      "parameters": {
        "filters": {
          "tags": "",
          "activeWorkflows": true
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "fTE1pX6nL40KSIdW",
          "name": "n8n account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "c28819b2-2e5d-4732-9a68-0d5045dcb59e",
      "name": "Arbeitsabläufe filtern",
      "type": "n8n-nodes-base.code",
      "position": [
        340,
        -300
      ],
      "parameters": {
        "jsCode": "const allWorkflows = $('Aggregate').last().json.data;\nlet html = '';\n\nconst documentedWebhookWorkflows = allWorkflows.filter(item => {\n  if (!item.nodes || item.nodes.length === 0) {\n    return false;\n  }\n  const hasWebhook = item.nodes.some(node => node.type === 'n8n-nodes-base.webhook');\n  const hasDocsNote = item.nodes.some(node => node.type === 'n8n-nodes-base.set' && node.name === 'API_DOCS');\n  return hasWebhook && hasDocsNote;\n});\n\n\nif (documentedWebhookWorkflows.length > 0) {\n  html += '<div class=\"accordion\" id=\"docsAccordion\">';\n\n  const n8nBaseUrl = $(\"Execute\").last().json.url_base || 'https://n8n.io/';\n\n  for (const workflow of documentedWebhookWorkflows) {\n    const docsNode = workflow.nodes.find(n => n.name === 'API_DOCS');\n\n    if (docsNode) {\n      const jsonString = docsNode.parameters.jsonOutput || JSON.stringify(docsNode.parameters.docsData);\n      let docsData = {};\n      let webhookNode = null;\n\n      try {\n        docsData = JSON.parse(jsonString);\n        webhookNode = workflow.nodes.find(n => { return n.type === 'n8n-nodes-base.webhook' && n.name === docsData.webhook });\n      } catch (e) {\n        console.error(`Erro ao parsear JSON no workflow: ${workflow.name}`, e);\n        continue;\n      }\n\n      if(webhookNode){\n        const method = (docsData.method || \"POST\").toUpperCase();\n        const uniqueId = webhookNode.parameters.path.replace(/[^a-zA-Z0-9]/g, '');\n\n        // --- make CURL\n        const fullUrl = `${n8nBaseUrl}webhook/${webhookNode.parameters.path}`;\n\n        let curlCommand = `curl -X ${method}\\\\`;\n        if (method === 'POST' || method === 'PUT' || method === 'PATCH') {\n          const requestBodyString = JSON.stringify(docsData.requestBody || {});\n          curlCommand += `\n          -H 'Content-Type: application/json' \\\\\n          -d '${requestBodyString}' \\\\`;\n                }\n                curlCommand += `\n          ${fullUrl}`;\n\n        html += `\n          <div class=\"accordion-item\">\n            <h2 class=\"accordion-header\" id=\"heading-${uniqueId}\">\n              <button class=\"accordion-button collapsed\" type=\"button\" data-bs-toggle=\"collapse\" data-bs-target=\"#collapse-${uniqueId}\" aria-expanded=\"false\" aria-controls=\"collapse-${uniqueId}\">\n                <span class=\"method method-${method.toLowerCase()}\">${method}</span>\n                <span class=\"endpoint-path\">/webhook/${webhookNode.parameters.path}</span>\n              </button>\n            </h2>\n            <div id=\"collapse-${uniqueId}\" class=\"accordion-collapse collapse\" aria-labelledby=\"heading-${uniqueId}\" data-bs-parent=\"#docsAccordion\">\n              <div class=\"accordion-body\">\n                <p><strong>${docsData.summary || 'No summary'}</strong></p>\n                <p>${docsData.description || 'No description.'}</p>\n                <hr style=\"border-color: var(--bs-border-color);\">\n                \n                <h6>cURL Command:</h6>\n                <pre><code>${curlCommand}</code></pre>\n                \n                <h6>Request Body:</h6>\n                <pre><code>${JSON.stringify(docsData.requestBody || {}, null, 2)}</code></pre>\n                <h6>Success Response (${docsData.successCode || 'N/A'}):</h6>\n                <pre><code>${JSON.stringify(docsData.successResponse || {}, null, 2)}</code></pre>\n                <h6>Error Response (${docsData.errorCode || 'N/A'}):</h6>\n                <pre><code>${JSON.stringify(docsData.errorResponse || {}, null, 2)}</code></pre>\n              </div>\n            </div>\n          </div>\n        `;\n      }\n    }\n  }\n  html += '</div>';\n} else {\n  html += '<div class=\"alert alert-info\">Nenhum endpoint documentado foi encontrado.</div>';\n}\n\nreturn [{\n  json: {\n    htmlContent: html\n  }\n}];"
      },
      "typeVersion": 2
    },
    {
      "id": "78526a12-613c-4530-9a6f-bb612036addf",
      "name": "Notizzettel2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -940,
        -400
      ],
      "parameters": {
        "color": 4,
        "width": 540,
        "height": 700,
        "content": "### Live n8n API Documentation Generator\n\n**Author:** Matheus Pedrosa | https://www.linkedin.com/in/matheus-pedrosa-custodio/\n**Version:** 1.0\n**Date:** 2025-08-21\n\n## Summary\nThis is a \"meta-workflow\" that acts as an engine to automatically generate a live, interactive HTML documentation page for your n8n instance's webhooks. It scans all active workflows, finds the ones designated for documentation, and renders a single, professional, dark-themed page.\n\n## Key Feature\nThe core logic relies on a **convention-based discovery**. To include a webhook in the documentation, you simply add a `Set` node named **`API_DOCS`** to that workflow and fill in a JSON object with the endpoint's metadata (summary, request body, responses, etc.). This generator then automatically parses that data to build the documentation page.\n\n## Setup (Quick Checklist)\n1.  **`API_DOCS` Nodes:** In every workflow you want to document, add a `Set` node named `API_DOCS` and provide the necessary JSON metadata (especially the `webhookPath`).\n2.  **`GetWorkflows` Node:** Configure this node with your `n8n API` credentials. It needs permission to read all workflows.\n3.  **`Configs` Node:** Customize the global settings for your documentation page, such as the main title (`name_doc`), description, and version.\n4.  **`Webhook` Trigger:** The URL of this workflow's trigger is the public URL for your final documentation page."
      },
      "typeVersion": 1
    },
    {
      "id": "602d0cd7-558e-4360-b385-bf9824f9278b",
      "name": "Webhook1",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -320,
        -40
      ],
      "webhookId": "15105da5-96ca-472f-a7db-2ddc2e8b0891",
      "parameters": {
        "path": "15105da5-96ca-472f-a7db-2ddc2e8b0891",
        "options": {},
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "6283f30d-d1eb-4a7b-9f97-73834d7c060f",
      "name": "API_DOKS",
      "type": "n8n-nodes-base.set",
      "position": [
        -320,
        120
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"expose\": true,\n  \"webhook\": \"Webhook1\",\n  \"summary\": \"Title test\",\n  \"method\":\"get\",\n  \"description\": \"Hey community, look at this cool workflow I'm doing.\",\n  \"tags\": [\n    \"test\",\n    \"tag_0101\"\n  ],\n  \"requestBody\": {},\n  \"successCode\": 200,\n  \"successResponse\": {\n    \"status\": 200,\n    \"message\": \"Workflow start\"\n  },\n  \"errorCode\": 400,\n  \"errorResponse\": {\n    \"status\": 500,\n    \"message\": \"Workflow error\"\n  }\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "57843c34-afb5-401e-86dc-8aa22c242263",
      "name": "Simulierte Antwort",
      "type": "n8n-nodes-base.code",
      "position": [
        -100,
        -40
      ],
      "parameters": {
        "jsCode": "return {\n    \"status\": 200,\n    \"message\": \"Workflow start\"\n  }"
      },
      "typeVersion": 2
    },
    {
      "id": "29b6b6ea-917b-47a3-b8a1-ff017b0a10a5",
      "name": "Notizzettel3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -940,
        400
      ],
      "parameters": {
        "width": 150,
        "height": 200,
        "content": "### Create documentation page\n\n![](https://cdn-icons-png.flaticon.com/512/4028/4028647.png)"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "286e23f0-44c8-46c4-bfd2-8aab6eae245b": {
      "main": [
        [
          {
            "node": "0bd66854-cf1b-46b5-ad75-e0d7ef9b71d4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "43a02f1b-9f18-4148-9705-2c3347997cfa": {
      "main": [
        [
          {
            "node": "91ad9f92-adf3-4a8c-af48-3d1e5cd06678",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3ab41431-6298-4380-aaec-d0e29f7f9cb5": {
      "main": [
        [
          {
            "node": "286e23f0-44c8-46c4-bfd2-8aab6eae245b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "602d0cd7-558e-4360-b385-bf9824f9278b": {
      "main": [
        [
          {
            "node": "57843c34-afb5-401e-86dc-8aa22c242263",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a59b516a-e188-4364-8722-f83fd00ed0f0": {
      "main": [
        [
          {
            "node": "c28819b2-2e5d-4732-9a68-0d5045dcb59e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "57843c34-afb5-401e-86dc-8aa22c242263": {
      "main": [
        [
          {
            "node": "1de3f20f-152c-4f81-b42d-cc9e03f5bf0d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "91ad9f92-adf3-4a8c-af48-3d1e5cd06678": {
      "main": [
        [
          {
            "node": "a59b516a-e188-4364-8722-f83fd00ed0f0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "f85d91a0-16ec-4f79-870a-dfc24f954469": {
      "main": [
        [
          {
            "node": "0a7a9d55-5b34-4129-952d-c982ebcc3d7c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c28819b2-2e5d-4732-9a68-0d5045dcb59e": {
      "main": [
        []
      ]
    },
    "0bd66854-cf1b-46b5-ad75-e0d7ef9b71d4": {
      "main": [
        [
          {
            "node": "f85d91a0-16ec-4f79-870a-dfc24f954469",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Häufig gestellte Fragen

Wie verwende ich diesen Workflow?

Kopieren Sie den obigen JSON-Code, erstellen Sie einen neuen Workflow in Ihrer n8n-Instanz und wählen Sie "Aus JSON importieren". Fügen Sie die Konfiguration ein und passen Sie die Anmeldedaten nach Bedarf an.

Für welche Szenarien ist dieser Workflow geeignet?

Experte - Dokumentenextraktion, Multimodales KI

Ist es kostenpflichtig?

Dieser Workflow ist völlig kostenlos. Beachten Sie jedoch, dass Drittanbieterdienste (wie OpenAI API), die im Workflow verwendet werden, möglicherweise kostenpflichtig sind.

Workflow-Informationen
Schwierigkeitsgrad
Experte
Anzahl der Nodes17
Kategorie2
Node-Typen10
Schwierigkeitsbeschreibung

Für fortgeschrittene Benutzer, komplexe Workflows mit 16+ Nodes

Autor
Matheus Pedrosa

Matheus Pedrosa

@julinho

I am a software engineer specializing in automations, with extensive experience on the N8N platform. With solid skills in JavaScript, Go, .NET, and C#, I am equipped to develop efficient and scalable solutions.

Externe Links
Auf n8n.io ansehen

Diesen Workflow teilen

Kategorien

Kategorien: 34