{
  "name": "AI Lead Qualification & Follow-up Engine",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "lead-intake",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-neuer-lead",
      "name": "Webhook: Neuer Lead",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -560,
        300
      ],
      "webhookId": "lead-intake"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "name",
              "value": "={{ ($json.body.name || '').trim() }}",
              "type": "string"
            },
            {
              "id": "a2",
              "name": "email",
              "value": "={{ ($json.body.email || '').trim().toLowerCase() }}",
              "type": "string"
            },
            {
              "id": "a3",
              "name": "company",
              "value": "={{ ($json.body.company || '').trim() }}",
              "type": "string"
            },
            {
              "id": "a4",
              "name": "message",
              "value": "={{ ($json.body.message || '').trim() }}",
              "type": "string"
            },
            {
              "id": "a5",
              "name": "domain",
              "value": "={{ ($json.body.email || '').split('@')[1] || '' }}",
              "type": "string"
            },
            {
              "id": "a6",
              "name": "received_at",
              "value": "={{ $now.toISO() }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "normalize-fields",
      "name": "Normalize Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -340,
        300
      ]
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Validierung + Anreicherung der Eingabe\nconst email = $json.email || '';\nconst domain = $json.domain || '';\nconst freemail = ['gmail.com','googlemail.com','yahoo.com','hotmail.com','outlook.com','gmx.de','web.de','icloud.com'];\nconst emailOk = /^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$/.test(email);\nconst isBusiness = emailOk && !freemail.includes(domain.toLowerCase());\nreturn {\n  ...$json,\n  valid: emailOk && !!$json.company,\n  is_business_email: isBusiness,\n  dedupe_key: email,            // fuer Upsert/Deduplizierung im CRM\n};"
      },
      "id": "validate-code",
      "name": "Validate (Code)",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -120,
        300
      ]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "c1",
              "leftValue": "={{ $json.valid }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ]
        },
        "options": {}
      },
      "id": "if-valid?",
      "name": "IF: Valid?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [
        100,
        300
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ status: \"error\", reason: \"invalid email or missing company\" }) }}",
        "options": {
          "responseCode": 400
        }
      },
      "id": "respond-400-invalid",
      "name": "Respond: 400 Invalid",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        320,
        520
      ]
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ status: \"received\", lead: $json.email }) }}",
        "options": {
          "responseCode": 200
        }
      },
      "id": "respond-200-received",
      "name": "Respond: 200 Received",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1,
      "position": [
        320,
        280
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://api.your-enrichment-provider.com/v1/company?domain={{ $json.domain }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendQuery": false,
        "sendHeaders": false,
        "sendBody": false,
        "options": {}
      },
      "id": "enrich-company-http",
      "name": "Enrich Company (HTTP)",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        540,
        280
      ],
      "onError": "continueRegularOutput",
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_ENRICH",
          "name": "Enrichment API key"
        }
      }
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "p1",
              "name": "lead_summary",
              "value": "=Lead:\\nName: {{ $('Normalize Fields').item.json.name }}\\nE-Mail: {{ $('Normalize Fields').item.json.email }} (Business: {{ $('Normalize Fields').item.json.is_business_email }})\\nFirma: {{ $('Normalize Fields').item.json.company }}\\nNachricht: {{ $('Normalize Fields').item.json.message }}\\n\\nFirmen-Anreicherung (kann leer sein):\\nBranche: {{ $json.industry || 'unbekannt' }}\\nMitarbeiter: {{ $json.employees || 'unbekannt' }}\\nLand: {{ $json.country || 'unbekannt' }}",
              "type": "string"
            },
            {
              "id": "p2",
              "name": "email",
              "value": "={{ $('Normalize Fields').item.json.email }}",
              "type": "string"
            },
            {
              "id": "p3",
              "name": "name",
              "value": "={{ $('Normalize Fields').item.json.name }}",
              "type": "string"
            },
            {
              "id": "p4",
              "name": "company",
              "value": "={{ $('Normalize Fields').item.json.company }}",
              "type": "string"
            },
            {
              "id": "p5",
              "name": "dedupe_key",
              "value": "={{ $('Validate (Code)').item.json.dedupe_key }}",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "id": "build-ai-prompt",
      "name": "Build AI Prompt",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        760,
        280
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.anthropic.com/v1/messages",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "anthropic-version",
              "value": "2023-06-01"
            },
            {
              "name": "content-type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ model: \"claude-sonnet-4-6\", max_tokens: 1024, system: \"Du bist ein B2B-RevOps-Analyst. Bewerte den Lead fuer eine KI-/Automatisierungs-Agentur. Antworte AUSSCHLIESSLICH mit gueltigem JSON in diesem Schema: {\\\"score\\\": number (0-100), \\\"segment\\\": \\\"hot\\\"|\\\"warm\\\"|\\\"cold\\\", \\\"reasoning\\\": string, \\\"suggested_next_step\\\": string, \\\"email_subject\\\": string, \\\"email_body\\\": string}. Kein Text ausserhalb des JSON.\", messages: [ { role: \"user\", content: $json.lead_summary } ] }) }}",
        "options": {
          "timeout": 30000
        }
      },
      "id": "claude-qualify-lead",
      "name": "Claude: Qualify Lead",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        980,
        280
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "REPLACE_ANTHROPIC",
          "name": "Anthropic API key (x-api-key)"
        }
      }
    },
    {
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Anthropic-Antwort robust parsen\nlet raw = '';\ntry { raw = $json.content[0].text; } catch (e) { raw = ''; }\nlet data;\ntry {\n  data = JSON.parse(raw);\n} catch (e) {\n  // Fallback: erstes JSON-Objekt aus dem Text ziehen\n  const m = raw && raw.match(/\\{[\\s\\S]*\\}/);\n  data = m ? JSON.parse(m[0]) : { score: 0, segment: 'cold', reasoning: 'parse_failed', suggested_next_step: 'manuelle Pruefung', email_subject: '', email_body: '' };\n}\nconst score = Number(data.score) || 0;\nreturn {\n  email: $('Build AI Prompt').item.json.email,\n  name: $('Build AI Prompt').item.json.name,\n  company: $('Build AI Prompt').item.json.company,\n  dedupe_key: $('Build AI Prompt').item.json.dedupe_key,\n  score,\n  segment: data.segment || (score >= 70 ? 'hot' : score >= 40 ? 'warm' : 'cold'),\n  reasoning: data.reasoning || '',\n  next_step: data.suggested_next_step || '',\n  email_subject: data.email_subject || '',\n  email_body: data.email_body || ''\n};"
      },
      "id": "parse-ai-json",
      "name": "Parse AI JSON",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1200,
        280
      ]
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "leftValue": "={{ $json.score }}",
                    "rightValue": 70,
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "Hot (>=70)"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "leftValue": "={{ $json.score }}",
                    "rightValue": 40,
                    "operator": {
                      "type": "number",
                      "operation": "gte"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "Warm (40-69)"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "leftValue": "={{ $json.score }}",
                    "rightValue": 40,
                    "operator": {
                      "type": "number",
                      "operation": "lt"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "Cold (<40)"
            }
          ]
        },
        "options": {}
      },
      "id": "route-by-score-switch",
      "name": "Route by Score (Switch)",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "position": [
        1420,
        280
      ]
    },
    {
      "parameters": {
        "resource": "contact",
        "operation": "upsert",
        "email": "={{ $json.email }}",
        "additionalFields": {
          "companyName": "={{ $json.company }}",
          "lifeCycleStage": "salesqualifiedlead"
        }
      },
      "id": "hubspot-deal-anlegen-hot",
      "name": "HubSpot: Deal anlegen (Hot)",
      "type": "n8n-nodes-base.hubspot",
      "typeVersion": 2.1,
      "position": [
        1680,
        80
      ],
      "credentials": {
        "hubspotOAuth2Api": {
          "id": "REPLACE_HUBSPOT",
          "name": "HubSpot account"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "post",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "sales-hot-leads",
          "mode": "name"
        },
        "text": "=:fire: *Hot Lead* ({{ $json.score }}/100) - {{ $json.name }} @ {{ $json.company }}\\n{{ $json.reasoning }}\\nNext: {{ $json.next_step }}",
        "otherOptions": {}
      },
      "id": "slack-sales-alert",
      "name": "Slack: Sales-Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        1900,
        80
      ],
      "credentials": {
        "slackOAuth2Api": {
          "id": "REPLACE_SLACK",
          "name": "Slack account"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "send",
        "sendTo": "={{ $json.email }}",
        "subject": "={{ $json.email_subject }}",
        "message": "={{ $json.email_body }}",
        "options": {}
      },
      "id": "gmail-angebot-senden-hot",
      "name": "Gmail: Angebot senden (Hot)",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        2120,
        80
      ],
      "credentials": {
        "gmailOAuth2": {
          "id": "REPLACE_GMAIL",
          "name": "Gmail account"
        }
      }
    },
    {
      "parameters": {
        "resource": "contact",
        "operation": "upsert",
        "email": "={{ $json.email }}",
        "additionalFields": {
          "companyName": "={{ $json.company }}",
          "lifeCycleStage": "lead"
        }
      },
      "id": "hubspot-kontakt-warm",
      "name": "HubSpot: Kontakt (Warm)",
      "type": "n8n-nodes-base.hubspot",
      "typeVersion": 2.1,
      "position": [
        1680,
        300
      ],
      "credentials": {
        "hubspotOAuth2Api": {
          "id": "REPLACE_HUBSPOT",
          "name": "HubSpot account"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "send",
        "sendTo": "={{ $json.email }}",
        "subject": "={{ $json.email_subject }}",
        "message": "={{ $json.email_body }}",
        "options": {}
      },
      "id": "gmail-nurture-warm",
      "name": "Gmail: Nurture (Warm)",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2.1,
      "position": [
        1900,
        300
      ],
      "credentials": {
        "gmailOAuth2": {
          "id": "REPLACE_GMAIL",
          "name": "Gmail account"
        }
      }
    },
    {
      "parameters": {},
      "id": "no-op-cold-nur-loggen",
      "name": "No-Op: Cold (nur loggen)",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        1680,
        520
      ]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "REPLACE_SHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Leads",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "received_at": "={{ $now.toISO() }}",
            "name": "={{ $json.name }}",
            "email": "={{ $json.email }}",
            "company": "={{ $json.company }}",
            "score": "={{ $json.score }}",
            "segment": "={{ $json.segment }}",
            "reasoning": "={{ $json.reasoning }}"
          },
          "matchingColumns": [],
          "schema": []
        },
        "options": {}
      },
      "id": "google-sheets-log",
      "name": "Google Sheets: Log",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.4,
      "position": [
        2360,
        300
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "REPLACE_SHEETS",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {},
      "id": "no-op-done",
      "name": "No-Op: Done",
      "type": "n8n-nodes-base.noOp",
      "typeVersion": 1,
      "position": [
        2580,
        300
      ]
    },
    {
      "parameters": {},
      "id": "error-trigger",
      "name": "Error Trigger",
      "type": "n8n-nodes-base.errorTrigger",
      "typeVersion": 1,
      "position": [
        -560,
        640
      ]
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "post",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "value": "automation-alerts",
          "mode": "name"
        },
        "text": "=:rotating_light: Workflow-Fehler in *{{ $json.workflow.name }}*\\nNode: {{ $json.execution.lastNodeExecuted }}\\n{{ $json.execution.error.message }}",
        "otherOptions": {}
      },
      "id": "slack-error-alert",
      "name": "Slack: Error-Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.2,
      "position": [
        -340,
        640
      ],
      "credentials": {
        "slackOAuth2Api": {
          "id": "REPLACE_SLACK",
          "name": "Slack account"
        }
      }
    },
    {
      "parameters": {
        "content": "## 1) Intake + Validierung\\nWebhook nimmt Leads an, antwortet sofort 200 (Form wartet nicht auf die KI). Code-Node validiert E-Mail, erkennt Freemail vs. Business und setzt einen dedupe_key.",
        "height": 150,
        "width": 520,
        "color": 5
      },
      "id": "note-intake",
      "name": "note-intake",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -580,
        120
      ]
    },
    {
      "parameters": {
        "content": "## 2) Anreicherung + KI-Qualifizierung\\nFirmendaten via HTTP (continue-on-error = resilient). Claude bewertet den Lead und liefert **strukturiertes JSON** (score, segment, Reasoning, fertiger E-Mail-Entwurf). Parser mit try/catch + Fallback.",
        "height": 150,
        "width": 660,
        "color": 6
      },
      "id": "note-ai",
      "name": "note-ai",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        740,
        120
      ]
    },
    {
      "parameters": {
        "content": "## 3) Routing nach Score\\nHot >=70: CRM-Deal + Slack-Alert + sofort E-Mail.\\nWarm 40-69: CRM-Kontakt + Nurture-Mail.\\nCold <40: nur Logging.\\nAlle Branches -> Google-Sheets-Log. Eigener Error-Trigger meldet Fehler nach Slack.",
        "height": 150,
        "width": 520,
        "color": 3
      },
      "id": "note-route",
      "name": "note-route",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1660,
        460
      ]
    }
  ],
  "connections": {
    "Webhook: Neuer Lead": {
      "main": [
        [
          {
            "node": "Normalize Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize Fields": {
      "main": [
        [
          {
            "node": "Validate (Code)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate (Code)": {
      "main": [
        [
          {
            "node": "IF: Valid?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF: Valid?": {
      "main": [
        [
          {
            "node": "Respond: 200 Received",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond: 400 Invalid",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Respond: 200 Received": {
      "main": [
        [
          {
            "node": "Enrich Company (HTTP)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Enrich Company (HTTP)": {
      "main": [
        [
          {
            "node": "Build AI Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build AI Prompt": {
      "main": [
        [
          {
            "node": "Claude: Qualify Lead",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude: Qualify Lead": {
      "main": [
        [
          {
            "node": "Parse AI JSON",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse AI JSON": {
      "main": [
        [
          {
            "node": "Route by Score (Switch)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Score (Switch)": {
      "main": [
        [
          {
            "node": "HubSpot: Deal anlegen (Hot)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "HubSpot: Kontakt (Warm)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No-Op: Cold (nur loggen)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HubSpot: Deal anlegen (Hot)": {
      "main": [
        [
          {
            "node": "Slack: Sales-Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack: Sales-Alert": {
      "main": [
        [
          {
            "node": "Gmail: Angebot senden (Hot)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail: Angebot senden (Hot)": {
      "main": [
        [
          {
            "node": "Google Sheets: Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HubSpot: Kontakt (Warm)": {
      "main": [
        [
          {
            "node": "Gmail: Nurture (Warm)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gmail: Nurture (Warm)": {
      "main": [
        [
          {
            "node": "Google Sheets: Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "No-Op: Cold (nur loggen)": {
      "main": [
        [
          {
            "node": "Google Sheets: Log",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets: Log": {
      "main": [
        [
          {
            "node": "No-Op: Done",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Error Trigger": {
      "main": [
        [
          {
            "node": "Slack: Error-Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {},
  "meta": {
    "templatecredsSetupCompleted": false
  },
  "tags": [
    {
      "name": "RevOps"
    },
    {
      "name": "AI"
    }
  ]
}