AutomationFlowsMarketing & Ads › Capture and Deduplicate Inbound Leads with Webhooks and Google Sheets

Capture and Deduplicate Inbound Leads with Webhooks and Google Sheets

BySyed Jawad @syedjawad225 on n8n.io

Capture inbound leads via webhook, validate and sanitize the data, deduplicate against Google Sheets, and store only clean leads ready to feed an AI-powered email/SMS nurture sequence. Webhook receives the lead POST request from any form builder or landing page. Validation…

Webhook trigger★★★★☆ complexity20 nodesGoogle Sheets
Marketing & Ads Trigger: Webhook Nodes: 20 Complexity: ★★★★☆ Added:
Capture and Deduplicate Inbound Leads with Webhooks and Google Sheets — n8n workflow card showing Google Sheets integration

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

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": "SXb3eAOAIAPVyOdf",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true,
    "templateCredsSetupCompleted": true
  },
  "name": "Workflow 1 \u2014 Lead Intake (Webhook)",
  "tags": [
    {
      "id": "a4mFplT9oYcZa3KR",
      "name": "Lead Processing",
      "createdAt": "2025-08-28T16:46:30.191Z",
      "updatedAt": "2025-08-28T16:46:30.191Z"
    },
    {
      "id": "h19Ch8D70XTU7UsX",
      "name": "inbound",
      "createdAt": "2025-08-24T13:25:31.996Z",
      "updatedAt": "2025-08-24T13:25:31.996Z"
    },
    {
      "id": "REQ0RaE7pmSbqgX8",
      "name": "Ready-to-import",
      "createdAt": "2026-06-25T10:20:40.309Z",
      "updatedAt": "2026-06-25T10:20:40.309Z"
    }
  ],
  "nodes": [
    {
      "id": "987de7e2-5f3f-4fbe-b987-d8125c88c889",
      "name": "Inbound Lead Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -3696,
        1248
      ],
      "parameters": {
        "path": "inbound-lead22",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "91c31d73-9fa8-4871-b37c-25a624f90bbf",
      "name": "Validate Required Fields",
      "type": "n8n-nodes-base.if",
      "position": [
        -3456,
        1248
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "cond-email-not-empty",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.body.email }}",
              "rightValue": ""
            },
            {
              "id": "cond-phone-not-empty",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.body.phone }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "ec91c3e3-0656-49b0-b529-b1871fbf63bf",
      "name": "Respond 400 \u2014 Missing Fields",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -3232,
        1408
      ],
      "parameters": {
        "options": {
          "responseCode": 400
        },
        "respondWith": "text",
        "responseBody": "Missing fields"
      },
      "typeVersion": 1
    },
    {
      "id": "5586a1cc-b7fd-4ee7-af40-db9528d554af",
      "name": "Sanitize Data",
      "type": "n8n-nodes-base.code",
      "position": [
        -3232,
        1248
      ],
      "parameters": {
        "jsCode": "const body = $input.first().json.body;\n// name \u2014 default to 'Friend' if absent\nconst name = body.name?.trim() || 'Friend';\n// email \u2014 trim + lowercase\nconst email = body.email?.trim().toLowerCase();\n// phone \u2014 normalize to international format (worldwide)\n// Strips formatting chars, preserves '+', handles 00-prefix country codes\nconst phone = (() => {\n  if (!body.phone) return body.phone;\n  const raw = body.phone.toString().trim();\n  const cleaned = raw.replace(/[^\\d+]/g, '');   // strip spaces, dashes, parens\n  if (cleaned.startsWith('+')) return cleaned;   // already international \u2705\n  const digits = cleaned.replace(/^0+/, '');     // strip leading zeros\n  if (digits.length >= 11) return '+' + digits;  // 11+ digits = has country code\n  return cleaned;                                 // short local number, return as-is\n})();\n// lead_source \u2014 optional, default to 'Unknown'\nconst lead_source = body.lead_source?.trim() || 'Unknown';\n// service_of_interest \u2014 optional, default to 'General Inquiry'\nconst service_of_interest = body.service_of_interest?.trim() || 'General Inquiry';\nconst firstName = name.split(' ')[0];\n// sms_consent \u2014 fail-safe default to false; only true if explicitly sent as true\nconst sms_consent = body.sms_consent === true || body.sms_consent === 'true';\nreturn [\n  {\n    json: {\n      name,\n      email,\n      phone,\n      first_name:           firstName,\n      stage:                1,\n      next_followup_at:     new Date().toISOString(),\n      has_replied:          false,\n      lead_source,\n      service_of_interest,\n      sms_consent\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "2bed7024-9658-41b5-8cb7-14ee6c7a1abb",
      "name": "Evaluate Duplicate Result",
      "type": "n8n-nodes-base.code",
      "position": [
        -2512,
        1248
      ],
      "parameters": {
        "jsCode": "// Runs even when GSheets returns 0 items (no match found).\n// Re-injects the sanitized payload with an isDuplicate flag.\n\nconst lookupRows = $input.all();\nconst sanitized  = $('Sanitize Data').first().json;\n\nconst isDuplicate =\n  lookupRows.length > 0 &&\n  lookupRows[0].json['Email'] !== undefined &&\n  lookupRows[0].json['Email'] !== '';\n\nreturn [\n  {\n    json: {\n      ...sanitized,\n      isDuplicate\n    }\n  }\n];"
      },
      "typeVersion": 2
    },
    {
      "id": "6213f283-16fe-457e-ba4e-7354c8eb8764",
      "name": "Respond 200 \u2014 Already Registered",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -2064,
        1200
      ],
      "parameters": {
        "options": {
          "responseCode": 200
        },
        "respondWith": "text",
        "responseBody": "Lead already registered"
      },
      "typeVersion": 1
    },
    {
      "id": "0713608d-6467-4f60-84c4-f4f71b648cb0",
      "name": "Respond 200 \u2014 Lead Accepted",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        -1632,
        1744
      ],
      "parameters": {
        "options": {
          "responseCode": 200
        },
        "respondWith": "text",
        "responseBody": "Lead received successfully"
      },
      "typeVersion": 1
    },
    {
      "id": "9fb274c9-8f66-47f9-8fc2-5e04dc79a2b8",
      "name": "Is Duplicate?",
      "type": "n8n-nodes-base.if",
      "position": [
        -2336,
        1248
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "31cbe7bc-4ae0-4a6e-bec7-325326008adc",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.isDuplicate }}",
              "rightValue": ""
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    },
    {
      "id": "0ab08496-4049-40b4-b72c-4c386a9fac03",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3776,
        1568
      ],
      "parameters": {
        "color": 5,
        "width": 512,
        "height": 640,
        "content": "## \ud83d\udd0c Connecting Frontend Forms to the Inbound Lead Webhook\n> **Lead Ingestion Notice:** This webhook URL acts as the entry gateway for all new leads. You can connect virtually any modern form builder or lead source to this endpoint to feed data into the automation pipeline seamlessly.\n\n### \ud83d\udccb Integration Methods by Platform:\n* **Native Webhook Integrations (Typeform, Jotform, Elementor Forms):** * Go to your form's settings/integrations panel, select **Webhooks**, and paste the production URL from this node. Configure the form to send data via a **POST** request.\n* **WordPress / Contact Form 7 / Gravity Forms:** * Use a lightweight webhook add-on plugin to automatically dispatch the form fields as a JSON payload to this webhook URL upon user submission.\n* **Custom Code (React, Vue, HTML/JS):** * Ensure your frontend developer structures a standard JavaScript `fetch()` or `axios.post()` function targeting this URL, passing the lead data inside the request body.\n\n### \u26a0\ufe0f Critical Data Mapping Rule:\n* To pass the **Validate Required Fields** node immediately following this trigger, ensure your form fields map exactly to the expected JSON keys (e.g., matching lowercase keys like `email`, `name`, or `company` precisely)."
      },
      "typeVersion": 1
    },
    {
      "id": "11794241-eb59-4a45-b695-a4ecc7f10586",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2912,
        400
      ],
      "parameters": {
        "color": 6,
        "width": 560,
        "height": 608,
        "content": "## \ud83d\ude80 AI Lead Nurture System \u2014 Read This First\nStop losing leads to slow follow-up. This is workflow 1 of 4\nin a complete lead automation system: capture \u2192 nurture\n(email + SMS + AI) \u2192 classify replies \u2192 daily report.\nThis template is fully functional once you connect your own\ncredentials. No fake demo \u2014 this is the real production logic.\n\n\u26a1 Quick setup (DIY, ~2-3 hrs):\n1. Create a Google Sheet with the required columns \n2. Replace YOUR_GOOGLE_SHEET_ID_HERE with your Sheet ID\n3. Connect credentials: Google Sheets, Gmail, OpenRouter\n4. Get workflows 1-4 here: [Buy on Gumroad](https://jawadsyed5.gumroad.com/l/xlrhb)\n\n\u23f1 Or skip the setup entirely (60 min, done-for-you):\nPre-built Google Sheet template + step-by-step video walkthrough\n+ all 4 workflows pre-wired + error handling & alert workflow\n(get notified if something breaks) + Join my private buyer Discord for instant support\n\n\u2192 Get the full system on Gumroad: [Buy on Gumroad](https://jawadsyed5.gumroad.com/l/xlrhb)\n\nBuilt for busy founders who'd rather close deals than debug nodes."
      },
      "typeVersion": 1
    },
    {
      "id": "7ceb00c8-9bfe-430d-93bf-be928a17cf1b",
      "name": "\ud83d\udd27 CONFIG: Paste Sheet Info Here",
      "type": "n8n-nodes-base.set",
      "position": [
        -2960,
        1248
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "doc_id_assignment",
              "name": "TEMPLATE_google_sheet_url_or_id",
              "type": "string",
              "value": "YOUR_GOOGLE_SHEET_ID_HERE"
            },
            {
              "id": "sheet_name_assignment",
              "name": "TEMPLATE_sheet_name",
              "type": "string",
              "value": "Total leads"
            },
            {
              "id": "248fb28f-a8c7-4ba8-880b-2d517a535996",
              "name": "name",
              "type": "string",
              "value": "={{ $json.name }}"
            },
            {
              "id": "d96f08cb-fc2c-4b76-a6d0-fe249043818d",
              "name": "email",
              "type": "string",
              "value": "={{ $json.email }}"
            },
            {
              "id": "e92f8a7a-4685-4e73-b874-b9bc085b5d74",
              "name": "first_name",
              "type": "string",
              "value": "={{ $json.first_name }}"
            },
            {
              "id": "4e0153cb-a8cc-444f-9a9c-166477882df6",
              "name": "phone",
              "type": "string",
              "value": "={{ $json.phone }}"
            },
            {
              "id": "c08b6c53-8ae2-42c3-96c5-46537e7b390c",
              "name": "stage",
              "type": "number",
              "value": "={{ $json.stage }}"
            },
            {
              "id": "b6bb26e7-8ec9-41b8-9963-23619c6822bb",
              "name": "has_replied",
              "type": "boolean",
              "value": "={{ $json.has_replied }}"
            },
            {
              "id": "4b273a43-1450-4678-8081-bcd156c5fa99",
              "name": "lead_source",
              "type": "string",
              "value": "={{ $json.lead_source }}"
            },
            {
              "id": "ac5ed62c-42e0-4098-9324-1c14eeafc0f5",
              "name": "service_of_interest",
              "type": "string",
              "value": "={{ $json.service_of_interest }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "7e458d21-9056-4874-ade8-b1d2655f4554",
      "name": "Lookup Email in Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -2752,
        1248
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $json.TEMPLATE_sheet_name }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.TEMPLATE_google_sheet_url_or_id }}"
        },
        "combineFilters": "OR"
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5,
      "alwaysOutputData": true
    },
    {
      "id": "7b3b42fa-e566-46f6-bd55-ec328c848997",
      "name": "\ud83d\udd27 CONFIG: Paste Sheet Info Here1",
      "type": "n8n-nodes-base.set",
      "position": [
        -2064,
        1744
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "doc_id_assignment",
              "name": "TEMPLATE_google_sheet_url_or_id",
              "type": "string",
              "value": "YOUR_GOOGLE_SHEET_ID_HERE"
            },
            {
              "id": "sheet_name_assignment",
              "name": "TEMPLATE_sheet_name",
              "type": "string",
              "value": "Total leads"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "57193015-1f29-46eb-bce9-82f5cd8c6d3d",
      "name": "Append New Lead to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1840,
        1744
      ],
      "parameters": {
        "columns": {
          "value": {
            "Name": "={{ $('Is Duplicate?').item.json.name }}",
            "Email": "={{ $('Is Duplicate?').item.json.email }}",
            "Phone": "={{ $('Is Duplicate?').item.json.phone }}",
            "Stage": "={{ $('Is Duplicate?').item.json.stage }}",
            "Created_At": "={{ $now.setZone('Asia/Karachi').toFormat('dd MMM yyyy, hh:mm a') }}",
            "First_Name": "={{ $('Is Duplicate?').item.json.first_name }}",
            "Has_Replied": "={{ $('Is Duplicate?').item.json.has_replied }}",
            "Lead_Source": "={{ $('Is Duplicate?').item.json.lead_source }}",
            "SMS_Consent": "={{ $('Is Duplicate?').item.json.sms_consent }}",
            "Next_Followup_At": "={{ $('Is Duplicate?').item.json.next_followup_at }}",
            "Service_Of_Interest": "={{ $('Is Duplicate?').item.json.service_of_interest }}"
          },
          "schema": [
            {
              "id": "Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Email",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Email",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Phone",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Phone",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "First_Name",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "First_Name",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Stage",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Stage",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Next_Followup_At",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Next_Followup_At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Has_Replied",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Has_Replied",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Created_At",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Created_At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Updated_At",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Updated_At",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SMS_Sent_Day1",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "SMS_Sent_Day1",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SMS_Sent_Day4",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "SMS_Sent_Day4",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Reply_Intent",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": "Reply_Intent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Lead_Source",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Lead_Source",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Service_Of_Interest",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "Service_Of_Interest",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": " Unsubscribed",
              "type": "string",
              "display": true,
              "removed": true,
              "required": false,
              "displayName": " Unsubscribed",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "SMS_Consent",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "SMS_Consent",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $json.TEMPLATE_sheet_name }}"
        },
        "documentId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $json.TEMPLATE_google_sheet_url_or_id }}"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "1f1c2d5a-276e-4cf8-bafb-0cc43bc840db",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3808,
        656
      ],
      "parameters": {
        "color": 3,
        "width": 864,
        "height": 384,
        "content": "## \u26a0\ufe0f CRITICAL: SMS Consent Mapping Required\n\nTo utilize SMS capabilities, your frontend intake form **must** include an explicit (unchecked by default) **SMS Consent Checkbox**.\n\n### \ud83d\udd27 Mapping Requirement:\n* Map your form's consent checkbox exactly to **`sms_consent`** in the incoming webhook payload.\n* **Expected Values:** `true` / `false` (or `1` / `0`).\n\n> \ud83d\udca1 **Note:** If this field is missing or false, the system will gracefully degrade and **only send email notifications**. \n> \n> *Compliance Disclaimer: You are responsible for designing the actual UI and legal consent language on your frontend form to match your local compliance laws (TCPA/GDPR).*"
      },
      "typeVersion": 1
    },
    {
      "id": "cd123d93-4f10-428b-9a3b-8db44af5bdb2",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4384,
        752
      ],
      "parameters": {
        "width": 544,
        "height": 1056,
        "content": "## \ud83d\ude80 AI Lead Nurture System \u2014 Workflow 1 of 4: Lead Intake\n**What this system does end-to-end:**\nA fully automated lead nurturing pipeline for service-based businesses.\nWhen a lead submits a form, they are instantly captured, deduplicated,\nand staged for a 3-touch AI-written email + SMS follow-up sequence.\nReplies are classified by an LLM, hot leads are escalated to you in\nreal time, and a daily performance report lands in your inbox every morning.\nIf anything breaks at any step, you get an immediate error alert by email. (Not included in free version)\n\n\u2192 Get the full system with pre-made Google Sheet on Gumroad: [Buy on Gumroad](https://jawadsyed5.gumroad.com/l/xlrhb)\n\n**What this specific workflow does:**\nReceives new leads via a POST webhook (from any form builder, website,\nor CRM), validates required fields (email + phone), sanitizes the data,\nchecks for duplicates in Google Sheets, and appends clean new leads\nready for the nurture scheduler to pick up.\n\n**Who it's for:**\nFreelancers, agency owners, and solo founders who generate inbound leads\nfrom websites or landing pages and want every lead followed up\nautomatically \u2014 without hiring a VA or touching a CRM.\n\n**System overview (5 workflows):**\n1. \u27a1\ufe0f Lead Intake (Webhook) \u2190 YOU ARE HERE\n2. Nurture Scheduler (Email + SMS + LLM)\n3. Reply Listener (LLM Intent Classifier)\n4. Daily Report\n5. Error Handling Monitors all 4 workflows (Not included in free version)\n\n**Credentials needed:**\n- Google Sheets (OAuth2)\n- Gmail (OAuth2)"
      },
      "typeVersion": 1
    },
    {
      "id": "be10bff3-9acd-4e71-bc4c-adb25afd401c",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3744,
        1072
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 480,
        "content": "## Receive and validate lead\n\nHandles the initial webhook intake, checks whether required fields are present, returns a 400 error for incomplete submissions, and sanitizes valid lead data before continuing."
      },
      "typeVersion": 1
    },
    {
      "id": "cbfb345f-a755-4ed3-a39f-100a540c58e3",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3008,
        1088
      ],
      "parameters": {
        "color": 7,
        "width": 400,
        "height": 320,
        "content": "## Lookup existing lead\n\nApplies the configured sheet details and searches Google Sheets for an existing row matching the submitted email address."
      },
      "typeVersion": 1
    },
    {
      "id": "333664ff-d260-4e2b-8a78-3f52d52c9462",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2560,
        1040
      ],
      "parameters": {
        "color": 7,
        "width": 656,
        "height": 496,
        "content": "## Evaluate duplicate status\n\nInterprets the sheet lookup result, branches based on whether the lead is a duplicate, and immediately responds when the email is already registered."
      },
      "typeVersion": 1
    },
    {
      "id": "20dc153d-f55c-41df-9813-fbd2acc7b5a2",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2096,
        1584
      ],
      "parameters": {
        "color": 7,
        "width": 624,
        "height": 320,
        "content": "## Append accepted lead\n\nConfigures the target sheet for new leads, appends non-duplicate lead data to Google Sheets, and returns a successful lead-accepted webhook response."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "callerPolicy": "workflowsFromSameOwner",
    "errorWorkflow": "aOt4yeU5vB68CS0X",
    "timeSavedMode": "fixed",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "8f6da5d8-dedb-410c-92d1-910aa8c736c3",
  "nodeGroups": [],
  "connections": {
    "Is Duplicate?": {
      "main": [
        [
          {
            "node": "Respond 200 \u2014 Already Registered",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83d\udd27 CONFIG: Paste Sheet Info Here1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sanitize Data": {
      "main": [
        [
          {
            "node": "\ud83d\udd27 CONFIG: Paste Sheet Info Here",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Inbound Lead Webhook": {
      "main": [
        [
          {
            "node": "Validate Required Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lookup Email in Sheets": {
      "main": [
        [
          {
            "node": "Evaluate Duplicate Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate Required Fields": {
      "main": [
        [
          {
            "node": "Sanitize Data",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond 400 \u2014 Missing Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Append New Lead to Sheets": {
      "main": [
        [
          {
            "node": "Respond 200 \u2014 Lead Accepted",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Evaluate Duplicate Result": {
      "main": [
        [
          {
            "node": "Is Duplicate?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd27 CONFIG: Paste Sheet Info Here": {
      "main": [
        [
          {
            "node": "Lookup Email in Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd27 CONFIG: Paste Sheet Info Here1": {
      "main": [
        [
          {
            "node": "Append New Lead to Sheets",
            "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

Capture inbound leads via webhook, validate and sanitize the data, deduplicate against Google Sheets, and store only clean leads ready to feed an AI-powered email/SMS nurture sequence. Webhook receives the lead POST request from any form builder or landing page. Validation…

Source: https://n8n.io/workflows/16647/ — 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

Ad agencies needing automated lead capture. Sales teams fighting fraud and scoring leads. B2B SaaS companies nurturing prospects. Marketing pros boosting sales pipelines. Captures leads via Webhook fr

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

This workflow captures real estate property inquiries via a webhook, validates and normalizes lead details, upserts the lead into Google Sheets, sends an auto-reply through Gmail, and notifies your te

Google Sheets, Gmail, Slack +1
Marketing & Ads

This workflow captures real estate property inquiries via a webhook, saves the lead to Google Sheets, sends an auto-reply email through Gmail, and posts a notification to a Slack channel before return

Google Sheets, Gmail, Slack +1
Marketing & Ads

This workflow captures shoe-shopping leads via a Tally form webhook, matches products from Google Sheets, uses a local Llama model (Ollama HTTP API) to score the lead and draft recommendations, then e

Google Sheets, HTTP Request, Gmail +1
Marketing & Ads

Lead Capture & CRM Automation. Uses slack, googleSheets, gmail. Webhook trigger; 14 nodes.

Slack, Google Sheets, Gmail