AutomationFlowsMarketing & Ads › AI Lead Qualification from Webhook to Sheets

AI Lead Qualification from Webhook to Sheets

Original n8n title: Ntf 02 Lead Enrichment

NTF 02 Lead Enrichment. Uses lmChatAnthropic, chainLlm, googleSheets, slack. Webhook trigger; 9 nodes.

Webhook trigger★★★★☆ complexityAI-powered9 nodesAnthropic ChatChain LlmGoogle SheetsSlack
Marketing & Ads Trigger: Webhook Nodes: 9 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow follows the Chainllm → Google Sheets 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
{
  "name": "NTF 02 Lead Enrichment",
  "tags": [
    {
      "name": "NTF-Playbook"
    }
  ],
  "settings": {
    "executionOrder": "v1"
  },
  "nodes": [
    {
      "id": "sticky-readme",
      "name": "README",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -60,
        -480
      ],
      "parameters": {
        "content": "## NTF 02 Lead Enrichment\n\n**Trigger:** Webhook, fire from any form (Typeform, Tally, Google Forms, etc.)\n\n**Flow:**\n1. Webhook receives form submission\n2. Extract fields (name, email, company, role, message)\n3. Claude writes a qualification summary + ICP score\n4. Append row to Google Sheets\n5. Send Slack alert with summary\n6. Respond to webhook\n\n**Setup:**\n- Set your Slack channel ID in the Slack node\n- Set your Google Sheets spreadsheet ID + sheet name\n- Edit the Claude prompt to match your ICP criteria\n- Replace `YOUR_WEBHOOK_PATH` in the Webhook node",
        "height": 380,
        "width": 560,
        "color": 6
      }
    },
    {
      "id": "webhook-trigger",
      "name": "Form Submission Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        0,
        0
      ],
      "parameters": {
        "httpMethod": "POST",
        "path": "lead-enrichment",
        "responseMode": "responseNode",
        "options": {}
      }
    },
    {
      "id": "extract-fields",
      "name": "Extract Lead Fields",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        0
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "name",
              "name": "name",
              "value": "={{ $json.body.name || $json.body.full_name || '' }}",
              "type": "string"
            },
            {
              "id": "email",
              "name": "email",
              "value": "={{ $json.body.email || '' }}",
              "type": "string"
            },
            {
              "id": "company",
              "name": "company",
              "value": "={{ $json.body.company || $json.body.organization || '' }}",
              "type": "string"
            },
            {
              "id": "role",
              "name": "role",
              "value": "={{ $json.body.role || $json.body.job_title || '' }}",
              "type": "string"
            },
            {
              "id": "message",
              "name": "message",
              "value": "={{ $json.body.message || $json.body.notes || '' }}",
              "type": "string"
            },
            {
              "id": "submitted_at",
              "name": "submitted_at",
              "value": "={{ $now.toISO() }}",
              "type": "string"
            }
          ]
        }
      }
    },
    {
      "id": "claude-qualify",
      "name": "Claude Qualify Lead",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "typeVersion": 1.3,
      "position": [
        440,
        0
      ],
      "parameters": {
        "model": "claude-sonnet-4-5",
        "options": {
          "maxTokens": 600
        }
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "qualify-chain",
      "name": "Qualification Prompt",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "typeVersion": 1.4,
      "position": [
        440,
        0
      ],
      "parameters": {
        "promptType": "define",
        "text": "=You are a lead qualification assistant. Analyze this lead and return a JSON object with these fields:\n- score: \"Qualified\" | \"Borderline\" | \"Not a Fit\"\n- reasoning: one sentence explaining the score\n- summary: 2-3 sentence executive summary of who this person is and why they reached out\n- next_action: recommended next step (\"Send calendar link\", \"Reply with questions\", or \"Send decline email\")\n\nLead details:\nName: {{ $('Extract Lead Fields').item.json.name }}\nEmail: {{ $('Extract Lead Fields').item.json.email }}\nCompany: {{ $('Extract Lead Fields').item.json.company }}\nRole: {{ $('Extract Lead Fields').item.json.role }}\nMessage: {{ $('Extract Lead Fields').item.json.message }}\n\nICP criteria (edit these to match your business):\n- Ideal company size: 10 to 200 employees\n- Ideal roles: Founder, CEO, COO, Operations Manager, Marketing Manager\n- Ideal problem: wants to save time, reduce manual work, or scale without hiring\n- Not a fit: agencies looking for white-label, pure developers, students\n\nReturn only valid JSON, no markdown fencing."
      }
    },
    {
      "id": "parse-json",
      "name": "Parse Claude Response",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        660,
        0
      ],
      "parameters": {
        "jsCode": "const raw = $input.first().json.text || '{}';\nlet parsed = {};\ntry {\n  const cleaned = raw.replace(/```json|```/g, '').trim();\n  parsed = JSON.parse(cleaned);\n} catch(e) {\n  parsed = { score: 'Borderline', reasoning: 'Parse error, review manually', summary: raw, next_action: 'Reply with questions' };\n}\nreturn [{ json: { ...parsed, ...items[0]?.json } }];"
      }
    },
    {
      "id": "sheets-append",
      "name": "Log to Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [
        880,
        -120
      ],
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_SPREADSHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Leads",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "Submitted At": "={{ $json.submitted_at }}",
            "Name": "={{ $json.name }}",
            "Email": "={{ $json.email }}",
            "Company": "={{ $json.company }}",
            "Role": "={{ $json.role }}",
            "Score": "={{ $json.score }}",
            "Summary": "={{ $json.summary }}",
            "Next Action": "={{ $json.next_action }}",
            "Reasoning": "={{ $json.reasoning }}"
          }
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "slack-alert",
      "name": "Slack Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2.3,
      "position": [
        880,
        80
      ],
      "parameters": {
        "operation": "post",
        "channel": "YOUR_SLACK_CHANNEL_ID",
        "text": "=*New Lead: {{ $json.name }}* ({{ $json.score }})\n*Company:* {{ $json.company }} | *Role:* {{ $json.role }}\n*Email:* {{ $json.email }}\n\n{{ $json.summary }}\n\n*Next action:* {{ $json.next_action }}"
      },
      "credentials": {
        "slackApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "id": "webhook-response",
      "name": "Webhook Response",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [
        1100,
        0
      ],
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify({ received: true }) }}"
      }
    }
  ],
  "connections": {
    "Form Submission Webhook": {
      "main": [
        [
          {
            "node": "Extract Lead Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Lead Fields": {
      "main": [
        [
          {
            "node": "Qualification Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude Qualify Lead": {
      "ai_languageModel": [
        [
          {
            "node": "Qualification Prompt",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Qualification Prompt": {
      "main": [
        [
          {
            "node": "Parse Claude Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Claude Response": {
      "main": [
        [
          {
            "node": "Log to Google Sheets",
            "type": "main",
            "index": 0
          },
          {
            "node": "Slack Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log to Google Sheets": {
      "main": [
        [
          {
            "node": "Webhook Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

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

About this workflow

NTF 02 Lead Enrichment. Uses lmChatAnthropic, chainLlm, googleSheets, slack. Webhook trigger; 9 nodes.

Source: https://github.com/MinaSaad1/n8n-lead-enrichment/blob/main/workflows/01-lead-enrichment.json — original creator credit. Request a take-down →

More Marketing & Ads workflows → · Browse all categories →

Related workflows

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

Marketing & Ads

Automated Social Media Lead Processing with AI Summaries, Slack Alerts & Jira Ticketing. Uses slack, jira, stickyNote, scheduleTrigger. Webhook trigger; 18 nodes.

Slack, Jira, Google Sheets +1
Marketing & Ads

AI Lead Scoring + Routing. Uses openAi, httpRequest, slack, googleSheets. Webhook trigger; 10 nodes.

OpenAI, HTTP Request, Slack +1
Marketing & Ads

This n8n workflow automates the generation of personalized marketing content for events, including emails, social media posts, and advertisements. Leveraging AI, it tailors content based on event deta

HTTP Request, Google Sheets, Email Send +1
Marketing & Ads

AI Lead Qualification & Follow-Up. Uses httpRequest, slack, googleSheets, gmail. Webhook trigger; 18 nodes.

HTTP Request, Slack, Google Sheets +2
Marketing & Ads

This workflow automates the entire lead management lifecycle, from initial capture and qualification to agent assignment and personalized nurturing, ensuring no lead is left behind and agents focus on

Google Sheets, Gmail, Slack